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

Checks whether a Literal expression is a number.

is_negative: bool
181    @property
182    def is_negative(self) -> bool:
183        """
184        Checks whether an expression is negative.
185
186        Handles both exp.Neg and Literal numbers with "-" which come from optimizer.simplify.
187        """
188        return isinstance(self, Neg) or (self.is_number and self.this.startswith("-"))

Checks whether an expression is negative.

Handles both exp.Neg and Literal numbers with "-" which come from optimizer.simplify.

is_int: bool
190    @property
191    def is_int(self) -> bool:
192        """
193        Checks whether a Literal expression is an integer.
194        """
195        return self.is_number and is_int(self.name)

Checks whether a Literal expression is an integer.

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

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
211    @property
212    def alias_column_names(self) -> t.List[str]:
213        table_alias = self.args.get("alias")
214        if not table_alias:
215            return []
216        return [c.name for c in table_alias.args.get("columns") or []]
name: str
218    @property
219    def name(self) -> str:
220        return self.text("this")
alias_or_name: str
222    @property
223    def alias_or_name(self) -> str:
224        return self.alias or self.name
output_name: str
226    @property
227    def output_name(self) -> str:
228        """
229        Name of the output column if this expression is a selection.
230
231        If the Expression has no output name, an empty string is returned.
232
233        Example:
234            >>> from sqlglot import parse_one
235            >>> parse_one("SELECT a").expressions[0].output_name
236            'a'
237            >>> parse_one("SELECT b AS c").expressions[0].output_name
238            'c'
239            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
240            ''
241        """
242        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]
244    @property
245    def type(self) -> t.Optional[DataType]:
246        return self._type
def is_type(self, *dtypes) -> bool:
254    def is_type(self, *dtypes) -> bool:
255        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
257    def is_leaf(self) -> bool:
258        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
260    @property
261    def meta(self) -> t.Dict[str, t.Any]:
262        if self._meta is None:
263            self._meta = {}
264        return self._meta
def copy(self):
300    def copy(self):
301        """
302        Returns a deep copy of the expression.
303        """
304        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]] = None) -> None:
306    def add_comments(self, comments: t.Optional[t.List[str]] = None) -> None:
307        if self.comments is None:
308            self.comments = []
309
310        if comments:
311            for comment in comments:
312                _, *meta = comment.split(SQLGLOT_META)
313                if meta:
314                    for kv in "".join(meta).split(","):
315                        k, *v = kv.split("=")
316                        value = v[0].strip() if v else True
317                        self.meta[k.strip()] = value
318                self.comments.append(comment)
def pop_comments(self) -> List[str]:
320    def pop_comments(self) -> t.List[str]:
321        comments = self.comments or []
322        self.comments = None
323        return comments
def append(self, arg_key: str, value: Any) -> None:
325    def append(self, arg_key: str, value: t.Any) -> None:
326        """
327        Appends value to arg_key if it's a list or sets it as a new list.
328
329        Args:
330            arg_key (str): name of the list expression arg
331            value (Any): value to append to the list
332        """
333        if type(self.args.get(arg_key)) is not list:
334            self.args[arg_key] = []
335        self._set_parent(arg_key, value)
336        values = self.args[arg_key]
337        if hasattr(value, "parent"):
338            value.index = len(values)
339        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:
341    def set(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
342        """
343        Sets arg_key to value.
344
345        Args:
346            arg_key: name of the expression arg.
347            value: value to set the arg to.
348            index: if the arg is a list, this specifies what position to add the value in it.
349        """
350        if index is not None:
351            expressions = self.args.get(arg_key) or []
352
353            if seq_get(expressions, index) is None:
354                return
355            if value is None:
356                expressions.pop(index)
357                for v in expressions[index:]:
358                    v.index = v.index - 1
359                return
360
361            if isinstance(value, list):
362                expressions.pop(index)
363                expressions[index:index] = value
364            else:
365                expressions[index] = value
366
367            value = expressions
368        elif value is None:
369            self.args.pop(arg_key, None)
370            return
371
372        self.args[arg_key] = value
373        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
387    @property
388    def depth(self) -> int:
389        """
390        Returns the depth of this tree.
391        """
392        if self.parent:
393            return self.parent.depth + 1
394        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
396    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
397        """Yields the key and expression for all arguments, exploding list args."""
398        # remove tuple when python 3.7 is deprecated
399        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
400            if type(vs) is list:
401                for v in reversed(vs) if reverse else vs:
402                    if hasattr(v, "parent"):
403                        yield v
404            else:
405                if hasattr(vs, "parent"):
406                    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]:
408    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
409        """
410        Returns the first node in this tree which matches at least one of
411        the specified types.
412
413        Args:
414            expression_types: the expression type(s) to match.
415            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
416
417        Returns:
418            The node which matches the criteria or None if no such node was found.
419        """
420        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]:
422    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
423        """
424        Returns a generator object which visits all nodes in this tree and only
425        yields those that match at least one of the specified expression types.
426
427        Args:
428            expression_types: the expression type(s) to match.
429            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
430
431        Returns:
432            The generator object.
433        """
434        for expression in self.walk(bfs=bfs):
435            if isinstance(expression, expression_types):
436                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]:
438    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
439        """
440        Returns a nearest parent matching expression_types.
441
442        Args:
443            expression_types: the expression type(s) to match.
444
445        Returns:
446            The parent node.
447        """
448        ancestor = self.parent
449        while ancestor and not isinstance(ancestor, expression_types):
450            ancestor = ancestor.parent
451        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]
453    @property
454    def parent_select(self) -> t.Optional[Select]:
455        """
456        Returns the parent select statement.
457        """
458        return self.find_ancestor(Select)

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
474    def walk(
475        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
476    ) -> t.Iterator[Expression]:
477        """
478        Returns a generator object which visits all nodes in this tree.
479
480        Args:
481            bfs: if set to True the BFS traversal order will be applied,
482                otherwise the DFS traversal will be used instead.
483            prune: callable that returns True if the generator should stop traversing
484                this branch of the tree.
485
486        Returns:
487            the generator object.
488        """
489        if bfs:
490            yield from self.bfs(prune=prune)
491        else:
492            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]:
494    def dfs(
495        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
496    ) -> t.Iterator[Expression]:
497        """
498        Returns a generator object which visits all nodes in this tree in
499        the DFS (Depth-first) order.
500
501        Returns:
502            The generator object.
503        """
504        stack = [self]
505
506        while stack:
507            node = stack.pop()
508
509            yield node
510
511            if prune and prune(node):
512                continue
513
514            for v in node.iter_expressions(reverse=True):
515                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]:
517    def bfs(
518        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
519    ) -> t.Iterator[Expression]:
520        """
521        Returns a generator object which visits all nodes in this tree in
522        the BFS (Breadth-first) order.
523
524        Returns:
525            The generator object.
526        """
527        queue = deque([self])
528
529        while queue:
530            node = queue.popleft()
531
532            yield node
533
534            if prune and prune(node):
535                continue
536
537            for v in node.iter_expressions():
538                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):
540    def unnest(self):
541        """
542        Returns the first non parenthesis child or self.
543        """
544        expression = self
545        while type(expression) is Paren:
546            expression = expression.this
547        return expression

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
563    def flatten(self, unnest=True):
564        """
565        Returns a generator which yields child nodes whose parents are the same class.
566
567        A AND B AND C -> [A, B, C]
568        """
569        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
570            if type(node) is not self.__class__:
571                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:
579    def to_s(self) -> str:
580        """
581        Same as __repr__, but includes additional information which can be useful
582        for debugging, like empty or missing args and the AST nodes' object IDs.
583        """
584        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:
586    def sql(self, dialect: DialectType = None, **opts) -> str:
587        """
588        Returns SQL string representation of this tree.
589
590        Args:
591            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
592            opts: other `sqlglot.generator.Generator` options.
593
594        Returns:
595            The SQL string.
596        """
597        from sqlglot.dialects import Dialect
598
599        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:
601    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
602        """
603        Visits all tree nodes (excluding already transformed ones)
604        and applies the given transformation function to each node.
605
606        Args:
607            fun: a function which takes a node as an argument and returns a
608                new transformed node or the same node without modifications. If the function
609                returns None, then the corresponding node will be removed from the syntax tree.
610            copy: if set to True a new tree instance is constructed, otherwise the tree is
611                modified in place.
612
613        Returns:
614            The transformed tree.
615        """
616        root = None
617        new_node = None
618
619        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
620            parent, arg_key, index = node.parent, node.arg_key, node.index
621            new_node = fun(node, *args, **kwargs)
622
623            if not root:
624                root = new_node
625            elif new_node is not node:
626                parent.set(arg_key, new_node, index)
627
628        assert root
629        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):
637    def replace(self, expression):
638        """
639        Swap out this expression with a new expression.
640
641        For example::
642
643            >>> tree = Select().select("x").from_("tbl")
644            >>> tree.find(Column).replace(column("y"))
645            Column(
646              this=Identifier(this=y, quoted=False))
647            >>> tree.sql()
648            'SELECT y FROM tbl'
649
650        Args:
651            expression: new node
652
653        Returns:
654            The new expression or expressions.
655        """
656        parent = self.parent
657
658        if not parent or parent is expression:
659            return expression
660
661        key = self.arg_key
662        value = parent.args.get(key)
663
664        if type(expression) is list and isinstance(value, Expression):
665            # We are trying to replace an Expression with a list, so it's assumed that
666            # the intention was to really replace the parent of this expression.
667            value.parent.replace(expression)
668        else:
669            parent.set(key, expression, self.index)
670
671        if expression is not self:
672            self.parent = None
673            self.arg_key = None
674            self.index = None
675
676        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:
678    def pop(self: E) -> E:
679        """
680        Remove this expression from its AST.
681
682        Returns:
683            The popped expression.
684        """
685        self.replace(None)
686        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
688    def assert_is(self, type_: t.Type[E]) -> E:
689        """
690        Assert that this `Expression` is an instance of `type_`.
691
692        If it is NOT an instance of `type_`, this raises an assertion error.
693        Otherwise, this returns this expression.
694
695        Examples:
696            This is useful for type security in chained expressions:
697
698            >>> import sqlglot
699            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
700            'SELECT x, z FROM y'
701        """
702        if not isinstance(self, type_):
703            raise AssertionError(f"{self} is not {type_}.")
704        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]:
706    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
707        """
708        Checks if this expression is valid (e.g. all mandatory args are set).
709
710        Args:
711            args: a sequence of values that were used to instantiate a Func expression. This is used
712                to check that the provided arguments don't exceed the function argument limit.
713
714        Returns:
715            A list of error messages for all possible errors that were found.
716        """
717        errors: t.List[str] = []
718
719        for k in self.args:
720            if k not in self.arg_types:
721                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
722        for k, mandatory in self.arg_types.items():
723            v = self.args.get(k)
724            if mandatory and (v is None or (isinstance(v, list) and not v)):
725                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
726
727        if (
728            args
729            and isinstance(self, Func)
730            and len(args) > len(self.arg_types)
731            and not self.is_var_len_args
732        ):
733            errors.append(
734                f"The number of provided arguments ({len(args)}) is greater than "
735                f"the maximum number of supported arguments ({len(self.arg_types)})"
736            )
737
738        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):
740    def dump(self):
741        """
742        Dump this Expression to a JSON-serializable dict.
743        """
744        from sqlglot.serde import dump
745
746        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
748    @classmethod
749    def load(cls, obj):
750        """
751        Load a dict (as returned by `Expression.dump`) into an Expression instance.
752        """
753        from sqlglot.serde import load
754
755        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:
757    def and_(
758        self,
759        *expressions: t.Optional[ExpOrStr],
760        dialect: DialectType = None,
761        copy: bool = True,
762        **opts,
763    ) -> Condition:
764        """
765        AND this condition with one or multiple expressions.
766
767        Example:
768            >>> condition("x=1").and_("y=1").sql()
769            'x = 1 AND y = 1'
770
771        Args:
772            *expressions: the SQL code strings to parse.
773                If an `Expression` instance is passed, it will be used as-is.
774            dialect: the dialect used to parse the input expression.
775            copy: whether to copy the involved expressions (only applies to Expressions).
776            opts: other options to use to parse the input expressions.
777
778        Returns:
779            The new And condition.
780        """
781        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:
783    def or_(
784        self,
785        *expressions: t.Optional[ExpOrStr],
786        dialect: DialectType = None,
787        copy: bool = True,
788        **opts,
789    ) -> Condition:
790        """
791        OR this condition with one or multiple expressions.
792
793        Example:
794            >>> condition("x=1").or_("y=1").sql()
795            'x = 1 OR y = 1'
796
797        Args:
798            *expressions: the SQL code strings to parse.
799                If an `Expression` instance is passed, it will be used as-is.
800            dialect: the dialect used to parse the input expression.
801            copy: whether to copy the involved expressions (only applies to Expressions).
802            opts: other options to use to parse the input expressions.
803
804        Returns:
805            The new Or condition.
806        """
807        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):
809    def not_(self, copy: bool = True):
810        """
811        Wrap this condition with NOT.
812
813        Example:
814            >>> condition("x=1").not_().sql()
815            'NOT x = 1'
816
817        Args:
818            copy: whether to copy this object.
819
820        Returns:
821            The new Not instance.
822        """
823        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:
825    def as_(
826        self,
827        alias: str | Identifier,
828        quoted: t.Optional[bool] = None,
829        dialect: DialectType = None,
830        copy: bool = True,
831        **opts,
832    ) -> Alias:
833        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:
858    def isin(
859        self,
860        *expressions: t.Any,
861        query: t.Optional[ExpOrStr] = None,
862        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
863        copy: bool = True,
864        **opts,
865    ) -> In:
866        subquery = maybe_parse(query, copy=copy, **opts) if query else None
867        if subquery and not isinstance(subquery, Subquery):
868            subquery = subquery.subquery(copy=False)
869
870        return In(
871            this=maybe_copy(self, copy),
872            expressions=[convert(e, copy=copy) for e in expressions],
873            query=subquery,
874            unnest=(
875                Unnest(
876                    expressions=[
877                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
878                        for e in ensure_list(unnest)
879                    ]
880                )
881                if unnest
882                else None
883            ),
884        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
886    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
887        return Between(
888            this=maybe_copy(self, copy),
889            low=convert(low, copy=copy, **opts),
890            high=convert(high, copy=copy, **opts),
891        )
def is_( self, other: Union[str, Expression]) -> Is:
893    def is_(self, other: ExpOrStr) -> Is:
894        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
896    def like(self, other: ExpOrStr) -> Like:
897        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
899    def ilike(self, other: ExpOrStr) -> ILike:
900        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
902    def eq(self, other: t.Any) -> EQ:
903        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
905    def neq(self, other: t.Any) -> NEQ:
906        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
908    def rlike(self, other: ExpOrStr) -> RegexpLike:
909        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
911    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
912        div = self._binop(Div, other)
913        div.args["typed"] = typed
914        div.args["safe"] = safe
915        return div
def asc(self, nulls_first: bool = True) -> Ordered:
917    def asc(self, nulls_first: bool = True) -> Ordered:
918        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
920    def desc(self, nulls_first: bool = False) -> Ordered:
921        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):
1004class Condition(Expression):
1005    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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

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

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

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

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

Returns the query's projections.

named_selects: List[str]
1161    @property
1162    def named_selects(self) -> t.List[str]:
1163        """Returns the output names of the query's projections."""
1164        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:
1166    def select(
1167        self: Q,
1168        *expressions: t.Optional[ExpOrStr],
1169        append: bool = True,
1170        dialect: DialectType = None,
1171        copy: bool = True,
1172        **opts,
1173    ) -> Q:
1174        """
1175        Append to or set the SELECT expressions.
1176
1177        Example:
1178            >>> Select().select("x", "y").sql()
1179            'SELECT x, y'
1180
1181        Args:
1182            *expressions: the SQL code strings to parse.
1183                If an `Expression` instance is passed, it will be used as-is.
1184            append: if `True`, add to any existing expressions.
1185                Otherwise, this resets the expressions.
1186            dialect: the dialect used to parse the input expressions.
1187            copy: if `False`, modify this expression instance in-place.
1188            opts: other options to use to parse the input expressions.
1189
1190        Returns:
1191            The modified Query expression.
1192        """
1193        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:
1195    def with_(
1196        self: Q,
1197        alias: ExpOrStr,
1198        as_: ExpOrStr,
1199        recursive: t.Optional[bool] = None,
1200        append: bool = True,
1201        dialect: DialectType = None,
1202        copy: bool = True,
1203        **opts,
1204    ) -> Q:
1205        """
1206        Append to or set the common table expressions.
1207
1208        Example:
1209            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1210            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1211
1212        Args:
1213            alias: the SQL code string to parse as the table name.
1214                If an `Expression` instance is passed, this is used as-is.
1215            as_: the SQL code string to parse as the table expression.
1216                If an `Expression` instance is passed, it will be used as-is.
1217            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1218            append: if `True`, add to any existing expressions.
1219                Otherwise, this resets the expressions.
1220            dialect: the dialect used to parse the input expression.
1221            copy: if `False`, modify this expression instance in-place.
1222            opts: other options to use to parse the input expressions.
1223
1224        Returns:
1225            The modified expression.
1226        """
1227        return _apply_cte_builder(
1228            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1229        )

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:
1231    def union(
1232        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1233    ) -> Union:
1234        """
1235        Builds a UNION expression.
1236
1237        Example:
1238            >>> import sqlglot
1239            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1240            'SELECT * FROM foo UNION SELECT * FROM bla'
1241
1242        Args:
1243            expression: the SQL code string.
1244                If an `Expression` instance is passed, it will be used as-is.
1245            distinct: set the DISTINCT flag if and only if this is true.
1246            dialect: the dialect used to parse the input expression.
1247            opts: other options to use to parse the input expressions.
1248
1249        Returns:
1250            The new Union expression.
1251        """
1252        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:
1254    def intersect(
1255        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1256    ) -> Intersect:
1257        """
1258        Builds an INTERSECT expression.
1259
1260        Example:
1261            >>> import sqlglot
1262            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1263            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1264
1265        Args:
1266            expression: the SQL code string.
1267                If an `Expression` instance is passed, it will be used as-is.
1268            distinct: set the DISTINCT flag if and only if this is true.
1269            dialect: the dialect used to parse the input expression.
1270            opts: other options to use to parse the input expressions.
1271
1272        Returns:
1273            The new Intersect expression.
1274        """
1275        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:
1277    def except_(
1278        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1279    ) -> Except:
1280        """
1281        Builds an EXCEPT expression.
1282
1283        Example:
1284            >>> import sqlglot
1285            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1286            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1287
1288        Args:
1289            expression: the SQL code string.
1290                If an `Expression` instance is passed, it will be used as-is.
1291            distinct: set the DISTINCT flag if and only if this is true.
1292            dialect: the dialect used to parse the input expression.
1293            opts: other options to use to parse the input expressions.
1294
1295        Returns:
1296            The new Except expression.
1297        """
1298        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):
1301class UDTF(DerivedTable):
1302    @property
1303    def selects(self) -> t.List[Expression]:
1304        alias = self.args.get("alias")
1305        return alias.columns if alias else []
selects: List[Expression]
1302    @property
1303    def selects(self) -> t.List[Expression]:
1304        alias = self.args.get("alias")
1305        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1308class Cache(Expression):
1309    arg_types = {
1310        "this": True,
1311        "lazy": False,
1312        "options": False,
1313        "expression": False,
1314    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1317class Uncache(Expression):
1318    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1321class Refresh(Expression):
1322    pass
key = 'refresh'
class DDL(Expression):
1325class DDL(Expression):
1326    @property
1327    def ctes(self) -> t.List[CTE]:
1328        """Returns a list of all the CTEs attached to this statement."""
1329        with_ = self.args.get("with")
1330        return with_.expressions if with_ else []
1331
1332    @property
1333    def selects(self) -> t.List[Expression]:
1334        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1335        return self.expression.selects if isinstance(self.expression, Query) else []
1336
1337    @property
1338    def named_selects(self) -> t.List[str]:
1339        """
1340        If this statement contains a query (e.g. a CTAS), this returns the output
1341        names of the query's projections.
1342        """
1343        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1326    @property
1327    def ctes(self) -> t.List[CTE]:
1328        """Returns a list of all the CTEs attached to this statement."""
1329        with_ = self.args.get("with")
1330        return with_.expressions if with_ else []

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

selects: List[Expression]
1332    @property
1333    def selects(self) -> t.List[Expression]:
1334        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1335        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]
1337    @property
1338    def named_selects(self) -> t.List[str]:
1339        """
1340        If this statement contains a query (e.g. a CTAS), this returns the output
1341        names of the query's projections.
1342        """
1343        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):
1346class DML(Expression):
1347    def returning(
1348        self,
1349        expression: ExpOrStr,
1350        dialect: DialectType = None,
1351        copy: bool = True,
1352        **opts,
1353    ) -> DML:
1354        """
1355        Set the RETURNING expression. Not supported by all dialects.
1356
1357        Example:
1358            >>> delete("tbl").returning("*", dialect="postgres").sql()
1359            'DELETE FROM tbl RETURNING *'
1360
1361        Args:
1362            expression: the SQL code strings to parse.
1363                If an `Expression` instance is passed, it will be used as-is.
1364            dialect: the dialect used to parse the input expressions.
1365            copy: if `False`, modify this expression instance in-place.
1366            opts: other options to use to parse the input expressions.
1367
1368        Returns:
1369            Delete: the modified expression.
1370        """
1371        return _apply_builder(
1372            expression=expression,
1373            instance=self,
1374            arg="returning",
1375            prefix="RETURNING",
1376            dialect=dialect,
1377            copy=copy,
1378            into=Returning,
1379            **opts,
1380        )
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:
1347    def returning(
1348        self,
1349        expression: ExpOrStr,
1350        dialect: DialectType = None,
1351        copy: bool = True,
1352        **opts,
1353    ) -> DML:
1354        """
1355        Set the RETURNING expression. Not supported by all dialects.
1356
1357        Example:
1358            >>> delete("tbl").returning("*", dialect="postgres").sql()
1359            'DELETE FROM tbl RETURNING *'
1360
1361        Args:
1362            expression: the SQL code strings to parse.
1363                If an `Expression` instance is passed, it will be used as-is.
1364            dialect: the dialect used to parse the input expressions.
1365            copy: if `False`, modify this expression instance in-place.
1366            opts: other options to use to parse the input expressions.
1367
1368        Returns:
1369            Delete: the modified expression.
1370        """
1371        return _apply_builder(
1372            expression=expression,
1373            instance=self,
1374            arg="returning",
1375            prefix="RETURNING",
1376            dialect=dialect,
1377            copy=copy,
1378            into=Returning,
1379            **opts,
1380        )

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):
1383class Create(DDL):
1384    arg_types = {
1385        "with": False,
1386        "this": True,
1387        "kind": True,
1388        "expression": False,
1389        "exists": False,
1390        "properties": False,
1391        "replace": False,
1392        "unique": False,
1393        "indexes": False,
1394        "no_schema_binding": False,
1395        "begin": False,
1396        "end": False,
1397        "clone": False,
1398    }
1399
1400    @property
1401    def kind(self) -> t.Optional[str]:
1402        kind = self.args.get("kind")
1403        return kind and kind.upper()
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False}
kind: Optional[str]
1400    @property
1401    def kind(self) -> t.Optional[str]:
1402        kind = self.args.get("kind")
1403        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1406class SequenceProperties(Expression):
1407    arg_types = {
1408        "increment": False,
1409        "minvalue": False,
1410        "maxvalue": False,
1411        "cache": False,
1412        "start": False,
1413        "owned": False,
1414        "options": False,
1415    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1418class TruncateTable(Expression):
1419    arg_types = {
1420        "expressions": True,
1421        "is_database": False,
1422        "exists": False,
1423        "only": False,
1424        "cluster": False,
1425        "identity": False,
1426        "option": False,
1427        "partition": False,
1428    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1434class Clone(Expression):
1435    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1438class Describe(Expression):
1439    arg_types = {"this": True, "style": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1442class Kill(Expression):
1443    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1446class Pragma(Expression):
1447    pass
key = 'pragma'
class Declare(Expression):
1450class Declare(Expression):
1451    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1454class DeclareItem(Expression):
1455    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1458class Set(Expression):
1459    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1462class Heredoc(Expression):
1463    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1466class SetItem(Expression):
1467    arg_types = {
1468        "this": False,
1469        "expressions": False,
1470        "kind": False,
1471        "collate": False,  # MySQL SET NAMES statement
1472        "global": False,
1473    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1476class Show(Expression):
1477    arg_types = {
1478        "this": True,
1479        "history": False,
1480        "terse": False,
1481        "target": False,
1482        "offset": False,
1483        "starts_with": False,
1484        "limit": False,
1485        "from": False,
1486        "like": False,
1487        "where": False,
1488        "db": False,
1489        "scope": False,
1490        "scope_kind": False,
1491        "full": False,
1492        "mutex": False,
1493        "query": False,
1494        "channel": False,
1495        "global": False,
1496        "log": False,
1497        "position": False,
1498        "types": False,
1499    }
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):
1502class UserDefinedFunction(Expression):
1503    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1506class CharacterSet(Expression):
1507    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1510class With(Expression):
1511    arg_types = {"expressions": True, "recursive": False}
1512
1513    @property
1514    def recursive(self) -> bool:
1515        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1513    @property
1514    def recursive(self) -> bool:
1515        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1518class WithinGroup(Expression):
1519    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1524class CTE(DerivedTable):
1525    arg_types = {
1526        "this": True,
1527        "alias": True,
1528        "scalar": False,
1529        "materialized": False,
1530    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1533class ProjectionDef(Expression):
1534    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1537class TableAlias(Expression):
1538    arg_types = {"this": False, "columns": False}
1539
1540    @property
1541    def columns(self):
1542        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1540    @property
1541    def columns(self):
1542        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1545class BitString(Condition):
1546    pass
key = 'bitstring'
class HexString(Condition):
1549class HexString(Condition):
1550    pass
key = 'hexstring'
class ByteString(Condition):
1553class ByteString(Condition):
1554    pass
key = 'bytestring'
class RawString(Condition):
1557class RawString(Condition):
1558    pass
key = 'rawstring'
class UnicodeString(Condition):
1561class UnicodeString(Condition):
1562    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1565class Column(Condition):
1566    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1567
1568    @property
1569    def table(self) -> str:
1570        return self.text("table")
1571
1572    @property
1573    def db(self) -> str:
1574        return self.text("db")
1575
1576    @property
1577    def catalog(self) -> str:
1578        return self.text("catalog")
1579
1580    @property
1581    def output_name(self) -> str:
1582        return self.name
1583
1584    @property
1585    def parts(self) -> t.List[Identifier]:
1586        """Return the parts of a column in order catalog, db, table, name."""
1587        return [
1588            t.cast(Identifier, self.args[part])
1589            for part in ("catalog", "db", "table", "this")
1590            if self.args.get(part)
1591        ]
1592
1593    def to_dot(self) -> Dot | Identifier:
1594        """Converts the column into a dot expression."""
1595        parts = self.parts
1596        parent = self.parent
1597
1598        while parent:
1599            if isinstance(parent, Dot):
1600                parts.append(parent.expression)
1601            parent = parent.parent
1602
1603        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
1568    @property
1569    def table(self) -> str:
1570        return self.text("table")
db: str
1572    @property
1573    def db(self) -> str:
1574        return self.text("db")
catalog: str
1576    @property
1577    def catalog(self) -> str:
1578        return self.text("catalog")
output_name: str
1580    @property
1581    def output_name(self) -> str:
1582        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]
1584    @property
1585    def parts(self) -> t.List[Identifier]:
1586        """Return the parts of a column in order catalog, db, table, name."""
1587        return [
1588            t.cast(Identifier, self.args[part])
1589            for part in ("catalog", "db", "table", "this")
1590            if self.args.get(part)
1591        ]

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

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

Converts the column into a dot expression.

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

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

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

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):
2191class OnConflict(Expression):
2192    arg_types = {
2193        "duplicate": False,
2194        "expressions": False,
2195        "action": False,
2196        "conflict_keys": False,
2197        "constraint": False,
2198    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2201class Returning(Expression):
2202    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2206class Introducer(Expression):
2207    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2211class National(Expression):
2212    pass
key = 'national'
class LoadData(Expression):
2215class LoadData(Expression):
2216    arg_types = {
2217        "this": True,
2218        "local": False,
2219        "overwrite": False,
2220        "inpath": True,
2221        "partition": False,
2222        "input_format": False,
2223        "serde": False,
2224    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2227class Partition(Expression):
2228    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2231class PartitionRange(Expression):
2232    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2236class PartitionId(Expression):
2237    pass
key = 'partitionid'
class Fetch(Expression):
2240class Fetch(Expression):
2241    arg_types = {
2242        "direction": False,
2243        "count": False,
2244        "percent": False,
2245        "with_ties": False,
2246    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2249class Group(Expression):
2250    arg_types = {
2251        "expressions": False,
2252        "grouping_sets": False,
2253        "cube": False,
2254        "rollup": False,
2255        "totals": False,
2256        "all": False,
2257    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2260class Lambda(Expression):
2261    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2264class Limit(Expression):
2265    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):
2268class Literal(Condition):
2269    arg_types = {"this": True, "is_string": True}
2270
2271    @property
2272    def hashable_args(self) -> t.Any:
2273        return (self.this, self.args.get("is_string"))
2274
2275    @classmethod
2276    def number(cls, number) -> Literal:
2277        return cls(this=str(number), is_string=False)
2278
2279    @classmethod
2280    def string(cls, string) -> Literal:
2281        return cls(this=str(string), is_string=True)
2282
2283    @property
2284    def output_name(self) -> str:
2285        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2271    @property
2272    def hashable_args(self) -> t.Any:
2273        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2275    @classmethod
2276    def number(cls, number) -> Literal:
2277        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2279    @classmethod
2280    def string(cls, string) -> Literal:
2281        return cls(this=str(string), is_string=True)
output_name: str
2283    @property
2284    def output_name(self) -> str:
2285        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 = 'literal'
class Join(Expression):
2288class Join(Expression):
2289    arg_types = {
2290        "this": True,
2291        "on": False,
2292        "side": False,
2293        "kind": False,
2294        "using": False,
2295        "method": False,
2296        "global": False,
2297        "hint": False,
2298        "match_condition": False,  # Snowflake
2299    }
2300
2301    @property
2302    def method(self) -> str:
2303        return self.text("method").upper()
2304
2305    @property
2306    def kind(self) -> str:
2307        return self.text("kind").upper()
2308
2309    @property
2310    def side(self) -> str:
2311        return self.text("side").upper()
2312
2313    @property
2314    def hint(self) -> str:
2315        return self.text("hint").upper()
2316
2317    @property
2318    def alias_or_name(self) -> str:
2319        return self.this.alias_or_name
2320
2321    def on(
2322        self,
2323        *expressions: t.Optional[ExpOrStr],
2324        append: bool = True,
2325        dialect: DialectType = None,
2326        copy: bool = True,
2327        **opts,
2328    ) -> Join:
2329        """
2330        Append to or set the ON expressions.
2331
2332        Example:
2333            >>> import sqlglot
2334            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2335            'JOIN x ON y = 1'
2336
2337        Args:
2338            *expressions: the SQL code strings to parse.
2339                If an `Expression` instance is passed, it will be used as-is.
2340                Multiple expressions are combined with an AND operator.
2341            append: if `True`, AND the new expressions to any existing expression.
2342                Otherwise, this resets the expression.
2343            dialect: the dialect used to parse the input expressions.
2344            copy: if `False`, modify this expression instance in-place.
2345            opts: other options to use to parse the input expressions.
2346
2347        Returns:
2348            The modified Join expression.
2349        """
2350        join = _apply_conjunction_builder(
2351            *expressions,
2352            instance=self,
2353            arg="on",
2354            append=append,
2355            dialect=dialect,
2356            copy=copy,
2357            **opts,
2358        )
2359
2360        if join.kind == "CROSS":
2361            join.set("kind", None)
2362
2363        return join
2364
2365    def using(
2366        self,
2367        *expressions: t.Optional[ExpOrStr],
2368        append: bool = True,
2369        dialect: DialectType = None,
2370        copy: bool = True,
2371        **opts,
2372    ) -> Join:
2373        """
2374        Append to or set the USING expressions.
2375
2376        Example:
2377            >>> import sqlglot
2378            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2379            'JOIN x USING (foo, bla)'
2380
2381        Args:
2382            *expressions: the SQL code strings to parse.
2383                If an `Expression` instance is passed, it will be used as-is.
2384            append: if `True`, concatenate the new expressions to the existing "using" list.
2385                Otherwise, this resets the expression.
2386            dialect: the dialect used to parse the input expressions.
2387            copy: if `False`, modify this expression instance in-place.
2388            opts: other options to use to parse the input expressions.
2389
2390        Returns:
2391            The modified Join expression.
2392        """
2393        join = _apply_list_builder(
2394            *expressions,
2395            instance=self,
2396            arg="using",
2397            append=append,
2398            dialect=dialect,
2399            copy=copy,
2400            **opts,
2401        )
2402
2403        if join.kind == "CROSS":
2404            join.set("kind", None)
2405
2406        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
2301    @property
2302    def method(self) -> str:
2303        return self.text("method").upper()
kind: str
2305    @property
2306    def kind(self) -> str:
2307        return self.text("kind").upper()
side: str
2309    @property
2310    def side(self) -> str:
2311        return self.text("side").upper()
hint: str
2313    @property
2314    def hint(self) -> str:
2315        return self.text("hint").upper()
alias_or_name: str
2317    @property
2318    def alias_or_name(self) -> str:
2319        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:
2321    def on(
2322        self,
2323        *expressions: t.Optional[ExpOrStr],
2324        append: bool = True,
2325        dialect: DialectType = None,
2326        copy: bool = True,
2327        **opts,
2328    ) -> Join:
2329        """
2330        Append to or set the ON expressions.
2331
2332        Example:
2333            >>> import sqlglot
2334            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2335            'JOIN x ON y = 1'
2336
2337        Args:
2338            *expressions: the SQL code strings to parse.
2339                If an `Expression` instance is passed, it will be used as-is.
2340                Multiple expressions are combined with an AND operator.
2341            append: if `True`, AND the new expressions to any existing expression.
2342                Otherwise, this resets the expression.
2343            dialect: the dialect used to parse the input expressions.
2344            copy: if `False`, modify this expression instance in-place.
2345            opts: other options to use to parse the input expressions.
2346
2347        Returns:
2348            The modified Join expression.
2349        """
2350        join = _apply_conjunction_builder(
2351            *expressions,
2352            instance=self,
2353            arg="on",
2354            append=append,
2355            dialect=dialect,
2356            copy=copy,
2357            **opts,
2358        )
2359
2360        if join.kind == "CROSS":
2361            join.set("kind", None)
2362
2363        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:
2365    def using(
2366        self,
2367        *expressions: t.Optional[ExpOrStr],
2368        append: bool = True,
2369        dialect: DialectType = None,
2370        copy: bool = True,
2371        **opts,
2372    ) -> Join:
2373        """
2374        Append to or set the USING expressions.
2375
2376        Example:
2377            >>> import sqlglot
2378            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2379            'JOIN x USING (foo, bla)'
2380
2381        Args:
2382            *expressions: the SQL code strings to parse.
2383                If an `Expression` instance is passed, it will be used as-is.
2384            append: if `True`, concatenate the new expressions to the existing "using" list.
2385                Otherwise, this resets the expression.
2386            dialect: the dialect used to parse the input expressions.
2387            copy: if `False`, modify this expression instance in-place.
2388            opts: other options to use to parse the input expressions.
2389
2390        Returns:
2391            The modified Join expression.
2392        """
2393        join = _apply_list_builder(
2394            *expressions,
2395            instance=self,
2396            arg="using",
2397            append=append,
2398            dialect=dialect,
2399            copy=copy,
2400            **opts,
2401        )
2402
2403        if join.kind == "CROSS":
2404            join.set("kind", None)
2405
2406        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):
2409class Lateral(UDTF):
2410    arg_types = {
2411        "this": True,
2412        "view": False,
2413        "outer": False,
2414        "alias": False,
2415        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2416    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2419class MatchRecognizeMeasure(Expression):
2420    arg_types = {
2421        "this": True,
2422        "window_frame": False,
2423    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2426class MatchRecognize(Expression):
2427    arg_types = {
2428        "partition_by": False,
2429        "order": False,
2430        "measures": False,
2431        "rows": False,
2432        "after": False,
2433        "pattern": False,
2434        "define": False,
2435        "alias": False,
2436    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2441class Final(Expression):
2442    pass
key = 'final'
class Offset(Expression):
2445class Offset(Expression):
2446    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2449class Order(Expression):
2450    arg_types = {
2451        "this": False,
2452        "expressions": True,
2453        "interpolate": False,
2454        "siblings": False,
2455    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2459class WithFill(Expression):
2460    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2465class Cluster(Order):
2466    pass
key = 'cluster'
class Distribute(Order):
2469class Distribute(Order):
2470    pass
key = 'distribute'
class Sort(Order):
2473class Sort(Order):
2474    pass
key = 'sort'
class Ordered(Expression):
2477class Ordered(Expression):
2478    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):
2481class Property(Expression):
2482    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2485class AllowedValuesProperty(Expression):
2486    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2489class AlgorithmProperty(Property):
2490    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2493class AutoIncrementProperty(Property):
2494    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2498class AutoRefreshProperty(Property):
2499    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2502class BackupProperty(Property):
2503    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2506class BlockCompressionProperty(Property):
2507    arg_types = {
2508        "autotemp": False,
2509        "always": False,
2510        "default": False,
2511        "manual": False,
2512        "never": False,
2513    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2516class CharacterSetProperty(Property):
2517    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2520class ChecksumProperty(Property):
2521    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2524class CollateProperty(Property):
2525    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2528class CopyGrantsProperty(Property):
2529    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2532class DataBlocksizeProperty(Property):
2533    arg_types = {
2534        "size": False,
2535        "units": False,
2536        "minimum": False,
2537        "maximum": False,
2538        "default": False,
2539    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2542class DataDeletionProperty(Property):
2543    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):
2546class DefinerProperty(Property):
2547    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2550class DistKeyProperty(Property):
2551    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2554class DistStyleProperty(Property):
2555    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2558class EngineProperty(Property):
2559    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2562class HeapProperty(Property):
2563    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2566class ToTableProperty(Property):
2567    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2570class ExecuteAsProperty(Property):
2571    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2574class ExternalProperty(Property):
2575    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2578class FallbackProperty(Property):
2579    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2582class FileFormatProperty(Property):
2583    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2586class FreespaceProperty(Property):
2587    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2590class GlobalProperty(Property):
2591    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2594class IcebergProperty(Property):
2595    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2598class InheritsProperty(Property):
2599    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2602class InputModelProperty(Property):
2603    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2606class OutputModelProperty(Property):
2607    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2610class IsolatedLoadingProperty(Property):
2611    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2614class JournalProperty(Property):
2615    arg_types = {
2616        "no": False,
2617        "dual": False,
2618        "before": False,
2619        "local": False,
2620        "after": False,
2621    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2624class LanguageProperty(Property):
2625    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2629class ClusteredByProperty(Property):
2630    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2633class DictProperty(Property):
2634    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2637class DictSubProperty(Property):
2638    pass
key = 'dictsubproperty'
class DictRange(Property):
2641class DictRange(Property):
2642    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2647class OnCluster(Property):
2648    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2651class LikeProperty(Property):
2652    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2655class LocationProperty(Property):
2656    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2659class LockProperty(Property):
2660    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2663class LockingProperty(Property):
2664    arg_types = {
2665        "this": False,
2666        "kind": True,
2667        "for_or_in": False,
2668        "lock_type": True,
2669        "override": False,
2670    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2673class LogProperty(Property):
2674    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2677class MaterializedProperty(Property):
2678    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2681class MergeBlockRatioProperty(Property):
2682    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):
2685class NoPrimaryIndexProperty(Property):
2686    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2689class OnProperty(Property):
2690    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2693class OnCommitProperty(Property):
2694    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2697class PartitionedByProperty(Property):
2698    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2702class PartitionBoundSpec(Expression):
2703    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2704    arg_types = {
2705        "this": False,
2706        "expression": False,
2707        "from_expressions": False,
2708        "to_expressions": False,
2709    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2712class PartitionedOfProperty(Property):
2713    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2714    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2717class RemoteWithConnectionModelProperty(Property):
2718    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2721class ReturnsProperty(Property):
2722    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):
2725class StrictProperty(Property):
2726    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2729class RowFormatProperty(Property):
2730    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2733class RowFormatDelimitedProperty(Property):
2734    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2735    arg_types = {
2736        "fields": False,
2737        "escaped": False,
2738        "collection_items": False,
2739        "map_keys": False,
2740        "lines": False,
2741        "null": False,
2742        "serde": False,
2743    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2746class RowFormatSerdeProperty(Property):
2747    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2751class QueryTransform(Expression):
2752    arg_types = {
2753        "expressions": True,
2754        "command_script": True,
2755        "schema": False,
2756        "row_format_before": False,
2757        "record_writer": False,
2758        "row_format_after": False,
2759        "record_reader": False,
2760    }
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):
2763class SampleProperty(Property):
2764    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2767class SchemaCommentProperty(Property):
2768    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2771class SerdeProperties(Property):
2772    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2775class SetProperty(Property):
2776    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2779class SharingProperty(Property):
2780    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2783class SetConfigProperty(Property):
2784    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2787class SettingsProperty(Property):
2788    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2791class SortKeyProperty(Property):
2792    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2795class SqlReadWriteProperty(Property):
2796    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2799class SqlSecurityProperty(Property):
2800    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2803class StabilityProperty(Property):
2804    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2807class TemporaryProperty(Property):
2808    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2811class TransformModelProperty(Property):
2812    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2815class TransientProperty(Property):
2816    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2819class UnloggedProperty(Property):
2820    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2824class ViewAttributeProperty(Property):
2825    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2828class VolatileProperty(Property):
2829    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2832class WithDataProperty(Property):
2833    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2836class WithJournalTableProperty(Property):
2837    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2840class WithSystemVersioningProperty(Property):
2841    arg_types = {
2842        "on": False,
2843        "this": False,
2844        "data_consistency": False,
2845        "retention_period": False,
2846        "with": True,
2847    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2850class Properties(Expression):
2851    arg_types = {"expressions": True}
2852
2853    NAME_TO_PROPERTY = {
2854        "ALGORITHM": AlgorithmProperty,
2855        "AUTO_INCREMENT": AutoIncrementProperty,
2856        "CHARACTER SET": CharacterSetProperty,
2857        "CLUSTERED_BY": ClusteredByProperty,
2858        "COLLATE": CollateProperty,
2859        "COMMENT": SchemaCommentProperty,
2860        "DEFINER": DefinerProperty,
2861        "DISTKEY": DistKeyProperty,
2862        "DISTSTYLE": DistStyleProperty,
2863        "ENGINE": EngineProperty,
2864        "EXECUTE AS": ExecuteAsProperty,
2865        "FORMAT": FileFormatProperty,
2866        "LANGUAGE": LanguageProperty,
2867        "LOCATION": LocationProperty,
2868        "LOCK": LockProperty,
2869        "PARTITIONED_BY": PartitionedByProperty,
2870        "RETURNS": ReturnsProperty,
2871        "ROW_FORMAT": RowFormatProperty,
2872        "SORTKEY": SortKeyProperty,
2873    }
2874
2875    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2876
2877    # CREATE property locations
2878    # Form: schema specified
2879    #   create [POST_CREATE]
2880    #     table a [POST_NAME]
2881    #     (b int) [POST_SCHEMA]
2882    #     with ([POST_WITH])
2883    #     index (b) [POST_INDEX]
2884    #
2885    # Form: alias selection
2886    #   create [POST_CREATE]
2887    #     table a [POST_NAME]
2888    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2889    #     index (c) [POST_INDEX]
2890    class Location(AutoName):
2891        POST_CREATE = auto()
2892        POST_NAME = auto()
2893        POST_SCHEMA = auto()
2894        POST_WITH = auto()
2895        POST_ALIAS = auto()
2896        POST_EXPRESSION = auto()
2897        POST_INDEX = auto()
2898        UNSUPPORTED = auto()
2899
2900    @classmethod
2901    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2902        expressions = []
2903        for key, value in properties_dict.items():
2904            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2905            if property_cls:
2906                expressions.append(property_cls(this=convert(value)))
2907            else:
2908                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2909
2910        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:
2900    @classmethod
2901    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2902        expressions = []
2903        for key, value in properties_dict.items():
2904            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2905            if property_cls:
2906                expressions.append(property_cls(this=convert(value)))
2907            else:
2908                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2909
2910        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2890    class Location(AutoName):
2891        POST_CREATE = auto()
2892        POST_NAME = auto()
2893        POST_SCHEMA = auto()
2894        POST_WITH = auto()
2895        POST_ALIAS = auto()
2896        POST_EXPRESSION = auto()
2897        POST_INDEX = auto()
2898        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):
2913class Qualify(Expression):
2914    pass
key = 'qualify'
class InputOutputFormat(Expression):
2917class InputOutputFormat(Expression):
2918    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2922class Return(Expression):
2923    pass
key = 'return'
class Reference(Expression):
2926class Reference(Expression):
2927    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2930class Tuple(Expression):
2931    arg_types = {"expressions": False}
2932
2933    def isin(
2934        self,
2935        *expressions: t.Any,
2936        query: t.Optional[ExpOrStr] = None,
2937        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2938        copy: bool = True,
2939        **opts,
2940    ) -> In:
2941        return In(
2942            this=maybe_copy(self, copy),
2943            expressions=[convert(e, copy=copy) for e in expressions],
2944            query=maybe_parse(query, copy=copy, **opts) if query else None,
2945            unnest=(
2946                Unnest(
2947                    expressions=[
2948                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2949                        for e in ensure_list(unnest)
2950                    ]
2951                )
2952                if unnest
2953                else None
2954            ),
2955        )
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:
2933    def isin(
2934        self,
2935        *expressions: t.Any,
2936        query: t.Optional[ExpOrStr] = None,
2937        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2938        copy: bool = True,
2939        **opts,
2940    ) -> In:
2941        return In(
2942            this=maybe_copy(self, copy),
2943            expressions=[convert(e, copy=copy) for e in expressions],
2944            query=maybe_parse(query, copy=copy, **opts) if query else None,
2945            unnest=(
2946                Unnest(
2947                    expressions=[
2948                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2949                        for e in ensure_list(unnest)
2950                    ]
2951                )
2952                if unnest
2953                else None
2954            ),
2955        )
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):
2986class QueryOption(Expression):
2987    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2991class WithTableHint(Expression):
2992    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2996class IndexTableHint(Expression):
2997    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3001class HistoricalData(Expression):
3002    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3005class Table(Expression):
3006    arg_types = {
3007        "this": False,
3008        "alias": False,
3009        "db": False,
3010        "catalog": False,
3011        "laterals": False,
3012        "joins": False,
3013        "pivots": False,
3014        "hints": False,
3015        "system_time": False,
3016        "version": False,
3017        "format": False,
3018        "pattern": False,
3019        "ordinality": False,
3020        "when": False,
3021        "only": False,
3022        "partition": False,
3023    }
3024
3025    @property
3026    def name(self) -> str:
3027        if isinstance(self.this, Func):
3028            return ""
3029        return self.this.name
3030
3031    @property
3032    def db(self) -> str:
3033        return self.text("db")
3034
3035    @property
3036    def catalog(self) -> str:
3037        return self.text("catalog")
3038
3039    @property
3040    def selects(self) -> t.List[Expression]:
3041        return []
3042
3043    @property
3044    def named_selects(self) -> t.List[str]:
3045        return []
3046
3047    @property
3048    def parts(self) -> t.List[Expression]:
3049        """Return the parts of a table in order catalog, db, table."""
3050        parts: t.List[Expression] = []
3051
3052        for arg in ("catalog", "db", "this"):
3053            part = self.args.get(arg)
3054
3055            if isinstance(part, Dot):
3056                parts.extend(part.flatten())
3057            elif isinstance(part, Expression):
3058                parts.append(part)
3059
3060        return parts
3061
3062    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3063        parts = self.parts
3064        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3065        alias = self.args.get("alias")
3066        if alias:
3067            col = alias_(col, alias.this, copy=copy)
3068        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}
name: str
3025    @property
3026    def name(self) -> str:
3027        if isinstance(self.this, Func):
3028            return ""
3029        return self.this.name
db: str
3031    @property
3032    def db(self) -> str:
3033        return self.text("db")
catalog: str
3035    @property
3036    def catalog(self) -> str:
3037        return self.text("catalog")
selects: List[Expression]
3039    @property
3040    def selects(self) -> t.List[Expression]:
3041        return []
named_selects: List[str]
3043    @property
3044    def named_selects(self) -> t.List[str]:
3045        return []
parts: List[Expression]
3047    @property
3048    def parts(self) -> t.List[Expression]:
3049        """Return the parts of a table in order catalog, db, table."""
3050        parts: t.List[Expression] = []
3051
3052        for arg in ("catalog", "db", "this"):
3053            part = self.args.get(arg)
3054
3055            if isinstance(part, Dot):
3056                parts.extend(part.flatten())
3057            elif isinstance(part, Expression):
3058                parts.append(part)
3059
3060        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3062    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3063        parts = self.parts
3064        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3065        alias = self.args.get("alias")
3066        if alias:
3067            col = alias_(col, alias.this, copy=copy)
3068        return col
key = 'table'
class SetOperation(Query):
3071class SetOperation(Query):
3072    arg_types = {
3073        "with": False,
3074        "this": True,
3075        "expression": True,
3076        "distinct": False,
3077        "by_name": False,
3078        **QUERY_MODIFIERS,
3079    }
3080
3081    def select(
3082        self: S,
3083        *expressions: t.Optional[ExpOrStr],
3084        append: bool = True,
3085        dialect: DialectType = None,
3086        copy: bool = True,
3087        **opts,
3088    ) -> S:
3089        this = maybe_copy(self, copy)
3090        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3091        this.expression.unnest().select(
3092            *expressions, append=append, dialect=dialect, copy=False, **opts
3093        )
3094        return this
3095
3096    @property
3097    def named_selects(self) -> t.List[str]:
3098        return self.this.unnest().named_selects
3099
3100    @property
3101    def is_star(self) -> bool:
3102        return self.this.is_star or self.expression.is_star
3103
3104    @property
3105    def selects(self) -> t.List[Expression]:
3106        return self.this.unnest().selects
3107
3108    @property
3109    def left(self) -> Expression:
3110        return self.this
3111
3112    @property
3113    def right(self) -> Expression:
3114        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:
3081    def select(
3082        self: S,
3083        *expressions: t.Optional[ExpOrStr],
3084        append: bool = True,
3085        dialect: DialectType = None,
3086        copy: bool = True,
3087        **opts,
3088    ) -> S:
3089        this = maybe_copy(self, copy)
3090        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3091        this.expression.unnest().select(
3092            *expressions, append=append, dialect=dialect, copy=False, **opts
3093        )
3094        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]
3096    @property
3097    def named_selects(self) -> t.List[str]:
3098        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3100    @property
3101    def is_star(self) -> bool:
3102        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3104    @property
3105    def selects(self) -> t.List[Expression]:
3106        return self.this.unnest().selects

Returns the query's projections.

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

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:
3218    def group_by(
3219        self,
3220        *expressions: t.Optional[ExpOrStr],
3221        append: bool = True,
3222        dialect: DialectType = None,
3223        copy: bool = True,
3224        **opts,
3225    ) -> Select:
3226        """
3227        Set the GROUP BY expression.
3228
3229        Example:
3230            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3231            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3232
3233        Args:
3234            *expressions: the SQL code strings to parse.
3235                If a `Group` instance is passed, this is used as-is.
3236                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3237                If nothing is passed in then a group by is not applied to the expression
3238            append: if `True`, add to any existing expressions.
3239                Otherwise, this flattens all the `Group` expression into a single expression.
3240            dialect: the dialect used to parse the input expression.
3241            copy: if `False`, modify this expression instance in-place.
3242            opts: other options to use to parse the input expressions.
3243
3244        Returns:
3245            The modified Select expression.
3246        """
3247        if not expressions:
3248            return self if not copy else self.copy()
3249
3250        return _apply_child_list_builder(
3251            *expressions,
3252            instance=self,
3253            arg="group",
3254            append=append,
3255            copy=copy,
3256            prefix="GROUP BY",
3257            into=Group,
3258            dialect=dialect,
3259            **opts,
3260        )

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

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

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:
3342    def select(
3343        self,
3344        *expressions: t.Optional[ExpOrStr],
3345        append: bool = True,
3346        dialect: DialectType = None,
3347        copy: bool = True,
3348        **opts,
3349    ) -> Select:
3350        return _apply_list_builder(
3351            *expressions,
3352            instance=self,
3353            arg="expressions",
3354            append=append,
3355            dialect=dialect,
3356            into=Expression,
3357            copy=copy,
3358            **opts,
3359        )

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:
3361    def lateral(
3362        self,
3363        *expressions: t.Optional[ExpOrStr],
3364        append: bool = True,
3365        dialect: DialectType = None,
3366        copy: bool = True,
3367        **opts,
3368    ) -> Select:
3369        """
3370        Append to or set the LATERAL expressions.
3371
3372        Example:
3373            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3374            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3375
3376        Args:
3377            *expressions: the SQL code strings to parse.
3378                If an `Expression` instance is passed, it will be used as-is.
3379            append: if `True`, add to any existing expressions.
3380                Otherwise, this resets the expressions.
3381            dialect: the dialect used to parse the input expressions.
3382            copy: if `False`, modify this expression instance in-place.
3383            opts: other options to use to parse the input expressions.
3384
3385        Returns:
3386            The modified Select expression.
3387        """
3388        return _apply_list_builder(
3389            *expressions,
3390            instance=self,
3391            arg="laterals",
3392            append=append,
3393            into=Lateral,
3394            prefix="LATERAL VIEW",
3395            dialect=dialect,
3396            copy=copy,
3397            **opts,
3398        )

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

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:
3498    def where(
3499        self,
3500        *expressions: t.Optional[ExpOrStr],
3501        append: bool = True,
3502        dialect: DialectType = None,
3503        copy: bool = True,
3504        **opts,
3505    ) -> Select:
3506        """
3507        Append to or set the WHERE expressions.
3508
3509        Example:
3510            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3511            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3512
3513        Args:
3514            *expressions: the SQL code strings to parse.
3515                If an `Expression` instance is passed, it will be used as-is.
3516                Multiple expressions are combined with an AND operator.
3517            append: if `True`, AND the new expressions to any existing expression.
3518                Otherwise, this resets the expression.
3519            dialect: the dialect used to parse the input expressions.
3520            copy: if `False`, modify this expression instance in-place.
3521            opts: other options to use to parse the input expressions.
3522
3523        Returns:
3524            Select: the modified expression.
3525        """
3526        return _apply_conjunction_builder(
3527            *expressions,
3528            instance=self,
3529            arg="where",
3530            append=append,
3531            into=Where,
3532            dialect=dialect,
3533            copy=copy,
3534            **opts,
3535        )

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

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:
3576    def window(
3577        self,
3578        *expressions: t.Optional[ExpOrStr],
3579        append: bool = True,
3580        dialect: DialectType = None,
3581        copy: bool = True,
3582        **opts,
3583    ) -> Select:
3584        return _apply_list_builder(
3585            *expressions,
3586            instance=self,
3587            arg="windows",
3588            append=append,
3589            into=Window,
3590            dialect=dialect,
3591            copy=copy,
3592            **opts,
3593        )
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:
3595    def qualify(
3596        self,
3597        *expressions: t.Optional[ExpOrStr],
3598        append: bool = True,
3599        dialect: DialectType = None,
3600        copy: bool = True,
3601        **opts,
3602    ) -> Select:
3603        return _apply_conjunction_builder(
3604            *expressions,
3605            instance=self,
3606            arg="qualify",
3607            append=append,
3608            into=Qualify,
3609            dialect=dialect,
3610            copy=copy,
3611            **opts,
3612        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3614    def distinct(
3615        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3616    ) -> Select:
3617        """
3618        Set the OFFSET expression.
3619
3620        Example:
3621            >>> Select().from_("tbl").select("x").distinct().sql()
3622            'SELECT DISTINCT x FROM tbl'
3623
3624        Args:
3625            ons: the expressions to distinct on
3626            distinct: whether the Select should be distinct
3627            copy: if `False`, modify this expression instance in-place.
3628
3629        Returns:
3630            Select: the modified expression.
3631        """
3632        instance = maybe_copy(self, copy)
3633        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3634        instance.set("distinct", Distinct(on=on) if distinct else None)
3635        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:
3637    def ctas(
3638        self,
3639        table: ExpOrStr,
3640        properties: t.Optional[t.Dict] = None,
3641        dialect: DialectType = None,
3642        copy: bool = True,
3643        **opts,
3644    ) -> Create:
3645        """
3646        Convert this expression to a CREATE TABLE AS statement.
3647
3648        Example:
3649            >>> Select().select("*").from_("tbl").ctas("x").sql()
3650            'CREATE TABLE x AS SELECT * FROM tbl'
3651
3652        Args:
3653            table: the SQL code string to parse as the table name.
3654                If another `Expression` instance is passed, it will be used as-is.
3655            properties: an optional mapping of table properties
3656            dialect: the dialect used to parse the input table.
3657            copy: if `False`, modify this expression instance in-place.
3658            opts: other options to use to parse the input table.
3659
3660        Returns:
3661            The new Create expression.
3662        """
3663        instance = maybe_copy(self, copy)
3664        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3665
3666        properties_expression = None
3667        if properties:
3668            properties_expression = Properties.from_dict(properties)
3669
3670        return Create(
3671            this=table_expression,
3672            kind="TABLE",
3673            expression=instance,
3674            properties=properties_expression,
3675        )

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:
3677    def lock(self, update: bool = True, copy: bool = True) -> Select:
3678        """
3679        Set the locking read mode for this expression.
3680
3681        Examples:
3682            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3683            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3684
3685            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3686            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3687
3688        Args:
3689            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3690            copy: if `False`, modify this expression instance in-place.
3691
3692        Returns:
3693            The modified expression.
3694        """
3695        inst = maybe_copy(self, copy)
3696        inst.set("locks", [Lock(update=update)])
3697
3698        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:
3700    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3701        """
3702        Set hints for this expression.
3703
3704        Examples:
3705            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3706            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3707
3708        Args:
3709            hints: The SQL code strings to parse as the hints.
3710                If an `Expression` instance is passed, it will be used as-is.
3711            dialect: The dialect used to parse the hints.
3712            copy: If `False`, modify this expression instance in-place.
3713
3714        Returns:
3715            The modified expression.
3716        """
3717        inst = maybe_copy(self, copy)
3718        inst.set(
3719            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3720        )
3721
3722        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]
3724    @property
3725    def named_selects(self) -> t.List[str]:
3726        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
3728    @property
3729    def is_star(self) -> bool:
3730        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3732    @property
3733    def selects(self) -> t.List[Expression]:
3734        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
3740class Subquery(DerivedTable, Query):
3741    arg_types = {
3742        "this": True,
3743        "alias": False,
3744        "with": False,
3745        **QUERY_MODIFIERS,
3746    }
3747
3748    def unnest(self):
3749        """Returns the first non subquery."""
3750        expression = self
3751        while isinstance(expression, Subquery):
3752            expression = expression.this
3753        return expression
3754
3755    def unwrap(self) -> Subquery:
3756        expression = self
3757        while expression.same_parent and expression.is_wrapper:
3758            expression = t.cast(Subquery, expression.parent)
3759        return expression
3760
3761    def select(
3762        self,
3763        *expressions: t.Optional[ExpOrStr],
3764        append: bool = True,
3765        dialect: DialectType = None,
3766        copy: bool = True,
3767        **opts,
3768    ) -> Subquery:
3769        this = maybe_copy(self, copy)
3770        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3771        return this
3772
3773    @property
3774    def is_wrapper(self) -> bool:
3775        """
3776        Whether this Subquery acts as a simple wrapper around another expression.
3777
3778        SELECT * FROM (((SELECT * FROM t)))
3779                      ^
3780                      This corresponds to a "wrapper" Subquery node
3781        """
3782        return all(v is None for k, v in self.args.items() if k != "this")
3783
3784    @property
3785    def is_star(self) -> bool:
3786        return self.this.is_star
3787
3788    @property
3789    def output_name(self) -> str:
3790        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):
3748    def unnest(self):
3749        """Returns the first non subquery."""
3750        expression = self
3751        while isinstance(expression, Subquery):
3752            expression = expression.this
3753        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3755    def unwrap(self) -> Subquery:
3756        expression = self
3757        while expression.same_parent and expression.is_wrapper:
3758            expression = t.cast(Subquery, expression.parent)
3759        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:
3761    def select(
3762        self,
3763        *expressions: t.Optional[ExpOrStr],
3764        append: bool = True,
3765        dialect: DialectType = None,
3766        copy: bool = True,
3767        **opts,
3768    ) -> Subquery:
3769        this = maybe_copy(self, copy)
3770        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3771        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
3773    @property
3774    def is_wrapper(self) -> bool:
3775        """
3776        Whether this Subquery acts as a simple wrapper around another expression.
3777
3778        SELECT * FROM (((SELECT * FROM t)))
3779                      ^
3780                      This corresponds to a "wrapper" Subquery node
3781        """
3782        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
3784    @property
3785    def is_star(self) -> bool:
3786        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3788    @property
3789    def output_name(self) -> str:
3790        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):
3793class TableSample(Expression):
3794    arg_types = {
3795        "this": False,
3796        "expressions": False,
3797        "method": False,
3798        "bucket_numerator": False,
3799        "bucket_denominator": False,
3800        "bucket_field": False,
3801        "percent": False,
3802        "rows": False,
3803        "size": False,
3804        "seed": False,
3805    }
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):
3808class Tag(Expression):
3809    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3810
3811    arg_types = {
3812        "this": False,
3813        "prefix": False,
3814        "postfix": False,
3815    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3820class Pivot(Expression):
3821    arg_types = {
3822        "this": False,
3823        "alias": False,
3824        "expressions": False,
3825        "field": False,
3826        "unpivot": False,
3827        "using": False,
3828        "group": False,
3829        "columns": False,
3830        "include_nulls": False,
3831    }
3832
3833    @property
3834    def unpivot(self) -> bool:
3835        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False}
unpivot: bool
3833    @property
3834    def unpivot(self) -> bool:
3835        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3838class Window(Condition):
3839    arg_types = {
3840        "this": True,
3841        "partition_by": False,
3842        "order": False,
3843        "spec": False,
3844        "alias": False,
3845        "over": False,
3846        "first": False,
3847    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3850class WindowSpec(Expression):
3851    arg_types = {
3852        "kind": False,
3853        "start": False,
3854        "start_side": False,
3855        "end": False,
3856        "end_side": False,
3857    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3860class PreWhere(Expression):
3861    pass
key = 'prewhere'
class Where(Expression):
3864class Where(Expression):
3865    pass
key = 'where'
class Star(Expression):
3868class Star(Expression):
3869    arg_types = {"except": False, "replace": False, "rename": False}
3870
3871    @property
3872    def name(self) -> str:
3873        return "*"
3874
3875    @property
3876    def output_name(self) -> str:
3877        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3871    @property
3872    def name(self) -> str:
3873        return "*"
output_name: str
3875    @property
3876    def output_name(self) -> str:
3877        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):
3880class Parameter(Condition):
3881    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3884class SessionParameter(Condition):
3885    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3888class Placeholder(Condition):
3889    arg_types = {"this": False, "kind": False}
3890
3891    @property
3892    def name(self) -> str:
3893        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3891    @property
3892    def name(self) -> str:
3893        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3896class Null(Condition):
3897    arg_types: t.Dict[str, t.Any] = {}
3898
3899    @property
3900    def name(self) -> str:
3901        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3899    @property
3900    def name(self) -> str:
3901        return "NULL"
key = 'null'
class Boolean(Condition):
3904class Boolean(Condition):
3905    pass
key = 'boolean'
class DataTypeParam(Expression):
3908class DataTypeParam(Expression):
3909    arg_types = {"this": True, "expression": False}
3910
3911    @property
3912    def name(self) -> str:
3913        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3911    @property
3912    def name(self) -> str:
3913        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3916class DataType(Expression):
3917    arg_types = {
3918        "this": True,
3919        "expressions": False,
3920        "nested": False,
3921        "values": False,
3922        "prefix": False,
3923        "kind": False,
3924    }
3925
3926    class Type(AutoName):
3927        ARRAY = auto()
3928        AGGREGATEFUNCTION = auto()
3929        SIMPLEAGGREGATEFUNCTION = auto()
3930        BIGDECIMAL = auto()
3931        BIGINT = auto()
3932        BIGSERIAL = auto()
3933        BINARY = auto()
3934        BIT = auto()
3935        BOOLEAN = auto()
3936        BPCHAR = auto()
3937        CHAR = auto()
3938        DATE = auto()
3939        DATE32 = auto()
3940        DATEMULTIRANGE = auto()
3941        DATERANGE = auto()
3942        DATETIME = auto()
3943        DATETIME64 = auto()
3944        DECIMAL = auto()
3945        DOUBLE = auto()
3946        ENUM = auto()
3947        ENUM8 = auto()
3948        ENUM16 = auto()
3949        FIXEDSTRING = auto()
3950        FLOAT = auto()
3951        GEOGRAPHY = auto()
3952        GEOMETRY = auto()
3953        HLLSKETCH = auto()
3954        HSTORE = auto()
3955        IMAGE = auto()
3956        INET = auto()
3957        INT = auto()
3958        INT128 = auto()
3959        INT256 = auto()
3960        INT4MULTIRANGE = auto()
3961        INT4RANGE = auto()
3962        INT8MULTIRANGE = auto()
3963        INT8RANGE = auto()
3964        INTERVAL = auto()
3965        IPADDRESS = auto()
3966        IPPREFIX = auto()
3967        IPV4 = auto()
3968        IPV6 = auto()
3969        JSON = auto()
3970        JSONB = auto()
3971        LIST = auto()
3972        LONGBLOB = auto()
3973        LONGTEXT = auto()
3974        LOWCARDINALITY = auto()
3975        MAP = auto()
3976        MEDIUMBLOB = auto()
3977        MEDIUMINT = auto()
3978        MEDIUMTEXT = auto()
3979        MONEY = auto()
3980        NAME = auto()
3981        NCHAR = auto()
3982        NESTED = auto()
3983        NULL = auto()
3984        NULLABLE = auto()
3985        NUMMULTIRANGE = auto()
3986        NUMRANGE = auto()
3987        NVARCHAR = auto()
3988        OBJECT = auto()
3989        ROWVERSION = auto()
3990        SERIAL = auto()
3991        SET = auto()
3992        SMALLINT = auto()
3993        SMALLMONEY = auto()
3994        SMALLSERIAL = auto()
3995        STRUCT = auto()
3996        SUPER = auto()
3997        TEXT = auto()
3998        TINYBLOB = auto()
3999        TINYTEXT = auto()
4000        TIME = auto()
4001        TIMETZ = auto()
4002        TIMESTAMP = auto()
4003        TIMESTAMPNTZ = auto()
4004        TIMESTAMPLTZ = auto()
4005        TIMESTAMPTZ = auto()
4006        TIMESTAMP_S = auto()
4007        TIMESTAMP_MS = auto()
4008        TIMESTAMP_NS = auto()
4009        TINYINT = auto()
4010        TSMULTIRANGE = auto()
4011        TSRANGE = auto()
4012        TSTZMULTIRANGE = auto()
4013        TSTZRANGE = auto()
4014        UBIGINT = auto()
4015        UINT = auto()
4016        UINT128 = auto()
4017        UINT256 = auto()
4018        UMEDIUMINT = auto()
4019        UDECIMAL = auto()
4020        UNIQUEIDENTIFIER = auto()
4021        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4022        USERDEFINED = "USER-DEFINED"
4023        USMALLINT = auto()
4024        UTINYINT = auto()
4025        UUID = auto()
4026        VARBINARY = auto()
4027        VARCHAR = auto()
4028        VARIANT = auto()
4029        XML = auto()
4030        YEAR = auto()
4031        TDIGEST = auto()
4032
4033    STRUCT_TYPES = {
4034        Type.NESTED,
4035        Type.OBJECT,
4036        Type.STRUCT,
4037    }
4038
4039    NESTED_TYPES = {
4040        *STRUCT_TYPES,
4041        Type.ARRAY,
4042        Type.MAP,
4043    }
4044
4045    TEXT_TYPES = {
4046        Type.CHAR,
4047        Type.NCHAR,
4048        Type.NVARCHAR,
4049        Type.TEXT,
4050        Type.VARCHAR,
4051        Type.NAME,
4052    }
4053
4054    SIGNED_INTEGER_TYPES = {
4055        Type.BIGINT,
4056        Type.INT,
4057        Type.INT128,
4058        Type.INT256,
4059        Type.MEDIUMINT,
4060        Type.SMALLINT,
4061        Type.TINYINT,
4062    }
4063
4064    UNSIGNED_INTEGER_TYPES = {
4065        Type.UBIGINT,
4066        Type.UINT,
4067        Type.UINT128,
4068        Type.UINT256,
4069        Type.UMEDIUMINT,
4070        Type.USMALLINT,
4071        Type.UTINYINT,
4072    }
4073
4074    INTEGER_TYPES = {
4075        *SIGNED_INTEGER_TYPES,
4076        *UNSIGNED_INTEGER_TYPES,
4077        Type.BIT,
4078    }
4079
4080    FLOAT_TYPES = {
4081        Type.DOUBLE,
4082        Type.FLOAT,
4083    }
4084
4085    REAL_TYPES = {
4086        *FLOAT_TYPES,
4087        Type.BIGDECIMAL,
4088        Type.DECIMAL,
4089        Type.MONEY,
4090        Type.SMALLMONEY,
4091        Type.UDECIMAL,
4092    }
4093
4094    NUMERIC_TYPES = {
4095        *INTEGER_TYPES,
4096        *REAL_TYPES,
4097    }
4098
4099    TEMPORAL_TYPES = {
4100        Type.DATE,
4101        Type.DATE32,
4102        Type.DATETIME,
4103        Type.DATETIME64,
4104        Type.TIME,
4105        Type.TIMESTAMP,
4106        Type.TIMESTAMPNTZ,
4107        Type.TIMESTAMPLTZ,
4108        Type.TIMESTAMPTZ,
4109        Type.TIMESTAMP_MS,
4110        Type.TIMESTAMP_NS,
4111        Type.TIMESTAMP_S,
4112        Type.TIMETZ,
4113    }
4114
4115    @classmethod
4116    def build(
4117        cls,
4118        dtype: DATA_TYPE,
4119        dialect: DialectType = None,
4120        udt: bool = False,
4121        copy: bool = True,
4122        **kwargs,
4123    ) -> DataType:
4124        """
4125        Constructs a DataType object.
4126
4127        Args:
4128            dtype: the data type of interest.
4129            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4130            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4131                DataType, thus creating a user-defined type.
4132            copy: whether to copy the data type.
4133            kwargs: additional arguments to pass in the constructor of DataType.
4134
4135        Returns:
4136            The constructed DataType object.
4137        """
4138        from sqlglot import parse_one
4139
4140        if isinstance(dtype, str):
4141            if dtype.upper() == "UNKNOWN":
4142                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4143
4144            try:
4145                data_type_exp = parse_one(
4146                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4147                )
4148            except ParseError:
4149                if udt:
4150                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4151                raise
4152        elif isinstance(dtype, DataType.Type):
4153            data_type_exp = DataType(this=dtype)
4154        elif isinstance(dtype, DataType):
4155            return maybe_copy(dtype, copy)
4156        else:
4157            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4158
4159        return DataType(**{**data_type_exp.args, **kwargs})
4160
4161    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4162        """
4163        Checks whether this DataType matches one of the provided data types. Nested types or precision
4164        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4165
4166        Args:
4167            dtypes: the data types to compare this DataType to.
4168
4169        Returns:
4170            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4171        """
4172        for dtype in dtypes:
4173            other = DataType.build(dtype, copy=False, udt=True)
4174
4175            if (
4176                other.expressions
4177                or self.this == DataType.Type.USERDEFINED
4178                or other.this == DataType.Type.USERDEFINED
4179            ):
4180                matches = self == other
4181            else:
4182                matches = self.this == other.this
4183
4184            if matches:
4185                return True
4186        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>}
NESTED_TYPES = {<Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>, <Type.ARRAY: 'ARRAY'>, <Type.OBJECT: 'OBJECT'>, <Type.MAP: 'MAP'>}
TEXT_TYPES = {<Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.TEXT: 'TEXT'>, <Type.NAME: 'NAME'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NCHAR: 'NCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT: 'UINT'>, <Type.UINT256: 'UINT256'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>}
INTEGER_TYPES = {<Type.UINT: 'UINT'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT256: 'UINT256'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.BIT: 'BIT'>, <Type.INT: 'INT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT128: 'UINT128'>, <Type.INT256: 'INT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.MONEY: 'MONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>}
NUMERIC_TYPES = {<Type.UINT: 'UINT'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT: 'INT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.MONEY: 'MONEY'>, <Type.USMALLINT: 'USMALLINT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.BIT: 'BIT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UINT128: 'UINT128'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UDECIMAL: 'UDECIMAL'>}
TEMPORAL_TYPES = {<Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATE: 'DATE'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATE32: 'DATE32'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMETZ: 'TIMETZ'>}
@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:
4115    @classmethod
4116    def build(
4117        cls,
4118        dtype: DATA_TYPE,
4119        dialect: DialectType = None,
4120        udt: bool = False,
4121        copy: bool = True,
4122        **kwargs,
4123    ) -> DataType:
4124        """
4125        Constructs a DataType object.
4126
4127        Args:
4128            dtype: the data type of interest.
4129            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4130            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4131                DataType, thus creating a user-defined type.
4132            copy: whether to copy the data type.
4133            kwargs: additional arguments to pass in the constructor of DataType.
4134
4135        Returns:
4136            The constructed DataType object.
4137        """
4138        from sqlglot import parse_one
4139
4140        if isinstance(dtype, str):
4141            if dtype.upper() == "UNKNOWN":
4142                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4143
4144            try:
4145                data_type_exp = parse_one(
4146                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4147                )
4148            except ParseError:
4149                if udt:
4150                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4151                raise
4152        elif isinstance(dtype, DataType.Type):
4153            data_type_exp = DataType(this=dtype)
4154        elif isinstance(dtype, DataType):
4155            return maybe_copy(dtype, copy)
4156        else:
4157            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4158
4159        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:
4161    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4162        """
4163        Checks whether this DataType matches one of the provided data types. Nested types or precision
4164        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4165
4166        Args:
4167            dtypes: the data types to compare this DataType to.
4168
4169        Returns:
4170            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4171        """
4172        for dtype in dtypes:
4173            other = DataType.build(dtype, copy=False, udt=True)
4174
4175            if (
4176                other.expressions
4177                or self.this == DataType.Type.USERDEFINED
4178                or other.this == DataType.Type.USERDEFINED
4179            ):
4180                matches = self == other
4181            else:
4182                matches = self.this == other.this
4183
4184            if matches:
4185                return True
4186        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):
3926    class Type(AutoName):
3927        ARRAY = auto()
3928        AGGREGATEFUNCTION = auto()
3929        SIMPLEAGGREGATEFUNCTION = auto()
3930        BIGDECIMAL = auto()
3931        BIGINT = auto()
3932        BIGSERIAL = auto()
3933        BINARY = auto()
3934        BIT = auto()
3935        BOOLEAN = auto()
3936        BPCHAR = auto()
3937        CHAR = auto()
3938        DATE = auto()
3939        DATE32 = auto()
3940        DATEMULTIRANGE = auto()
3941        DATERANGE = auto()
3942        DATETIME = auto()
3943        DATETIME64 = auto()
3944        DECIMAL = auto()
3945        DOUBLE = auto()
3946        ENUM = auto()
3947        ENUM8 = auto()
3948        ENUM16 = auto()
3949        FIXEDSTRING = auto()
3950        FLOAT = auto()
3951        GEOGRAPHY = auto()
3952        GEOMETRY = auto()
3953        HLLSKETCH = auto()
3954        HSTORE = auto()
3955        IMAGE = auto()
3956        INET = auto()
3957        INT = auto()
3958        INT128 = auto()
3959        INT256 = auto()
3960        INT4MULTIRANGE = auto()
3961        INT4RANGE = auto()
3962        INT8MULTIRANGE = auto()
3963        INT8RANGE = auto()
3964        INTERVAL = auto()
3965        IPADDRESS = auto()
3966        IPPREFIX = auto()
3967        IPV4 = auto()
3968        IPV6 = auto()
3969        JSON = auto()
3970        JSONB = auto()
3971        LIST = auto()
3972        LONGBLOB = auto()
3973        LONGTEXT = auto()
3974        LOWCARDINALITY = auto()
3975        MAP = auto()
3976        MEDIUMBLOB = auto()
3977        MEDIUMINT = auto()
3978        MEDIUMTEXT = auto()
3979        MONEY = auto()
3980        NAME = auto()
3981        NCHAR = auto()
3982        NESTED = auto()
3983        NULL = auto()
3984        NULLABLE = auto()
3985        NUMMULTIRANGE = auto()
3986        NUMRANGE = auto()
3987        NVARCHAR = auto()
3988        OBJECT = auto()
3989        ROWVERSION = auto()
3990        SERIAL = auto()
3991        SET = auto()
3992        SMALLINT = auto()
3993        SMALLMONEY = auto()
3994        SMALLSERIAL = auto()
3995        STRUCT = auto()
3996        SUPER = auto()
3997        TEXT = auto()
3998        TINYBLOB = auto()
3999        TINYTEXT = auto()
4000        TIME = auto()
4001        TIMETZ = auto()
4002        TIMESTAMP = auto()
4003        TIMESTAMPNTZ = auto()
4004        TIMESTAMPLTZ = auto()
4005        TIMESTAMPTZ = auto()
4006        TIMESTAMP_S = auto()
4007        TIMESTAMP_MS = auto()
4008        TIMESTAMP_NS = auto()
4009        TINYINT = auto()
4010        TSMULTIRANGE = auto()
4011        TSRANGE = auto()
4012        TSTZMULTIRANGE = auto()
4013        TSTZRANGE = auto()
4014        UBIGINT = auto()
4015        UINT = auto()
4016        UINT128 = auto()
4017        UINT256 = auto()
4018        UMEDIUMINT = auto()
4019        UDECIMAL = auto()
4020        UNIQUEIDENTIFIER = auto()
4021        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4022        USERDEFINED = "USER-DEFINED"
4023        USMALLINT = auto()
4024        UTINYINT = auto()
4025        UUID = auto()
4026        VARBINARY = auto()
4027        VARCHAR = auto()
4028        VARIANT = auto()
4029        XML = auto()
4030        YEAR = auto()
4031        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'>
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):
4193class PseudoType(DataType):
4194    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4198class ObjectIdentifier(DataType):
4199    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4203class SubqueryPredicate(Predicate):
4204    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4207class All(SubqueryPredicate):
4208    pass
key = 'all'
class Any(SubqueryPredicate):
4211class Any(SubqueryPredicate):
4212    pass
key = 'any'
class Exists(SubqueryPredicate):
4215class Exists(SubqueryPredicate):
4216    pass
key = 'exists'
class Command(Expression):
4221class Command(Expression):
4222    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4225class Transaction(Expression):
4226    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4229class Commit(Expression):
4230    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4233class Rollback(Expression):
4234    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4237class AlterTable(Expression):
4238    arg_types = {
4239        "this": True,
4240        "actions": True,
4241        "exists": False,
4242        "only": False,
4243        "options": False,
4244        "cluster": False,
4245    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False}
key = 'altertable'
class AddConstraint(Expression):
4248class AddConstraint(Expression):
4249    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4252class DropPartition(Expression):
4253    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4257class ReplacePartition(Expression):
4258    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4262class Binary(Condition):
4263    arg_types = {"this": True, "expression": True}
4264
4265    @property
4266    def left(self) -> Expression:
4267        return self.this
4268
4269    @property
4270    def right(self) -> Expression:
4271        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4265    @property
4266    def left(self) -> Expression:
4267        return self.this
right: Expression
4269    @property
4270    def right(self) -> Expression:
4271        return self.expression
key = 'binary'
class Add(Binary):
4274class Add(Binary):
4275    pass
key = 'add'
class Connector(Binary):
4278class Connector(Binary):
4279    pass
key = 'connector'
class And(Connector):
4282class And(Connector):
4283    pass
key = 'and'
class Or(Connector):
4286class Or(Connector):
4287    pass
key = 'or'
class BitwiseAnd(Binary):
4290class BitwiseAnd(Binary):
4291    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4294class BitwiseLeftShift(Binary):
4295    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4298class BitwiseOr(Binary):
4299    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4302class BitwiseRightShift(Binary):
4303    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4306class BitwiseXor(Binary):
4307    pass
key = 'bitwisexor'
class Div(Binary):
4310class Div(Binary):
4311    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):
4314class Overlaps(Binary):
4315    pass
key = 'overlaps'
class Dot(Binary):
4318class Dot(Binary):
4319    @property
4320    def is_star(self) -> bool:
4321        return self.expression.is_star
4322
4323    @property
4324    def name(self) -> str:
4325        return self.expression.name
4326
4327    @property
4328    def output_name(self) -> str:
4329        return self.name
4330
4331    @classmethod
4332    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4333        """Build a Dot object with a sequence of expressions."""
4334        if len(expressions) < 2:
4335            raise ValueError("Dot requires >= 2 expressions.")
4336
4337        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4338
4339    @property
4340    def parts(self) -> t.List[Expression]:
4341        """Return the parts of a table / column in order catalog, db, table."""
4342        this, *parts = self.flatten()
4343
4344        parts.reverse()
4345
4346        for arg in COLUMN_PARTS:
4347            part = this.args.get(arg)
4348
4349            if isinstance(part, Expression):
4350                parts.append(part)
4351
4352        parts.reverse()
4353        return parts
is_star: bool
4319    @property
4320    def is_star(self) -> bool:
4321        return self.expression.is_star

Checks whether an expression is a star.

name: str
4323    @property
4324    def name(self) -> str:
4325        return self.expression.name
output_name: str
4327    @property
4328    def output_name(self) -> str:
4329        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:
4331    @classmethod
4332    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4333        """Build a Dot object with a sequence of expressions."""
4334        if len(expressions) < 2:
4335            raise ValueError("Dot requires >= 2 expressions.")
4336
4337        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]
4339    @property
4340    def parts(self) -> t.List[Expression]:
4341        """Return the parts of a table / column in order catalog, db, table."""
4342        this, *parts = self.flatten()
4343
4344        parts.reverse()
4345
4346        for arg in COLUMN_PARTS:
4347            part = this.args.get(arg)
4348
4349            if isinstance(part, Expression):
4350                parts.append(part)
4351
4352        parts.reverse()
4353        return parts

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

key = 'dot'
class DPipe(Binary):
4356class DPipe(Binary):
4357    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4360class EQ(Binary, Predicate):
4361    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4364class NullSafeEQ(Binary, Predicate):
4365    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4368class NullSafeNEQ(Binary, Predicate):
4369    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4373class PropertyEQ(Binary):
4374    pass
key = 'propertyeq'
class Distance(Binary):
4377class Distance(Binary):
4378    pass
key = 'distance'
class Escape(Binary):
4381class Escape(Binary):
4382    pass
key = 'escape'
class Glob(Binary, Predicate):
4385class Glob(Binary, Predicate):
4386    pass
key = 'glob'
class GT(Binary, Predicate):
4389class GT(Binary, Predicate):
4390    pass
key = 'gt'
class GTE(Binary, Predicate):
4393class GTE(Binary, Predicate):
4394    pass
key = 'gte'
class ILike(Binary, Predicate):
4397class ILike(Binary, Predicate):
4398    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4401class ILikeAny(Binary, Predicate):
4402    pass
key = 'ilikeany'
class IntDiv(Binary):
4405class IntDiv(Binary):
4406    pass
key = 'intdiv'
class Is(Binary, Predicate):
4409class Is(Binary, Predicate):
4410    pass
key = 'is'
class Kwarg(Binary):
4413class Kwarg(Binary):
4414    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4417class Like(Binary, Predicate):
4418    pass
key = 'like'
class LikeAny(Binary, Predicate):
4421class LikeAny(Binary, Predicate):
4422    pass
key = 'likeany'
class LT(Binary, Predicate):
4425class LT(Binary, Predicate):
4426    pass
key = 'lt'
class LTE(Binary, Predicate):
4429class LTE(Binary, Predicate):
4430    pass
key = 'lte'
class Mod(Binary):
4433class Mod(Binary):
4434    pass
key = 'mod'
class Mul(Binary):
4437class Mul(Binary):
4438    pass
key = 'mul'
class NEQ(Binary, Predicate):
4441class NEQ(Binary, Predicate):
4442    pass
key = 'neq'
class Operator(Binary):
4446class Operator(Binary):
4447    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4450class SimilarTo(Binary, Predicate):
4451    pass
key = 'similarto'
class Slice(Binary):
4454class Slice(Binary):
4455    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4458class Sub(Binary):
4459    pass
key = 'sub'
class Unary(Condition):
4464class Unary(Condition):
4465    pass
key = 'unary'
class BitwiseNot(Unary):
4468class BitwiseNot(Unary):
4469    pass
key = 'bitwisenot'
class Not(Unary):
4472class Not(Unary):
4473    pass
key = 'not'
class Paren(Unary):
4476class Paren(Unary):
4477    @property
4478    def output_name(self) -> str:
4479        return self.this.name
output_name: str
4477    @property
4478    def output_name(self) -> str:
4479        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):
4482class Neg(Unary):
4483    pass
key = 'neg'
class Alias(Expression):
4486class Alias(Expression):
4487    arg_types = {"this": True, "alias": False}
4488
4489    @property
4490    def output_name(self) -> str:
4491        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4489    @property
4490    def output_name(self) -> str:
4491        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):
4496class PivotAlias(Alias):
4497    pass
key = 'pivotalias'
class Aliases(Expression):
4500class Aliases(Expression):
4501    arg_types = {"this": True, "expressions": True}
4502
4503    @property
4504    def aliases(self):
4505        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4503    @property
4504    def aliases(self):
4505        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4509class AtIndex(Expression):
4510    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4513class AtTimeZone(Expression):
4514    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4517class FromTimeZone(Expression):
4518    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4521class Between(Predicate):
4522    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4525class Bracket(Condition):
4526    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4527    arg_types = {
4528        "this": True,
4529        "expressions": True,
4530        "offset": False,
4531        "safe": False,
4532        "returns_list_for_maps": False,
4533    }
4534
4535    @property
4536    def output_name(self) -> str:
4537        if len(self.expressions) == 1:
4538            return self.expressions[0].output_name
4539
4540        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4535    @property
4536    def output_name(self) -> str:
4537        if len(self.expressions) == 1:
4538            return self.expressions[0].output_name
4539
4540        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):
4543class Distinct(Expression):
4544    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4547class In(Predicate):
4548    arg_types = {
4549        "this": True,
4550        "expressions": False,
4551        "query": False,
4552        "unnest": False,
4553        "field": False,
4554        "is_global": False,
4555    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4559class ForIn(Expression):
4560    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4563class TimeUnit(Expression):
4564    """Automatically converts unit arg into a var."""
4565
4566    arg_types = {"unit": False}
4567
4568    UNABBREVIATED_UNIT_NAME = {
4569        "D": "DAY",
4570        "H": "HOUR",
4571        "M": "MINUTE",
4572        "MS": "MILLISECOND",
4573        "NS": "NANOSECOND",
4574        "Q": "QUARTER",
4575        "S": "SECOND",
4576        "US": "MICROSECOND",
4577        "W": "WEEK",
4578        "Y": "YEAR",
4579    }
4580
4581    VAR_LIKE = (Column, Literal, Var)
4582
4583    def __init__(self, **args):
4584        unit = args.get("unit")
4585        if isinstance(unit, self.VAR_LIKE):
4586            args["unit"] = Var(
4587                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4588            )
4589        elif isinstance(unit, Week):
4590            unit.set("this", Var(this=unit.this.name.upper()))
4591
4592        super().__init__(**args)
4593
4594    @property
4595    def unit(self) -> t.Optional[Var | IntervalSpan]:
4596        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4583    def __init__(self, **args):
4584        unit = args.get("unit")
4585        if isinstance(unit, self.VAR_LIKE):
4586            args["unit"] = Var(
4587                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4588            )
4589        elif isinstance(unit, Week):
4590            unit.set("this", Var(this=unit.this.name.upper()))
4591
4592        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]
4594    @property
4595    def unit(self) -> t.Optional[Var | IntervalSpan]:
4596        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4599class IntervalOp(TimeUnit):
4600    arg_types = {"unit": True, "expression": True}
4601
4602    def interval(self):
4603        return Interval(
4604            this=self.expression.copy(),
4605            unit=self.unit.copy(),
4606        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4602    def interval(self):
4603        return Interval(
4604            this=self.expression.copy(),
4605            unit=self.unit.copy(),
4606        )
key = 'intervalop'
class IntervalSpan(DataType):
4612class IntervalSpan(DataType):
4613    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4616class Interval(TimeUnit):
4617    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4620class IgnoreNulls(Expression):
4621    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4624class RespectNulls(Expression):
4625    pass
key = 'respectnulls'
class HavingMax(Expression):
4629class HavingMax(Expression):
4630    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4634class Func(Condition):
4635    """
4636    The base class for all function expressions.
4637
4638    Attributes:
4639        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4640            treated as a variable length argument and the argument's value will be stored as a list.
4641        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4642            function expression. These values are used to map this node to a name during parsing as
4643            well as to provide the function's name during SQL string generation. By default the SQL
4644            name is set to the expression's class name transformed to snake case.
4645    """
4646
4647    is_var_len_args = False
4648
4649    @classmethod
4650    def from_arg_list(cls, args):
4651        if cls.is_var_len_args:
4652            all_arg_keys = list(cls.arg_types)
4653            # If this function supports variable length argument treat the last argument as such.
4654            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4655            num_non_var = len(non_var_len_arg_keys)
4656
4657            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4658            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4659        else:
4660            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4661
4662        return cls(**args_dict)
4663
4664    @classmethod
4665    def sql_names(cls):
4666        if cls is Func:
4667            raise NotImplementedError(
4668                "SQL name is only supported by concrete function implementations"
4669            )
4670        if "_sql_names" not in cls.__dict__:
4671            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4672        return cls._sql_names
4673
4674    @classmethod
4675    def sql_name(cls):
4676        return cls.sql_names()[0]
4677
4678    @classmethod
4679    def default_parser_mappings(cls):
4680        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):
4649    @classmethod
4650    def from_arg_list(cls, args):
4651        if cls.is_var_len_args:
4652            all_arg_keys = list(cls.arg_types)
4653            # If this function supports variable length argument treat the last argument as such.
4654            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4655            num_non_var = len(non_var_len_arg_keys)
4656
4657            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4658            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4659        else:
4660            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4661
4662        return cls(**args_dict)
@classmethod
def sql_names(cls):
4664    @classmethod
4665    def sql_names(cls):
4666        if cls is Func:
4667            raise NotImplementedError(
4668                "SQL name is only supported by concrete function implementations"
4669            )
4670        if "_sql_names" not in cls.__dict__:
4671            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4672        return cls._sql_names
@classmethod
def sql_name(cls):
4674    @classmethod
4675    def sql_name(cls):
4676        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4678    @classmethod
4679    def default_parser_mappings(cls):
4680        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4683class AggFunc(Func):
4684    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4687class ParameterizedAgg(AggFunc):
4688    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4691class Abs(Func):
4692    pass
key = 'abs'
class ArgMax(AggFunc):
4695class ArgMax(AggFunc):
4696    arg_types = {"this": True, "expression": True, "count": False}
4697    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4700class ArgMin(AggFunc):
4701    arg_types = {"this": True, "expression": True, "count": False}
4702    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4705class ApproxTopK(AggFunc):
4706    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4709class Flatten(Func):
4710    pass
key = 'flatten'
class Transform(Func):
4714class Transform(Func):
4715    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4718class Anonymous(Func):
4719    arg_types = {"this": True, "expressions": False}
4720    is_var_len_args = True
4721
4722    @property
4723    def name(self) -> str:
4724        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
4722    @property
4723    def name(self) -> str:
4724        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4727class AnonymousAggFunc(AggFunc):
4728    arg_types = {"this": True, "expressions": False}
4729    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4733class CombinedAggFunc(AnonymousAggFunc):
4734    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4737class CombinedParameterizedAgg(ParameterizedAgg):
4738    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):
4743class Hll(AggFunc):
4744    arg_types = {"this": True, "expressions": False}
4745    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4748class ApproxDistinct(AggFunc):
4749    arg_types = {"this": True, "accuracy": False}
4750    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4753class Array(Func):
4754    arg_types = {"expressions": False}
4755    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4759class ToArray(Func):
4760    pass
key = 'toarray'
class List(Func):
4764class List(Func):
4765    arg_types = {"expressions": False}
4766    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class ToChar(Func):
4771class ToChar(Func):
4772    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4777class ToNumber(Func):
4778    arg_types = {
4779        "this": True,
4780        "format": False,
4781        "nlsparam": False,
4782        "precision": False,
4783        "scale": False,
4784    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4788class Convert(Func):
4789    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4792class GenerateSeries(Func):
4793    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
arg_types = {'start': True, 'end': True, 'step': False, 'is_end_exclusive': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4796class ArrayAgg(AggFunc):
4797    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4800class ArrayUniqueAgg(AggFunc):
4801    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4804class ArrayAll(Func):
4805    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4809class ArrayAny(Func):
4810    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4813class ArrayConcat(Func):
4814    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4815    arg_types = {"this": True, "expressions": False}
4816    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4819class ArrayConstructCompact(Func):
4820    arg_types = {"expressions": True}
4821    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4824class ArrayContains(Binary, Func):
4825    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4828class ArrayContainsAll(Binary, Func):
4829    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4832class ArrayFilter(Func):
4833    arg_types = {"this": True, "expression": True}
4834    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4837class ArrayToString(Func):
4838    arg_types = {"this": True, "expression": True, "null": False}
4839    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4842class StringToArray(Func):
4843    arg_types = {"this": True, "expression": True, "null": False}
4844    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4847class ArrayOverlaps(Binary, Func):
4848    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4851class ArraySize(Func):
4852    arg_types = {"this": True, "expression": False}
4853    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4856class ArraySort(Func):
4857    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4860class ArraySum(Func):
4861    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4864class ArrayUnionAgg(AggFunc):
4865    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4868class Avg(AggFunc):
4869    pass
key = 'avg'
class AnyValue(AggFunc):
4872class AnyValue(AggFunc):
4873    pass
key = 'anyvalue'
class Lag(AggFunc):
4876class Lag(AggFunc):
4877    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4880class Lead(AggFunc):
4881    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4886class First(AggFunc):
4887    pass
key = 'first'
class Last(AggFunc):
4890class Last(AggFunc):
4891    pass
key = 'last'
class FirstValue(AggFunc):
4894class FirstValue(AggFunc):
4895    pass
key = 'firstvalue'
class LastValue(AggFunc):
4898class LastValue(AggFunc):
4899    pass
key = 'lastvalue'
class NthValue(AggFunc):
4902class NthValue(AggFunc):
4903    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4906class Case(Func):
4907    arg_types = {"this": False, "ifs": True, "default": False}
4908
4909    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4910        instance = maybe_copy(self, copy)
4911        instance.append(
4912            "ifs",
4913            If(
4914                this=maybe_parse(condition, copy=copy, **opts),
4915                true=maybe_parse(then, copy=copy, **opts),
4916            ),
4917        )
4918        return instance
4919
4920    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4921        instance = maybe_copy(self, copy)
4922        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4923        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:
4909    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4910        instance = maybe_copy(self, copy)
4911        instance.append(
4912            "ifs",
4913            If(
4914                this=maybe_parse(condition, copy=copy, **opts),
4915                true=maybe_parse(then, copy=copy, **opts),
4916            ),
4917        )
4918        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4920    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4921        instance = maybe_copy(self, copy)
4922        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4923        return instance
key = 'case'
class Cast(Func):
4926class Cast(Func):
4927    arg_types = {
4928        "this": True,
4929        "to": True,
4930        "format": False,
4931        "safe": False,
4932        "action": False,
4933    }
4934
4935    @property
4936    def name(self) -> str:
4937        return self.this.name
4938
4939    @property
4940    def to(self) -> DataType:
4941        return self.args["to"]
4942
4943    @property
4944    def output_name(self) -> str:
4945        return self.name
4946
4947    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4948        """
4949        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4950        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4951        array<int> != array<float>.
4952
4953        Args:
4954            dtypes: the data types to compare this Cast's DataType to.
4955
4956        Returns:
4957            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4958        """
4959        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4935    @property
4936    def name(self) -> str:
4937        return self.this.name
to: DataType
4939    @property
4940    def to(self) -> DataType:
4941        return self.args["to"]
output_name: str
4943    @property
4944    def output_name(self) -> str:
4945        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:
4947    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4948        """
4949        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4950        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4951        array<int> != array<float>.
4952
4953        Args:
4954            dtypes: the data types to compare this Cast's DataType to.
4955
4956        Returns:
4957            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4958        """
4959        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):
4962class TryCast(Cast):
4963    pass
key = 'trycast'
class Try(Func):
4966class Try(Func):
4967    pass
key = 'try'
class CastToStrType(Func):
4970class CastToStrType(Func):
4971    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4974class Collate(Binary, Func):
4975    pass
key = 'collate'
class Ceil(Func):
4978class Ceil(Func):
4979    arg_types = {"this": True, "decimals": False}
4980    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4983class Coalesce(Func):
4984    arg_types = {"this": True, "expressions": False}
4985    is_var_len_args = True
4986    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4989class Chr(Func):
4990    arg_types = {"this": True, "charset": False, "expressions": False}
4991    is_var_len_args = True
4992    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4995class Concat(Func):
4996    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4997    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5000class ConcatWs(Concat):
5001    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5005class ConnectByRoot(Func):
5006    pass
key = 'connectbyroot'
class Count(AggFunc):
5009class Count(AggFunc):
5010    arg_types = {"this": False, "expressions": False}
5011    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5014class CountIf(AggFunc):
5015    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5019class Cbrt(Func):
5020    pass
key = 'cbrt'
class CurrentDate(Func):
5023class CurrentDate(Func):
5024    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5027class CurrentDatetime(Func):
5028    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5031class CurrentTime(Func):
5032    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5035class CurrentTimestamp(Func):
5036    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5039class CurrentUser(Func):
5040    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5043class DateAdd(Func, IntervalOp):
5044    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5047class DateSub(Func, IntervalOp):
5048    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5051class DateDiff(Func, TimeUnit):
5052    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5053    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5056class DateTrunc(Func):
5057    arg_types = {"unit": True, "this": True, "zone": False}
5058
5059    def __init__(self, **args):
5060        unit = args.get("unit")
5061        if isinstance(unit, TimeUnit.VAR_LIKE):
5062            args["unit"] = Literal.string(
5063                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5064            )
5065        elif isinstance(unit, Week):
5066            unit.set("this", Literal.string(unit.this.name.upper()))
5067
5068        super().__init__(**args)
5069
5070    @property
5071    def unit(self) -> Expression:
5072        return self.args["unit"]
DateTrunc(**args)
5059    def __init__(self, **args):
5060        unit = args.get("unit")
5061        if isinstance(unit, TimeUnit.VAR_LIKE):
5062            args["unit"] = Literal.string(
5063                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5064            )
5065        elif isinstance(unit, Week):
5066            unit.set("this", Literal.string(unit.this.name.upper()))
5067
5068        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5070    @property
5071    def unit(self) -> Expression:
5072        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
5075class DatetimeAdd(Func, IntervalOp):
5076    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5079class DatetimeSub(Func, IntervalOp):
5080    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5083class DatetimeDiff(Func, TimeUnit):
5084    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5087class DatetimeTrunc(Func, TimeUnit):
5088    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5091class DayOfWeek(Func):
5092    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5095class DayOfMonth(Func):
5096    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5099class DayOfYear(Func):
5100    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5103class ToDays(Func):
5104    pass
key = 'todays'
class WeekOfYear(Func):
5107class WeekOfYear(Func):
5108    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5111class MonthsBetween(Func):
5112    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5115class LastDay(Func, TimeUnit):
5116    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5117    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5120class Extract(Func):
5121    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5124class Timestamp(Func):
5125    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5128class TimestampAdd(Func, TimeUnit):
5129    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5132class TimestampSub(Func, TimeUnit):
5133    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5136class TimestampDiff(Func, TimeUnit):
5137    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5138    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5141class TimestampTrunc(Func, TimeUnit):
5142    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5145class TimeAdd(Func, TimeUnit):
5146    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5149class TimeSub(Func, TimeUnit):
5150    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5153class TimeDiff(Func, TimeUnit):
5154    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5157class TimeTrunc(Func, TimeUnit):
5158    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5161class DateFromParts(Func):
5162    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5163    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5166class TimeFromParts(Func):
5167    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5168    arg_types = {
5169        "hour": True,
5170        "min": True,
5171        "sec": True,
5172        "nano": False,
5173        "fractions": False,
5174        "precision": False,
5175    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5178class DateStrToDate(Func):
5179    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5182class DateToDateStr(Func):
5183    pass
key = 'datetodatestr'
class DateToDi(Func):
5186class DateToDi(Func):
5187    pass
key = 'datetodi'
class Date(Func):
5191class Date(Func):
5192    arg_types = {"this": False, "zone": False, "expressions": False}
5193    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5196class Day(Func):
5197    pass
key = 'day'
class Decode(Func):
5200class Decode(Func):
5201    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5204class DiToDate(Func):
5205    pass
key = 'ditodate'
class Encode(Func):
5208class Encode(Func):
5209    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5212class Exp(Func):
5213    pass
key = 'exp'
class Explode(Func):
5217class Explode(Func):
5218    arg_types = {"this": True, "expressions": False}
5219    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5222class ExplodeOuter(Explode):
5223    pass
key = 'explodeouter'
class Posexplode(Explode):
5226class Posexplode(Explode):
5227    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5230class PosexplodeOuter(Posexplode, ExplodeOuter):
5231    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5234class Unnest(Func, UDTF):
5235    arg_types = {
5236        "expressions": True,
5237        "alias": False,
5238        "offset": False,
5239    }
5240
5241    @property
5242    def selects(self) -> t.List[Expression]:
5243        columns = super().selects
5244        offset = self.args.get("offset")
5245        if offset:
5246            columns = columns + [to_identifier("offset") if offset is True else offset]
5247        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5241    @property
5242    def selects(self) -> t.List[Expression]:
5243        columns = super().selects
5244        offset = self.args.get("offset")
5245        if offset:
5246            columns = columns + [to_identifier("offset") if offset is True else offset]
5247        return columns
key = 'unnest'
class Floor(Func):
5250class Floor(Func):
5251    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5254class FromBase64(Func):
5255    pass
key = 'frombase64'
class ToBase64(Func):
5258class ToBase64(Func):
5259    pass
key = 'tobase64'
class GapFill(Func):
5262class GapFill(Func):
5263    arg_types = {
5264        "this": True,
5265        "ts_column": True,
5266        "bucket_width": True,
5267        "partitioning_columns": False,
5268        "value_columns": False,
5269        "origin": False,
5270        "ignore_nulls": False,
5271    }
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):
5274class GenerateDateArray(Func):
5275    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5278class Greatest(Func):
5279    arg_types = {"this": True, "expressions": False}
5280    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5283class GroupConcat(AggFunc):
5284    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5287class Hex(Func):
5288    pass
key = 'hex'
class LowerHex(Hex):
5291class LowerHex(Hex):
5292    pass
key = 'lowerhex'
class Xor(Connector, Func):
5295class Xor(Connector, Func):
5296    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5299class If(Func):
5300    arg_types = {"this": True, "true": True, "false": False}
5301    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5304class Nullif(Func):
5305    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5308class Initcap(Func):
5309    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5312class IsNan(Func):
5313    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5316class IsInf(Func):
5317    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5320class JSONPath(Expression):
5321    arg_types = {"expressions": True}
5322
5323    @property
5324    def output_name(self) -> str:
5325        last_segment = self.expressions[-1].this
5326        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5323    @property
5324    def output_name(self) -> str:
5325        last_segment = self.expressions[-1].this
5326        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):
5329class JSONPathPart(Expression):
5330    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5333class JSONPathFilter(JSONPathPart):
5334    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5337class JSONPathKey(JSONPathPart):
5338    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5341class JSONPathRecursive(JSONPathPart):
5342    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5345class JSONPathRoot(JSONPathPart):
5346    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5349class JSONPathScript(JSONPathPart):
5350    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5353class JSONPathSlice(JSONPathPart):
5354    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5357class JSONPathSelector(JSONPathPart):
5358    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5361class JSONPathSubscript(JSONPathPart):
5362    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5365class JSONPathUnion(JSONPathPart):
5366    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5369class JSONPathWildcard(JSONPathPart):
5370    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5373class FormatJson(Expression):
5374    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5377class JSONKeyValue(Expression):
5378    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5381class JSONObject(Func):
5382    arg_types = {
5383        "expressions": False,
5384        "null_handling": False,
5385        "unique_keys": False,
5386        "return_type": False,
5387        "encoding": False,
5388    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5391class JSONObjectAgg(AggFunc):
5392    arg_types = {
5393        "expressions": False,
5394        "null_handling": False,
5395        "unique_keys": False,
5396        "return_type": False,
5397        "encoding": False,
5398    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5402class JSONArray(Func):
5403    arg_types = {
5404        "expressions": True,
5405        "null_handling": False,
5406        "return_type": False,
5407        "strict": False,
5408    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5412class JSONArrayAgg(Func):
5413    arg_types = {
5414        "this": True,
5415        "order": False,
5416        "null_handling": False,
5417        "return_type": False,
5418        "strict": False,
5419    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5424class JSONColumnDef(Expression):
5425    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):
5428class JSONSchema(Expression):
5429    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5433class JSONTable(Func):
5434    arg_types = {
5435        "this": True,
5436        "schema": True,
5437        "path": False,
5438        "error_handling": False,
5439        "empty_handling": False,
5440    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5443class OpenJSONColumnDef(Expression):
5444    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):
5447class OpenJSON(Func):
5448    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5451class JSONBContains(Binary):
5452    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5455class JSONExtract(Binary, Func):
5456    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5457    _sql_names = ["JSON_EXTRACT"]
5458    is_var_len_args = True
5459
5460    @property
5461    def output_name(self) -> str:
5462        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
5460    @property
5461    def output_name(self) -> str:
5462        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):
5465class JSONExtractScalar(Binary, Func):
5466    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5467    _sql_names = ["JSON_EXTRACT_SCALAR"]
5468    is_var_len_args = True
5469
5470    @property
5471    def output_name(self) -> str:
5472        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
5470    @property
5471    def output_name(self) -> str:
5472        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):
5475class JSONBExtract(Binary, Func):
5476    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5479class JSONBExtractScalar(Binary, Func):
5480    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5483class JSONFormat(Func):
5484    arg_types = {"this": False, "options": False}
5485    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5489class JSONArrayContains(Binary, Predicate, Func):
5490    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5493class ParseJSON(Func):
5494    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5495    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5496    arg_types = {"this": True, "expressions": False}
5497    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5500class Least(Func):
5501    arg_types = {"this": True, "expressions": False}
5502    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5505class Left(Func):
5506    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5513class Length(Func):
5514    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5517class Levenshtein(Func):
5518    arg_types = {
5519        "this": True,
5520        "expression": False,
5521        "ins_cost": False,
5522        "del_cost": False,
5523        "sub_cost": False,
5524    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5527class Ln(Func):
5528    pass
key = 'ln'
class Log(Func):
5531class Log(Func):
5532    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5535class LogicalOr(AggFunc):
5536    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5539class LogicalAnd(AggFunc):
5540    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5543class Lower(Func):
5544    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5547class Map(Func):
5548    arg_types = {"keys": False, "values": False}
5549
5550    @property
5551    def keys(self) -> t.List[Expression]:
5552        keys = self.args.get("keys")
5553        return keys.expressions if keys else []
5554
5555    @property
5556    def values(self) -> t.List[Expression]:
5557        values = self.args.get("values")
5558        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5550    @property
5551    def keys(self) -> t.List[Expression]:
5552        keys = self.args.get("keys")
5553        return keys.expressions if keys else []
values: List[Expression]
5555    @property
5556    def values(self) -> t.List[Expression]:
5557        values = self.args.get("values")
5558        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5562class ToMap(Func):
5563    pass
key = 'tomap'
class MapFromEntries(Func):
5566class MapFromEntries(Func):
5567    pass
key = 'mapfromentries'
class StarMap(Func):
5570class StarMap(Func):
5571    pass
key = 'starmap'
class VarMap(Func):
5574class VarMap(Func):
5575    arg_types = {"keys": True, "values": True}
5576    is_var_len_args = True
5577
5578    @property
5579    def keys(self) -> t.List[Expression]:
5580        return self.args["keys"].expressions
5581
5582    @property
5583    def values(self) -> t.List[Expression]:
5584        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5578    @property
5579    def keys(self) -> t.List[Expression]:
5580        return self.args["keys"].expressions
values: List[Expression]
5582    @property
5583    def values(self) -> t.List[Expression]:
5584        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5588class MatchAgainst(Func):
5589    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5592class Max(AggFunc):
5593    arg_types = {"this": True, "expressions": False}
5594    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5597class MD5(Func):
5598    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5602class MD5Digest(Func):
5603    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5606class Min(AggFunc):
5607    arg_types = {"this": True, "expressions": False}
5608    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5611class Month(Func):
5612    pass
key = 'month'
class AddMonths(Func):
5615class AddMonths(Func):
5616    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5619class Nvl2(Func):
5620    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5624class Predict(Func):
5625    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5628class Pow(Binary, Func):
5629    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5632class PercentileCont(AggFunc):
5633    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5636class PercentileDisc(AggFunc):
5637    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5640class Quantile(AggFunc):
5641    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5644class ApproxQuantile(Quantile):
5645    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):
5648class Quarter(Func):
5649    pass
key = 'quarter'
class Rand(Func):
5652class Rand(Func):
5653    _sql_names = ["RAND", "RANDOM"]
5654    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5657class Randn(Func):
5658    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5661class RangeN(Func):
5662    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5665class ReadCSV(Func):
5666    _sql_names = ["READ_CSV"]
5667    is_var_len_args = True
5668    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5671class Reduce(Func):
5672    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):
5675class RegexpExtract(Func):
5676    arg_types = {
5677        "this": True,
5678        "expression": True,
5679        "position": False,
5680        "occurrence": False,
5681        "parameters": False,
5682        "group": False,
5683    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5686class RegexpReplace(Func):
5687    arg_types = {
5688        "this": True,
5689        "expression": True,
5690        "replacement": False,
5691        "position": False,
5692        "occurrence": False,
5693        "modifiers": False,
5694    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5697class RegexpLike(Binary, Func):
5698    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5701class RegexpILike(Binary, Func):
5702    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5707class RegexpSplit(Func):
5708    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5711class Repeat(Func):
5712    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5717class Round(Func):
5718    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5721class RowNumber(Func):
5722    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5725class SafeDivide(Func):
5726    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5729class SHA(Func):
5730    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5733class SHA2(Func):
5734    _sql_names = ["SHA2"]
5735    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5738class Sign(Func):
5739    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5742class SortArray(Func):
5743    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5746class Split(Func):
5747    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5752class Substring(Func):
5753    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5756class StandardHash(Func):
5757    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5760class StartsWith(Func):
5761    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5762    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5765class StrPosition(Func):
5766    arg_types = {
5767        "this": True,
5768        "substr": True,
5769        "position": False,
5770        "instance": False,
5771    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5774class StrToDate(Func):
5775    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'strtodate'
class StrToTime(Func):
5778class StrToTime(Func):
5779    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5784class StrToUnix(Func):
5785    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5790class StrToMap(Func):
5791    arg_types = {
5792        "this": True,
5793        "pair_delim": False,
5794        "key_value_delim": False,
5795        "duplicate_resolution_callback": False,
5796    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5799class NumberToStr(Func):
5800    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5803class FromBase(Func):
5804    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5807class Struct(Func):
5808    arg_types = {"expressions": False}
5809    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5812class StructExtract(Func):
5813    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5818class Stuff(Func):
5819    _sql_names = ["STUFF", "INSERT"]
5820    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):
5823class Sum(AggFunc):
5824    pass
key = 'sum'
class Sqrt(Func):
5827class Sqrt(Func):
5828    pass
key = 'sqrt'
class Stddev(AggFunc):
5831class Stddev(AggFunc):
5832    pass
key = 'stddev'
class StddevPop(AggFunc):
5835class StddevPop(AggFunc):
5836    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5839class StddevSamp(AggFunc):
5840    pass
key = 'stddevsamp'
class TimeToStr(Func):
5843class TimeToStr(Func):
5844    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):
5847class TimeToTimeStr(Func):
5848    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5851class TimeToUnix(Func):
5852    pass
key = 'timetounix'
class TimeStrToDate(Func):
5855class TimeStrToDate(Func):
5856    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5859class TimeStrToTime(Func):
5860    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5863class TimeStrToUnix(Func):
5864    pass
key = 'timestrtounix'
class Trim(Func):
5867class Trim(Func):
5868    arg_types = {
5869        "this": True,
5870        "expression": False,
5871        "position": False,
5872        "collation": False,
5873    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5876class TsOrDsAdd(Func, TimeUnit):
5877    # return_type is used to correctly cast the arguments of this expression when transpiling it
5878    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5879
5880    @property
5881    def return_type(self) -> DataType:
5882        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
5880    @property
5881    def return_type(self) -> DataType:
5882        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5885class TsOrDsDiff(Func, TimeUnit):
5886    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5889class TsOrDsToDateStr(Func):
5890    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5893class TsOrDsToDate(Func):
5894    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5897class TsOrDsToTime(Func):
5898    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5901class TsOrDsToTimestamp(Func):
5902    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5905class TsOrDiToDi(Func):
5906    pass
key = 'tsorditodi'
class Unhex(Func):
5909class Unhex(Func):
5910    pass
key = 'unhex'
class UnixDate(Func):
5914class UnixDate(Func):
5915    pass
key = 'unixdate'
class UnixToStr(Func):
5918class UnixToStr(Func):
5919    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5924class UnixToTime(Func):
5925    arg_types = {
5926        "this": True,
5927        "scale": False,
5928        "zone": False,
5929        "hours": False,
5930        "minutes": False,
5931        "format": False,
5932    }
5933
5934    SECONDS = Literal.number(0)
5935    DECIS = Literal.number(1)
5936    CENTIS = Literal.number(2)
5937    MILLIS = Literal.number(3)
5938    DECIMILLIS = Literal.number(4)
5939    CENTIMILLIS = Literal.number(5)
5940    MICROS = Literal.number(6)
5941    DECIMICROS = Literal.number(7)
5942    CENTIMICROS = Literal.number(8)
5943    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):
5946class UnixToTimeStr(Func):
5947    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5950class TimestampFromParts(Func):
5951    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5952    arg_types = {
5953        "year": True,
5954        "month": True,
5955        "day": True,
5956        "hour": True,
5957        "min": True,
5958        "sec": True,
5959        "nano": False,
5960        "zone": False,
5961        "milli": False,
5962    }
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):
5965class Upper(Func):
5966    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5969class Corr(Binary, AggFunc):
5970    pass
key = 'corr'
class Variance(AggFunc):
5973class Variance(AggFunc):
5974    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5977class VariancePop(AggFunc):
5978    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
5981class CovarSamp(Binary, AggFunc):
5982    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
5985class CovarPop(Binary, AggFunc):
5986    pass
key = 'covarpop'
class Week(Func):
5989class Week(Func):
5990    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5993class XMLTable(Func):
5994    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):
5997class Year(Func):
5998    pass
key = 'year'
class Use(Expression):
6001class Use(Expression):
6002    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6005class Merge(Expression):
6006    arg_types = {
6007        "this": True,
6008        "using": True,
6009        "on": True,
6010        "expressions": True,
6011        "with": False,
6012    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6015class When(Func):
6016    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):
6021class NextValueFor(Func):
6022    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6027class Semicolon(Expression):
6028    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME_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:
6068def maybe_parse(
6069    sql_or_expression: ExpOrStr,
6070    *,
6071    into: t.Optional[IntoType] = None,
6072    dialect: DialectType = None,
6073    prefix: t.Optional[str] = None,
6074    copy: bool = False,
6075    **opts,
6076) -> Expression:
6077    """Gracefully handle a possible string or expression.
6078
6079    Example:
6080        >>> maybe_parse("1")
6081        Literal(this=1, is_string=False)
6082        >>> maybe_parse(to_identifier("x"))
6083        Identifier(this=x, quoted=False)
6084
6085    Args:
6086        sql_or_expression: the SQL code string or an expression
6087        into: the SQLGlot Expression to parse into
6088        dialect: the dialect used to parse the input expressions (in the case that an
6089            input expression is a SQL string).
6090        prefix: a string to prefix the sql with before it gets parsed
6091            (automatically includes a space)
6092        copy: whether to copy the expression.
6093        **opts: other options to use to parse the input expressions (again, in the case
6094            that an input expression is a SQL string).
6095
6096    Returns:
6097        Expression: the parsed or given expression.
6098    """
6099    if isinstance(sql_or_expression, Expression):
6100        if copy:
6101            return sql_or_expression.copy()
6102        return sql_or_expression
6103
6104    if sql_or_expression is None:
6105        raise ParseError("SQL cannot be None")
6106
6107    import sqlglot
6108
6109    sql = str(sql_or_expression)
6110    if prefix:
6111        sql = f"{prefix} {sql}"
6112
6113    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):
6124def maybe_copy(instance, copy=True):
6125    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:
6345def union(
6346    left: ExpOrStr,
6347    right: ExpOrStr,
6348    distinct: bool = True,
6349    dialect: DialectType = None,
6350    copy: bool = True,
6351    **opts,
6352) -> Union:
6353    """
6354    Initializes a syntax tree from one UNION expression.
6355
6356    Example:
6357        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6358        'SELECT * FROM foo UNION SELECT * FROM bla'
6359
6360    Args:
6361        left: the SQL code string corresponding to the left-hand side.
6362            If an `Expression` instance is passed, it will be used as-is.
6363        right: the SQL code string corresponding to the right-hand side.
6364            If an `Expression` instance is passed, it will be used as-is.
6365        distinct: set the DISTINCT flag if and only if this is true.
6366        dialect: the dialect used to parse the input expression.
6367        copy: whether to copy the expression.
6368        opts: other options to use to parse the input expressions.
6369
6370    Returns:
6371        The new Union instance.
6372    """
6373    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6374    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6375
6376    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:
6379def intersect(
6380    left: ExpOrStr,
6381    right: ExpOrStr,
6382    distinct: bool = True,
6383    dialect: DialectType = None,
6384    copy: bool = True,
6385    **opts,
6386) -> Intersect:
6387    """
6388    Initializes a syntax tree from one INTERSECT expression.
6389
6390    Example:
6391        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6392        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6393
6394    Args:
6395        left: the SQL code string corresponding to the left-hand side.
6396            If an `Expression` instance is passed, it will be used as-is.
6397        right: the SQL code string corresponding to the right-hand side.
6398            If an `Expression` instance is passed, it will be used as-is.
6399        distinct: set the DISTINCT flag if and only if this is true.
6400        dialect: the dialect used to parse the input expression.
6401        copy: whether to copy the expression.
6402        opts: other options to use to parse the input expressions.
6403
6404    Returns:
6405        The new Intersect instance.
6406    """
6407    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6408    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6409
6410    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:
6413def except_(
6414    left: ExpOrStr,
6415    right: ExpOrStr,
6416    distinct: bool = True,
6417    dialect: DialectType = None,
6418    copy: bool = True,
6419    **opts,
6420) -> Except:
6421    """
6422    Initializes a syntax tree from one EXCEPT expression.
6423
6424    Example:
6425        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6426        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6427
6428    Args:
6429        left: the SQL code string corresponding to the left-hand side.
6430            If an `Expression` instance is passed, it will be used as-is.
6431        right: the SQL code string corresponding to the right-hand side.
6432            If an `Expression` instance is passed, it will be used as-is.
6433        distinct: set the DISTINCT flag if and only if this is true.
6434        dialect: the dialect used to parse the input expression.
6435        copy: whether to copy the expression.
6436        opts: other options to use to parse the input expressions.
6437
6438    Returns:
6439        The new Except instance.
6440    """
6441    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6442    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6443
6444    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:
6447def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6448    """
6449    Initializes a syntax tree from one or multiple SELECT expressions.
6450
6451    Example:
6452        >>> select("col1", "col2").from_("tbl").sql()
6453        'SELECT col1, col2 FROM tbl'
6454
6455    Args:
6456        *expressions: the SQL code string to parse as the expressions of a
6457            SELECT statement. If an Expression instance is passed, this is used as-is.
6458        dialect: the dialect used to parse the input expressions (in the case that an
6459            input expression is a SQL string).
6460        **opts: other options to use to parse the input expressions (again, in the case
6461            that an input expression is a SQL string).
6462
6463    Returns:
6464        Select: the syntax tree for the SELECT statement.
6465    """
6466    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:
6469def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6470    """
6471    Initializes a syntax tree from a FROM expression.
6472
6473    Example:
6474        >>> from_("tbl").select("col1", "col2").sql()
6475        'SELECT col1, col2 FROM tbl'
6476
6477    Args:
6478        *expression: the SQL code string to parse as the FROM expressions of a
6479            SELECT statement. If an Expression instance is passed, this is used as-is.
6480        dialect: the dialect used to parse the input expression (in the case that the
6481            input expression is a SQL string).
6482        **opts: other options to use to parse the input expressions (again, in the case
6483            that the input expression is a SQL string).
6484
6485    Returns:
6486        Select: the syntax tree for the SELECT statement.
6487    """
6488    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:
6491def update(
6492    table: str | Table,
6493    properties: dict,
6494    where: t.Optional[ExpOrStr] = None,
6495    from_: t.Optional[ExpOrStr] = None,
6496    dialect: DialectType = None,
6497    **opts,
6498) -> Update:
6499    """
6500    Creates an update statement.
6501
6502    Example:
6503        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6504        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6505
6506    Args:
6507        *properties: dictionary of properties to set which are
6508            auto converted to sql objects eg None -> NULL
6509        where: sql conditional parsed into a WHERE statement
6510        from_: sql statement parsed into a FROM statement
6511        dialect: the dialect used to parse the input expressions.
6512        **opts: other options to use to parse the input expressions.
6513
6514    Returns:
6515        Update: the syntax tree for the UPDATE statement.
6516    """
6517    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6518    update_expr.set(
6519        "expressions",
6520        [
6521            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6522            for k, v in properties.items()
6523        ],
6524    )
6525    if from_:
6526        update_expr.set(
6527            "from",
6528            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6529        )
6530    if isinstance(where, Condition):
6531        where = Where(this=where)
6532    if where:
6533        update_expr.set(
6534            "where",
6535            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6536        )
6537    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:
6540def delete(
6541    table: ExpOrStr,
6542    where: t.Optional[ExpOrStr] = None,
6543    returning: t.Optional[ExpOrStr] = None,
6544    dialect: DialectType = None,
6545    **opts,
6546) -> Delete:
6547    """
6548    Builds a delete statement.
6549
6550    Example:
6551        >>> delete("my_table", where="id > 1").sql()
6552        'DELETE FROM my_table WHERE id > 1'
6553
6554    Args:
6555        where: sql conditional parsed into a WHERE statement
6556        returning: sql conditional parsed into a RETURNING statement
6557        dialect: the dialect used to parse the input expressions.
6558        **opts: other options to use to parse the input expressions.
6559
6560    Returns:
6561        Delete: the syntax tree for the DELETE statement.
6562    """
6563    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6564    if where:
6565        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6566    if returning:
6567        delete_expr = t.cast(
6568            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6569        )
6570    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:
6573def insert(
6574    expression: ExpOrStr,
6575    into: ExpOrStr,
6576    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6577    overwrite: t.Optional[bool] = None,
6578    returning: t.Optional[ExpOrStr] = None,
6579    dialect: DialectType = None,
6580    copy: bool = True,
6581    **opts,
6582) -> Insert:
6583    """
6584    Builds an INSERT statement.
6585
6586    Example:
6587        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6588        'INSERT INTO tbl VALUES (1, 2, 3)'
6589
6590    Args:
6591        expression: the sql string or expression of the INSERT statement
6592        into: the tbl to insert data to.
6593        columns: optionally the table's column names.
6594        overwrite: whether to INSERT OVERWRITE or not.
6595        returning: sql conditional parsed into a RETURNING statement
6596        dialect: the dialect used to parse the input expressions.
6597        copy: whether to copy the expression.
6598        **opts: other options to use to parse the input expressions.
6599
6600    Returns:
6601        Insert: the syntax tree for the INSERT statement.
6602    """
6603    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6604    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6605
6606    if columns:
6607        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6608
6609    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6610
6611    if returning:
6612        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6613
6614    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:
6617def condition(
6618    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6619) -> Condition:
6620    """
6621    Initialize a logical condition expression.
6622
6623    Example:
6624        >>> condition("x=1").sql()
6625        'x = 1'
6626
6627        This is helpful for composing larger logical syntax trees:
6628        >>> where = condition("x=1")
6629        >>> where = where.and_("y=1")
6630        >>> Select().from_("tbl").select("*").where(where).sql()
6631        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6632
6633    Args:
6634        *expression: the SQL code string to parse.
6635            If an Expression instance is passed, this is used as-is.
6636        dialect: the dialect used to parse the input expression (in the case that the
6637            input expression is a SQL string).
6638        copy: Whether to copy `expression` (only applies to expressions).
6639        **opts: other options to use to parse the input expressions (again, in the case
6640            that the input expression is a SQL string).
6641
6642    Returns:
6643        The new Condition instance
6644    """
6645    return maybe_parse(
6646        expression,
6647        into=Condition,
6648        dialect=dialect,
6649        copy=copy,
6650        **opts,
6651    )

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:
6654def and_(
6655    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6656) -> Condition:
6657    """
6658    Combine multiple conditions with an AND logical operator.
6659
6660    Example:
6661        >>> and_("x=1", and_("y=1", "z=1")).sql()
6662        'x = 1 AND (y = 1 AND z = 1)'
6663
6664    Args:
6665        *expressions: the SQL code strings to parse.
6666            If an Expression instance is passed, this is used as-is.
6667        dialect: the dialect used to parse the input expression.
6668        copy: whether to copy `expressions` (only applies to Expressions).
6669        **opts: other options to use to parse the input expressions.
6670
6671    Returns:
6672        The new condition
6673    """
6674    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:
6677def or_(
6678    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6679) -> Condition:
6680    """
6681    Combine multiple conditions with an OR logical operator.
6682
6683    Example:
6684        >>> or_("x=1", or_("y=1", "z=1")).sql()
6685        'x = 1 OR (y = 1 OR z = 1)'
6686
6687    Args:
6688        *expressions: the SQL code strings to parse.
6689            If an Expression instance is passed, this is used as-is.
6690        dialect: the dialect used to parse the input expression.
6691        copy: whether to copy `expressions` (only applies to Expressions).
6692        **opts: other options to use to parse the input expressions.
6693
6694    Returns:
6695        The new condition
6696    """
6697    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:
6700def xor(
6701    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6702) -> Condition:
6703    """
6704    Combine multiple conditions with an XOR logical operator.
6705
6706    Example:
6707        >>> xor("x=1", xor("y=1", "z=1")).sql()
6708        'x = 1 XOR (y = 1 XOR z = 1)'
6709
6710    Args:
6711        *expressions: the SQL code strings to parse.
6712            If an Expression instance is passed, this is used as-is.
6713        dialect: the dialect used to parse the input expression.
6714        copy: whether to copy `expressions` (only applies to Expressions).
6715        **opts: other options to use to parse the input expressions.
6716
6717    Returns:
6718        The new condition
6719    """
6720    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:
6723def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6724    """
6725    Wrap a condition with a NOT operator.
6726
6727    Example:
6728        >>> not_("this_suit='black'").sql()
6729        "NOT this_suit = 'black'"
6730
6731    Args:
6732        expression: the SQL code string to parse.
6733            If an Expression instance is passed, this is used as-is.
6734        dialect: the dialect used to parse the input expression.
6735        copy: whether to copy the expression or not.
6736        **opts: other options to use to parse the input expressions.
6737
6738    Returns:
6739        The new condition.
6740    """
6741    this = condition(
6742        expression,
6743        dialect=dialect,
6744        copy=copy,
6745        **opts,
6746    )
6747    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:
6750def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6751    """
6752    Wrap an expression in parentheses.
6753
6754    Example:
6755        >>> paren("5 + 3").sql()
6756        '(5 + 3)'
6757
6758    Args:
6759        expression: the SQL code string to parse.
6760            If an Expression instance is passed, this is used as-is.
6761        copy: whether to copy the expression or not.
6762
6763    Returns:
6764        The wrapped expression.
6765    """
6766    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):
6782def to_identifier(name, quoted=None, copy=True):
6783    """Builds an identifier.
6784
6785    Args:
6786        name: The name to turn into an identifier.
6787        quoted: Whether to force quote the identifier.
6788        copy: Whether to copy name if it's an Identifier.
6789
6790    Returns:
6791        The identifier ast node.
6792    """
6793
6794    if name is None:
6795        return None
6796
6797    if isinstance(name, Identifier):
6798        identifier = maybe_copy(name, copy)
6799    elif isinstance(name, str):
6800        identifier = Identifier(
6801            this=name,
6802            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6803        )
6804    else:
6805        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6806    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:
6809def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6810    """
6811    Parses a given string into an identifier.
6812
6813    Args:
6814        name: The name to parse into an identifier.
6815        dialect: The dialect to parse against.
6816
6817    Returns:
6818        The identifier ast node.
6819    """
6820    try:
6821        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6822    except ParseError:
6823        expression = to_identifier(name)
6824
6825    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:
6831def to_interval(interval: str | Literal) -> Interval:
6832    """Builds an interval expression from a string like '1 day' or '5 months'."""
6833    if isinstance(interval, Literal):
6834        if not interval.is_string:
6835            raise ValueError("Invalid interval string.")
6836
6837        interval = interval.this
6838
6839    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6840
6841    if not interval_parts:
6842        raise ValueError("Invalid interval string.")
6843
6844    return Interval(
6845        this=Literal.string(interval_parts.group(1)),
6846        unit=Var(this=interval_parts.group(2).upper()),
6847    )

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:
6850def to_table(
6851    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6852) -> Table:
6853    """
6854    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6855    If a table is passed in then that table is returned.
6856
6857    Args:
6858        sql_path: a `[catalog].[schema].[table]` string.
6859        dialect: the source dialect according to which the table name will be parsed.
6860        copy: Whether to copy a table if it is passed in.
6861        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6862
6863    Returns:
6864        A table expression.
6865    """
6866    if isinstance(sql_path, Table):
6867        return maybe_copy(sql_path, copy=copy)
6868
6869    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6870
6871    for k, v in kwargs.items():
6872        table.set(k, v)
6873
6874    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:
6877def to_column(
6878    sql_path: str | Column,
6879    quoted: t.Optional[bool] = None,
6880    dialect: DialectType = None,
6881    copy: bool = True,
6882    **kwargs,
6883) -> Column:
6884    """
6885    Create a column from a `[table].[column]` sql path. Table is optional.
6886    If a column is passed in then that column is returned.
6887
6888    Args:
6889        sql_path: a `[table].[column]` string.
6890        quoted: Whether or not to force quote identifiers.
6891        dialect: the source dialect according to which the column name will be parsed.
6892        copy: Whether to copy a column if it is passed in.
6893        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6894
6895    Returns:
6896        A column expression.
6897    """
6898    if isinstance(sql_path, Column):
6899        return maybe_copy(sql_path, copy=copy)
6900
6901    try:
6902        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6903    except ParseError:
6904        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6905
6906    for k, v in kwargs.items():
6907        col.set(k, v)
6908
6909    if quoted:
6910        for i in col.find_all(Identifier):
6911            i.set("quoted", True)
6912
6913    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):
6916def alias_(
6917    expression: ExpOrStr,
6918    alias: t.Optional[str | Identifier],
6919    table: bool | t.Sequence[str | Identifier] = False,
6920    quoted: t.Optional[bool] = None,
6921    dialect: DialectType = None,
6922    copy: bool = True,
6923    **opts,
6924):
6925    """Create an Alias expression.
6926
6927    Example:
6928        >>> alias_('foo', 'bar').sql()
6929        'foo AS bar'
6930
6931        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6932        '(SELECT 1, 2) AS bar(a, b)'
6933
6934    Args:
6935        expression: the SQL code strings to parse.
6936            If an Expression instance is passed, this is used as-is.
6937        alias: the alias name to use. If the name has
6938            special characters it is quoted.
6939        table: Whether to create a table alias, can also be a list of columns.
6940        quoted: whether to quote the alias
6941        dialect: the dialect used to parse the input expression.
6942        copy: Whether to copy the expression.
6943        **opts: other options to use to parse the input expressions.
6944
6945    Returns:
6946        Alias: the aliased expression
6947    """
6948    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6949    alias = to_identifier(alias, quoted=quoted)
6950
6951    if table:
6952        table_alias = TableAlias(this=alias)
6953        exp.set("alias", table_alias)
6954
6955        if not isinstance(table, bool):
6956            for column in table:
6957                table_alias.append("columns", to_identifier(column, quoted=quoted))
6958
6959        return exp
6960
6961    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6962    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6963    # for the complete Window expression.
6964    #
6965    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6966
6967    if "alias" in exp.arg_types and not isinstance(exp, Window):
6968        exp.set("alias", alias)
6969        return exp
6970    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:
6973def subquery(
6974    expression: ExpOrStr,
6975    alias: t.Optional[Identifier | str] = None,
6976    dialect: DialectType = None,
6977    **opts,
6978) -> Select:
6979    """
6980    Build a subquery expression that's selected from.
6981
6982    Example:
6983        >>> subquery('select x from tbl', 'bar').select('x').sql()
6984        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6985
6986    Args:
6987        expression: the SQL code strings to parse.
6988            If an Expression instance is passed, this is used as-is.
6989        alias: the alias name to use.
6990        dialect: the dialect used to parse the input expression.
6991        **opts: other options to use to parse the input expressions.
6992
6993    Returns:
6994        A new Select instance with the subquery expression included.
6995    """
6996
6997    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
6998    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):
7029def column(
7030    col,
7031    table=None,
7032    db=None,
7033    catalog=None,
7034    *,
7035    fields=None,
7036    quoted=None,
7037    copy=True,
7038):
7039    """
7040    Build a Column.
7041
7042    Args:
7043        col: Column name.
7044        table: Table name.
7045        db: Database name.
7046        catalog: Catalog name.
7047        fields: Additional fields using dots.
7048        quoted: Whether to force quotes on the column's identifiers.
7049        copy: Whether to copy identifiers if passed in.
7050
7051    Returns:
7052        The new Column instance.
7053    """
7054    this = Column(
7055        this=to_identifier(col, quoted=quoted, copy=copy),
7056        table=to_identifier(table, quoted=quoted, copy=copy),
7057        db=to_identifier(db, quoted=quoted, copy=copy),
7058        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7059    )
7060
7061    if fields:
7062        this = Dot.build(
7063            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7064        )
7065    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:
7068def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7069    """Cast an expression to a data type.
7070
7071    Example:
7072        >>> cast('x + 1', 'int').sql()
7073        'CAST(x + 1 AS INT)'
7074
7075    Args:
7076        expression: The expression to cast.
7077        to: The datatype to cast to.
7078        copy: Whether to copy the supplied expressions.
7079
7080    Returns:
7081        The new Cast instance.
7082    """
7083    expr = maybe_parse(expression, copy=copy, **opts)
7084    data_type = DataType.build(to, copy=copy, **opts)
7085
7086    if expr.is_type(data_type):
7087        return expr
7088
7089    expr = Cast(this=expr, to=data_type)
7090    expr.type = data_type
7091
7092    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:
7095def table_(
7096    table: Identifier | str,
7097    db: t.Optional[Identifier | str] = None,
7098    catalog: t.Optional[Identifier | str] = None,
7099    quoted: t.Optional[bool] = None,
7100    alias: t.Optional[Identifier | str] = None,
7101) -> Table:
7102    """Build a Table.
7103
7104    Args:
7105        table: Table name.
7106        db: Database name.
7107        catalog: Catalog name.
7108        quote: Whether to force quotes on the table's identifiers.
7109        alias: Table's alias.
7110
7111    Returns:
7112        The new Table instance.
7113    """
7114    return Table(
7115        this=to_identifier(table, quoted=quoted) if table else None,
7116        db=to_identifier(db, quoted=quoted) if db else None,
7117        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7118        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7119    )

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:
7122def values(
7123    values: t.Iterable[t.Tuple[t.Any, ...]],
7124    alias: t.Optional[str] = None,
7125    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7126) -> Values:
7127    """Build VALUES statement.
7128
7129    Example:
7130        >>> values([(1, '2')]).sql()
7131        "VALUES (1, '2')"
7132
7133    Args:
7134        values: values statements that will be converted to SQL
7135        alias: optional alias
7136        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7137         If either are provided then an alias is also required.
7138
7139    Returns:
7140        Values: the Values expression object
7141    """
7142    if columns and not alias:
7143        raise ValueError("Alias is required when providing columns")
7144
7145    return Values(
7146        expressions=[convert(tup) for tup in values],
7147        alias=(
7148            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7149            if columns
7150            else (TableAlias(this=to_identifier(alias)) if alias else None)
7151        ),
7152    )

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:
7155def var(name: t.Optional[ExpOrStr]) -> Var:
7156    """Build a SQL variable.
7157
7158    Example:
7159        >>> repr(var('x'))
7160        'Var(this=x)'
7161
7162        >>> repr(var(column('x', table='y')))
7163        'Var(this=x)'
7164
7165    Args:
7166        name: The name of the var or an expression who's name will become the var.
7167
7168    Returns:
7169        The new variable node.
7170    """
7171    if not name:
7172        raise ValueError("Cannot convert empty name into var.")
7173
7174    if isinstance(name, Expression):
7175        name = name.name
7176    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:
7179def rename_table(
7180    old_name: str | Table,
7181    new_name: str | Table,
7182    dialect: DialectType = None,
7183) -> AlterTable:
7184    """Build ALTER TABLE... RENAME... expression
7185
7186    Args:
7187        old_name: The old name of the table
7188        new_name: The new name of the table
7189        dialect: The dialect to parse the table.
7190
7191    Returns:
7192        Alter table expression
7193    """
7194    old_table = to_table(old_name, dialect=dialect)
7195    new_table = to_table(new_name, dialect=dialect)
7196    return AlterTable(
7197        this=old_table,
7198        actions=[
7199            RenameTable(this=new_table),
7200        ],
7201    )

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:
7204def rename_column(
7205    table_name: str | Table,
7206    old_column_name: str | Column,
7207    new_column_name: str | Column,
7208    exists: t.Optional[bool] = None,
7209    dialect: DialectType = None,
7210) -> AlterTable:
7211    """Build ALTER TABLE... RENAME COLUMN... expression
7212
7213    Args:
7214        table_name: Name of the table
7215        old_column: The old name of the column
7216        new_column: The new name of the column
7217        exists: Whether to add the `IF EXISTS` clause
7218        dialect: The dialect to parse the table/column.
7219
7220    Returns:
7221        Alter table expression
7222    """
7223    table = to_table(table_name, dialect=dialect)
7224    old_column = to_column(old_column_name, dialect=dialect)
7225    new_column = to_column(new_column_name, dialect=dialect)
7226    return AlterTable(
7227        this=table,
7228        actions=[
7229            RenameColumn(this=old_column, to=new_column, exists=exists),
7230        ],
7231    )

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:
7234def convert(value: t.Any, copy: bool = False) -> Expression:
7235    """Convert a python value into an expression object.
7236
7237    Raises an error if a conversion is not possible.
7238
7239    Args:
7240        value: A python object.
7241        copy: Whether to copy `value` (only applies to Expressions and collections).
7242
7243    Returns:
7244        The equivalent expression object.
7245    """
7246    if isinstance(value, Expression):
7247        return maybe_copy(value, copy)
7248    if isinstance(value, str):
7249        return Literal.string(value)
7250    if isinstance(value, bool):
7251        return Boolean(this=value)
7252    if value is None or (isinstance(value, float) and math.isnan(value)):
7253        return null()
7254    if isinstance(value, numbers.Number):
7255        return Literal.number(value)
7256    if isinstance(value, bytes):
7257        return HexString(this=value.hex())
7258    if isinstance(value, datetime.datetime):
7259        datetime_literal = Literal.string(
7260            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7261                sep=" "
7262            )
7263        )
7264        return TimeStrToTime(this=datetime_literal)
7265    if isinstance(value, datetime.date):
7266        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7267        return DateStrToDate(this=date_literal)
7268    if isinstance(value, tuple):
7269        if hasattr(value, "_fields"):
7270            return Struct(
7271                expressions=[
7272                    PropertyEQ(
7273                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7274                    )
7275                    for k in value._fields
7276                ]
7277            )
7278        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7279    if isinstance(value, list):
7280        return Array(expressions=[convert(v, copy=copy) for v in value])
7281    if isinstance(value, dict):
7282        return Map(
7283            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7284            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7285        )
7286    if hasattr(value, "__dict__"):
7287        return Struct(
7288            expressions=[
7289                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7290                for k, v in value.__dict__.items()
7291            ]
7292        )
7293    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:
7296def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7297    """
7298    Replace children of an expression with the result of a lambda fun(child) -> exp.
7299    """
7300    for k, v in tuple(expression.args.items()):
7301        is_list_arg = type(v) is list
7302
7303        child_nodes = v if is_list_arg else [v]
7304        new_child_nodes = []
7305
7306        for cn in child_nodes:
7307            if isinstance(cn, Expression):
7308                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7309                    new_child_nodes.append(child_node)
7310            else:
7311                new_child_nodes.append(cn)
7312
7313        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:
7316def replace_tree(
7317    expression: Expression,
7318    fun: t.Callable,
7319    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7320) -> Expression:
7321    """
7322    Replace an entire tree with the result of function calls on each node.
7323
7324    This will be traversed in reverse dfs, so leaves first.
7325    If new nodes are created as a result of function calls, they will also be traversed.
7326    """
7327    stack = list(expression.dfs(prune=prune))
7328
7329    while stack:
7330        node = stack.pop()
7331        new_node = fun(node)
7332
7333        if new_node is not node:
7334            node.replace(new_node)
7335
7336            if isinstance(new_node, Expression):
7337                stack.append(new_node)
7338
7339    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]:
7342def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7343    """
7344    Return all table names referenced through columns in an expression.
7345
7346    Example:
7347        >>> import sqlglot
7348        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7349        ['a', 'c']
7350
7351    Args:
7352        expression: expression to find table names.
7353        exclude: a table name to exclude
7354
7355    Returns:
7356        A list of unique names.
7357    """
7358    return {
7359        table
7360        for table in (column.table for column in expression.find_all(Column))
7361        if table and table != exclude
7362    }

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:
7365def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7366    """Get the full name of a table as a string.
7367
7368    Args:
7369        table: Table expression node or string.
7370        dialect: The dialect to generate the table name for.
7371        identify: Determines when an identifier should be quoted. Possible values are:
7372            False (default): Never quote, except in cases where it's mandatory by the dialect.
7373            True: Always quote.
7374
7375    Examples:
7376        >>> from sqlglot import exp, parse_one
7377        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7378        'a.b.c'
7379
7380    Returns:
7381        The table name.
7382    """
7383
7384    table = maybe_parse(table, into=Table, dialect=dialect)
7385
7386    if not table:
7387        raise ValueError(f"Cannot parse {table}")
7388
7389    return ".".join(
7390        (
7391            part.sql(dialect=dialect, identify=True, copy=False)
7392            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7393            else part.name
7394        )
7395        for part in table.parts
7396    )

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:
7399def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7400    """Returns a case normalized table name without quotes.
7401
7402    Args:
7403        table: the table to normalize
7404        dialect: the dialect to use for normalization rules
7405        copy: whether to copy the expression.
7406
7407    Examples:
7408        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7409        'A-B.c'
7410    """
7411    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7412
7413    return ".".join(
7414        p.name
7415        for p in normalize_identifiers(
7416            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7417        ).parts
7418    )

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:
7421def replace_tables(
7422    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7423) -> E:
7424    """Replace all tables in expression according to the mapping.
7425
7426    Args:
7427        expression: expression node to be transformed and replaced.
7428        mapping: mapping of table names.
7429        dialect: the dialect of the mapping table
7430        copy: whether to copy the expression.
7431
7432    Examples:
7433        >>> from sqlglot import exp, parse_one
7434        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7435        'SELECT * FROM c /* a.b */'
7436
7437    Returns:
7438        The mapped expression.
7439    """
7440
7441    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7442
7443    def _replace_tables(node: Expression) -> Expression:
7444        if isinstance(node, Table):
7445            original = normalize_table_name(node, dialect=dialect)
7446            new_name = mapping.get(original)
7447
7448            if new_name:
7449                table = to_table(
7450                    new_name,
7451                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7452                    dialect=dialect,
7453                )
7454                table.add_comments([original])
7455                return table
7456        return node
7457
7458    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:
7461def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7462    """Replace placeholders in an expression.
7463
7464    Args:
7465        expression: expression node to be transformed and replaced.
7466        args: positional names that will substitute unnamed placeholders in the given order.
7467        kwargs: keyword arguments that will substitute named placeholders.
7468
7469    Examples:
7470        >>> from sqlglot import exp, parse_one
7471        >>> replace_placeholders(
7472        ...     parse_one("select * from :tbl where ? = ?"),
7473        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7474        ... ).sql()
7475        "SELECT * FROM foo WHERE str_col = 'b'"
7476
7477    Returns:
7478        The mapped expression.
7479    """
7480
7481    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7482        if isinstance(node, Placeholder):
7483            if node.this:
7484                new_name = kwargs.get(node.this)
7485                if new_name is not None:
7486                    return convert(new_name)
7487            else:
7488                try:
7489                    return convert(next(args))
7490                except StopIteration:
7491                    pass
7492        return node
7493
7494    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:
7497def expand(
7498    expression: Expression,
7499    sources: t.Dict[str, Query],
7500    dialect: DialectType = None,
7501    copy: bool = True,
7502) -> Expression:
7503    """Transforms an expression by expanding all referenced sources into subqueries.
7504
7505    Examples:
7506        >>> from sqlglot import parse_one
7507        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7508        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7509
7510        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7511        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7512
7513    Args:
7514        expression: The expression to expand.
7515        sources: A dictionary of name to Queries.
7516        dialect: The dialect of the sources dict.
7517        copy: Whether to copy the expression during transformation. Defaults to True.
7518
7519    Returns:
7520        The transformed expression.
7521    """
7522    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7523
7524    def _expand(node: Expression):
7525        if isinstance(node, Table):
7526            name = normalize_table_name(node, dialect=dialect)
7527            source = sources.get(name)
7528            if source:
7529                subquery = source.subquery(node.alias or name)
7530                subquery.comments = [f"source: {name}"]
7531                return subquery.transform(_expand, copy=False)
7532        return node
7533
7534    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:
7537def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7538    """
7539    Returns a Func expression.
7540
7541    Examples:
7542        >>> func("abs", 5).sql()
7543        'ABS(5)'
7544
7545        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7546        'CAST(5 AS DOUBLE)'
7547
7548    Args:
7549        name: the name of the function to build.
7550        args: the args used to instantiate the function of interest.
7551        copy: whether to copy the argument expressions.
7552        dialect: the source dialect.
7553        kwargs: the kwargs used to instantiate the function of interest.
7554
7555    Note:
7556        The arguments `args` and `kwargs` are mutually exclusive.
7557
7558    Returns:
7559        An instance of the function of interest, or an anonymous function, if `name` doesn't
7560        correspond to an existing `sqlglot.expressions.Func` class.
7561    """
7562    if args and kwargs:
7563        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7564
7565    from sqlglot.dialects.dialect import Dialect
7566
7567    dialect = Dialect.get_or_raise(dialect)
7568
7569    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7570    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7571
7572    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7573    if constructor:
7574        if converted:
7575            if "dialect" in constructor.__code__.co_varnames:
7576                function = constructor(converted, dialect=dialect)
7577            else:
7578                function = constructor(converted)
7579        elif constructor.__name__ == "from_arg_list":
7580            function = constructor.__self__(**kwargs)  # type: ignore
7581        else:
7582            constructor = FUNCTION_BY_NAME.get(name.upper())
7583            if constructor:
7584                function = constructor(**kwargs)
7585            else:
7586                raise ValueError(
7587                    f"Unable to convert '{name}' into a Func. Either manually construct "
7588                    "the Func expression of interest or parse the function call."
7589                )
7590    else:
7591        kwargs = kwargs or {"expressions": converted}
7592        function = Anonymous(this=name, **kwargs)
7593
7594    for error_message in function.error_messages(converted):
7595        raise ValueError(error_message)
7596
7597    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:
7600def case(
7601    expression: t.Optional[ExpOrStr] = None,
7602    **opts,
7603) -> Case:
7604    """
7605    Initialize a CASE statement.
7606
7607    Example:
7608        case().when("a = 1", "foo").else_("bar")
7609
7610    Args:
7611        expression: Optionally, the input expression (not all dialects support this)
7612        **opts: Extra keyword arguments for parsing `expression`
7613    """
7614    if expression is not None:
7615        this = maybe_parse(expression, **opts)
7616    else:
7617        this = None
7618    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:
7621def array(
7622    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7623) -> Array:
7624    """
7625    Returns an array.
7626
7627    Examples:
7628        >>> array(1, 'x').sql()
7629        'ARRAY(1, x)'
7630
7631    Args:
7632        expressions: the expressions to add to the array.
7633        copy: whether to copy the argument expressions.
7634        dialect: the source dialect.
7635        kwargs: the kwargs used to instantiate the function of interest.
7636
7637    Returns:
7638        An array expression.
7639    """
7640    return Array(
7641        expressions=[
7642            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7643            for expression in expressions
7644        ]
7645    )

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:
7648def tuple_(
7649    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7650) -> Tuple:
7651    """
7652    Returns an tuple.
7653
7654    Examples:
7655        >>> tuple_(1, 'x').sql()
7656        '(1, x)'
7657
7658    Args:
7659        expressions: the expressions to add to the tuple.
7660        copy: whether to copy the argument expressions.
7661        dialect: the source dialect.
7662        kwargs: the kwargs used to instantiate the function of interest.
7663
7664    Returns:
7665        A tuple expression.
7666    """
7667    return Tuple(
7668        expressions=[
7669            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7670            for expression in expressions
7671        ]
7672    )

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:
7675def true() -> Boolean:
7676    """
7677    Returns a true Boolean expression.
7678    """
7679    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7682def false() -> Boolean:
7683    """
7684    Returns a false Boolean expression.
7685    """
7686    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7689def null() -> Null:
7690    """
7691    Returns a Null expression.
7692    """
7693    return Null()

Returns a Null expression.

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