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

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

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

Returns the output names of the query's projections.

is_star: bool
3108    @property
3109    def is_star(self) -> bool:
3110        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3112    @property
3113    def selects(self) -> t.List[Expression]:
3114        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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:
3350    def select(
3351        self,
3352        *expressions: t.Optional[ExpOrStr],
3353        append: bool = True,
3354        dialect: DialectType = None,
3355        copy: bool = True,
3356        **opts,
3357    ) -> Select:
3358        return _apply_list_builder(
3359            *expressions,
3360            instance=self,
3361            arg="expressions",
3362            append=append,
3363            dialect=dialect,
3364            into=Expression,
3365            copy=copy,
3366            **opts,
3367        )

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3740    @property
3741    def selects(self) -> t.List[Expression]:
3742        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

output_name: str
3796    @property
3797    def output_name(self) -> str:
3798        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):
3801class TableSample(Expression):
3802    arg_types = {
3803        "this": False,
3804        "expressions": False,
3805        "method": False,
3806        "bucket_numerator": False,
3807        "bucket_denominator": False,
3808        "bucket_field": False,
3809        "percent": False,
3810        "rows": False,
3811        "size": False,
3812        "seed": False,
3813    }
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):
3816class Tag(Expression):
3817    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3818
3819    arg_types = {
3820        "this": False,
3821        "prefix": False,
3822        "postfix": False,
3823    }

Tags are used for generating arbitrary sql like SELECT x.

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

Checks whether an expression is a star.

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

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

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

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

key = 'kwarg'
class Like(Binary, Predicate):
4425class Like(Binary, Predicate):
4426    pass
key = 'like'
class LikeAny(Binary, Predicate):
4429class LikeAny(Binary, Predicate):
4430    pass
key = 'likeany'
class LT(Binary, Predicate):
4433class LT(Binary, Predicate):
4434    pass
key = 'lt'
class LTE(Binary, Predicate):
4437class LTE(Binary, Predicate):
4438    pass
key = 'lte'
class Mod(Binary):
4441class Mod(Binary):
4442    pass
key = 'mod'
class Mul(Binary):
4445class Mul(Binary):
4446    pass
key = 'mul'
class NEQ(Binary, Predicate):
4449class NEQ(Binary, Predicate):
4450    pass
key = 'neq'
class Operator(Binary):
4454class Operator(Binary):
4455    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4458class SimilarTo(Binary, Predicate):
4459    pass
key = 'similarto'
class Slice(Binary):
4462class Slice(Binary):
4463    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4466class Sub(Binary):
4467    pass
key = 'sub'
class Unary(Condition):
4472class Unary(Condition):
4473    pass
key = 'unary'
class BitwiseNot(Unary):
4476class BitwiseNot(Unary):
4477    pass
key = 'bitwisenot'
class Not(Unary):
4480class Not(Unary):
4481    pass
key = 'not'
class Paren(Unary):
4484class Paren(Unary):
4485    @property
4486    def output_name(self) -> str:
4487        return self.this.name
output_name: str
4485    @property
4486    def output_name(self) -> str:
4487        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):
4490class Neg(Unary):
4491    pass
key = 'neg'
class Alias(Expression):
4494class Alias(Expression):
4495    arg_types = {"this": True, "alias": False}
4496
4497    @property
4498    def output_name(self) -> str:
4499        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4497    @property
4498    def output_name(self) -> str:
4499        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):
4504class PivotAlias(Alias):
4505    pass
key = 'pivotalias'
class Aliases(Expression):
4508class Aliases(Expression):
4509    arg_types = {"this": True, "expressions": True}
4510
4511    @property
4512    def aliases(self):
4513        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4511    @property
4512    def aliases(self):
4513        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4517class AtIndex(Expression):
4518    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4521class AtTimeZone(Expression):
4522    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4525class FromTimeZone(Expression):
4526    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4529class Between(Predicate):
4530    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4533class Bracket(Condition):
4534    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4535    arg_types = {
4536        "this": True,
4537        "expressions": True,
4538        "offset": False,
4539        "safe": False,
4540        "returns_list_for_maps": False,
4541    }
4542
4543    @property
4544    def output_name(self) -> str:
4545        if len(self.expressions) == 1:
4546            return self.expressions[0].output_name
4547
4548        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4543    @property
4544    def output_name(self) -> str:
4545        if len(self.expressions) == 1:
4546            return self.expressions[0].output_name
4547
4548        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):
4551class Distinct(Expression):
4552    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4555class In(Predicate):
4556    arg_types = {
4557        "this": True,
4558        "expressions": False,
4559        "query": False,
4560        "unnest": False,
4561        "field": False,
4562        "is_global": False,
4563    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4567class ForIn(Expression):
4568    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4571class TimeUnit(Expression):
4572    """Automatically converts unit arg into a var."""
4573
4574    arg_types = {"unit": False}
4575
4576    UNABBREVIATED_UNIT_NAME = {
4577        "D": "DAY",
4578        "H": "HOUR",
4579        "M": "MINUTE",
4580        "MS": "MILLISECOND",
4581        "NS": "NANOSECOND",
4582        "Q": "QUARTER",
4583        "S": "SECOND",
4584        "US": "MICROSECOND",
4585        "W": "WEEK",
4586        "Y": "YEAR",
4587    }
4588
4589    VAR_LIKE = (Column, Literal, Var)
4590
4591    def __init__(self, **args):
4592        unit = args.get("unit")
4593        if isinstance(unit, self.VAR_LIKE):
4594            args["unit"] = Var(
4595                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4596            )
4597        elif isinstance(unit, Week):
4598            unit.set("this", Var(this=unit.this.name.upper()))
4599
4600        super().__init__(**args)
4601
4602    @property
4603    def unit(self) -> t.Optional[Var | IntervalSpan]:
4604        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4591    def __init__(self, **args):
4592        unit = args.get("unit")
4593        if isinstance(unit, self.VAR_LIKE):
4594            args["unit"] = Var(
4595                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4596            )
4597        elif isinstance(unit, Week):
4598            unit.set("this", Var(this=unit.this.name.upper()))
4599
4600        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]
4602    @property
4603    def unit(self) -> t.Optional[Var | IntervalSpan]:
4604        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4607class IntervalOp(TimeUnit):
4608    arg_types = {"unit": True, "expression": True}
4609
4610    def interval(self):
4611        return Interval(
4612            this=self.expression.copy(),
4613            unit=self.unit.copy(),
4614        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4610    def interval(self):
4611        return Interval(
4612            this=self.expression.copy(),
4613            unit=self.unit.copy(),
4614        )
key = 'intervalop'
class IntervalSpan(DataType):
4620class IntervalSpan(DataType):
4621    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4624class Interval(TimeUnit):
4625    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4628class IgnoreNulls(Expression):
4629    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4632class RespectNulls(Expression):
4633    pass
key = 'respectnulls'
class HavingMax(Expression):
4637class HavingMax(Expression):
4638    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4642class Func(Condition):
4643    """
4644    The base class for all function expressions.
4645
4646    Attributes:
4647        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4648            treated as a variable length argument and the argument's value will be stored as a list.
4649        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4650            function expression. These values are used to map this node to a name during parsing as
4651            well as to provide the function's name during SQL string generation. By default the SQL
4652            name is set to the expression's class name transformed to snake case.
4653    """
4654
4655    is_var_len_args = False
4656
4657    @classmethod
4658    def from_arg_list(cls, args):
4659        if cls.is_var_len_args:
4660            all_arg_keys = list(cls.arg_types)
4661            # If this function supports variable length argument treat the last argument as such.
4662            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4663            num_non_var = len(non_var_len_arg_keys)
4664
4665            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4666            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4667        else:
4668            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4669
4670        return cls(**args_dict)
4671
4672    @classmethod
4673    def sql_names(cls):
4674        if cls is Func:
4675            raise NotImplementedError(
4676                "SQL name is only supported by concrete function implementations"
4677            )
4678        if "_sql_names" not in cls.__dict__:
4679            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4680        return cls._sql_names
4681
4682    @classmethod
4683    def sql_name(cls):
4684        return cls.sql_names()[0]
4685
4686    @classmethod
4687    def default_parser_mappings(cls):
4688        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):
4657    @classmethod
4658    def from_arg_list(cls, args):
4659        if cls.is_var_len_args:
4660            all_arg_keys = list(cls.arg_types)
4661            # If this function supports variable length argument treat the last argument as such.
4662            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4663            num_non_var = len(non_var_len_arg_keys)
4664
4665            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4666            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4667        else:
4668            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4669
4670        return cls(**args_dict)
@classmethod
def sql_names(cls):
4672    @classmethod
4673    def sql_names(cls):
4674        if cls is Func:
4675            raise NotImplementedError(
4676                "SQL name is only supported by concrete function implementations"
4677            )
4678        if "_sql_names" not in cls.__dict__:
4679            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4680        return cls._sql_names
@classmethod
def sql_name(cls):
4682    @classmethod
4683    def sql_name(cls):
4684        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4686    @classmethod
4687    def default_parser_mappings(cls):
4688        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4691class AggFunc(Func):
4692    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4695class ParameterizedAgg(AggFunc):
4696    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4699class Abs(Func):
4700    pass
key = 'abs'
class ArgMax(AggFunc):
4703class ArgMax(AggFunc):
4704    arg_types = {"this": True, "expression": True, "count": False}
4705    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4708class ArgMin(AggFunc):
4709    arg_types = {"this": True, "expression": True, "count": False}
4710    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4713class ApproxTopK(AggFunc):
4714    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4717class Flatten(Func):
4718    pass
key = 'flatten'
class Transform(Func):
4722class Transform(Func):
4723    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4726class Anonymous(Func):
4727    arg_types = {"this": True, "expressions": False}
4728    is_var_len_args = True
4729
4730    @property
4731    def name(self) -> str:
4732        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
4730    @property
4731    def name(self) -> str:
4732        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4735class AnonymousAggFunc(AggFunc):
4736    arg_types = {"this": True, "expressions": False}
4737    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4741class CombinedAggFunc(AnonymousAggFunc):
4742    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4745class CombinedParameterizedAgg(ParameterizedAgg):
4746    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):
4751class Hll(AggFunc):
4752    arg_types = {"this": True, "expressions": False}
4753    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4756class ApproxDistinct(AggFunc):
4757    arg_types = {"this": True, "accuracy": False}
4758    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4761class Array(Func):
4762    arg_types = {"expressions": False}
4763    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4767class ToArray(Func):
4768    pass
key = 'toarray'
class List(Func):
4772class List(Func):
4773    arg_types = {"expressions": False}
4774    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class ToChar(Func):
4779class ToChar(Func):
4780    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4785class ToNumber(Func):
4786    arg_types = {
4787        "this": True,
4788        "format": False,
4789        "nlsparam": False,
4790        "precision": False,
4791        "scale": False,
4792    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4796class Convert(Func):
4797    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4800class GenerateSeries(Func):
4801    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):
4804class ArrayAgg(AggFunc):
4805    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4808class ArrayUniqueAgg(AggFunc):
4809    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4812class ArrayAll(Func):
4813    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4817class ArrayAny(Func):
4818    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4821class ArrayConcat(Func):
4822    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4823    arg_types = {"this": True, "expressions": False}
4824    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4827class ArrayConstructCompact(Func):
4828    arg_types = {"expressions": True}
4829    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4832class ArrayContains(Binary, Func):
4833    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4836class ArrayContainsAll(Binary, Func):
4837    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4840class ArrayFilter(Func):
4841    arg_types = {"this": True, "expression": True}
4842    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4845class ArrayToString(Func):
4846    arg_types = {"this": True, "expression": True, "null": False}
4847    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4850class StringToArray(Func):
4851    arg_types = {"this": True, "expression": True, "null": False}
4852    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4855class ArrayOverlaps(Binary, Func):
4856    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4859class ArraySize(Func):
4860    arg_types = {"this": True, "expression": False}
4861    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4864class ArraySort(Func):
4865    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4868class ArraySum(Func):
4869    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4872class ArrayUnionAgg(AggFunc):
4873    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4876class Avg(AggFunc):
4877    pass
key = 'avg'
class AnyValue(AggFunc):
4880class AnyValue(AggFunc):
4881    pass
key = 'anyvalue'
class Lag(AggFunc):
4884class Lag(AggFunc):
4885    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4888class Lead(AggFunc):
4889    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4894class First(AggFunc):
4895    pass
key = 'first'
class Last(AggFunc):
4898class Last(AggFunc):
4899    pass
key = 'last'
class FirstValue(AggFunc):
4902class FirstValue(AggFunc):
4903    pass
key = 'firstvalue'
class LastValue(AggFunc):
4906class LastValue(AggFunc):
4907    pass
key = 'lastvalue'
class NthValue(AggFunc):
4910class NthValue(AggFunc):
4911    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4914class Case(Func):
4915    arg_types = {"this": False, "ifs": True, "default": False}
4916
4917    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4918        instance = maybe_copy(self, copy)
4919        instance.append(
4920            "ifs",
4921            If(
4922                this=maybe_parse(condition, copy=copy, **opts),
4923                true=maybe_parse(then, copy=copy, **opts),
4924            ),
4925        )
4926        return instance
4927
4928    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4929        instance = maybe_copy(self, copy)
4930        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4931        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:
4917    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4918        instance = maybe_copy(self, copy)
4919        instance.append(
4920            "ifs",
4921            If(
4922                this=maybe_parse(condition, copy=copy, **opts),
4923                true=maybe_parse(then, copy=copy, **opts),
4924            ),
4925        )
4926        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4928    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4929        instance = maybe_copy(self, copy)
4930        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4931        return instance
key = 'case'
class Cast(Func):
4934class Cast(Func):
4935    arg_types = {
4936        "this": True,
4937        "to": True,
4938        "format": False,
4939        "safe": False,
4940        "action": False,
4941    }
4942
4943    @property
4944    def name(self) -> str:
4945        return self.this.name
4946
4947    @property
4948    def to(self) -> DataType:
4949        return self.args["to"]
4950
4951    @property
4952    def output_name(self) -> str:
4953        return self.name
4954
4955    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4956        """
4957        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4958        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4959        array<int> != array<float>.
4960
4961        Args:
4962            dtypes: the data types to compare this Cast's DataType to.
4963
4964        Returns:
4965            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4966        """
4967        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4943    @property
4944    def name(self) -> str:
4945        return self.this.name
to: DataType
4947    @property
4948    def to(self) -> DataType:
4949        return self.args["to"]
output_name: str
4951    @property
4952    def output_name(self) -> str:
4953        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:
4955    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4956        """
4957        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4958        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4959        array<int> != array<float>.
4960
4961        Args:
4962            dtypes: the data types to compare this Cast's DataType to.
4963
4964        Returns:
4965            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4966        """
4967        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):
4970class TryCast(Cast):
4971    pass
key = 'trycast'
class Try(Func):
4974class Try(Func):
4975    pass
key = 'try'
class CastToStrType(Func):
4978class CastToStrType(Func):
4979    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4982class Collate(Binary, Func):
4983    pass
key = 'collate'
class Ceil(Func):
4986class Ceil(Func):
4987    arg_types = {"this": True, "decimals": False}
4988    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4991class Coalesce(Func):
4992    arg_types = {"this": True, "expressions": False}
4993    is_var_len_args = True
4994    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4997class Chr(Func):
4998    arg_types = {"this": True, "charset": False, "expressions": False}
4999    is_var_len_args = True
5000    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5003class Concat(Func):
5004    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5005    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5008class ConcatWs(Concat):
5009    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5013class ConnectByRoot(Func):
5014    pass
key = 'connectbyroot'
class Count(AggFunc):
5017class Count(AggFunc):
5018    arg_types = {"this": False, "expressions": False}
5019    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5022class CountIf(AggFunc):
5023    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5027class Cbrt(Func):
5028    pass
key = 'cbrt'
class CurrentDate(Func):
5031class CurrentDate(Func):
5032    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5035class CurrentDatetime(Func):
5036    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5039class CurrentTime(Func):
5040    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5043class CurrentTimestamp(Func):
5044    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5047class CurrentUser(Func):
5048    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5051class DateAdd(Func, IntervalOp):
5052    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5055class DateSub(Func, IntervalOp):
5056    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5059class DateDiff(Func, TimeUnit):
5060    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5061    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5064class DateTrunc(Func):
5065    arg_types = {"unit": True, "this": True, "zone": False}
5066
5067    def __init__(self, **args):
5068        unit = args.get("unit")
5069        if isinstance(unit, TimeUnit.VAR_LIKE):
5070            args["unit"] = Literal.string(
5071                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5072            )
5073        elif isinstance(unit, Week):
5074            unit.set("this", Literal.string(unit.this.name.upper()))
5075
5076        super().__init__(**args)
5077
5078    @property
5079    def unit(self) -> Expression:
5080        return self.args["unit"]
DateTrunc(**args)
5067    def __init__(self, **args):
5068        unit = args.get("unit")
5069        if isinstance(unit, TimeUnit.VAR_LIKE):
5070            args["unit"] = Literal.string(
5071                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5072            )
5073        elif isinstance(unit, Week):
5074            unit.set("this", Literal.string(unit.this.name.upper()))
5075
5076        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5078    @property
5079    def unit(self) -> Expression:
5080        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5085class Datetime(Func):
5086    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5089class DatetimeAdd(Func, IntervalOp):
5090    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5093class DatetimeSub(Func, IntervalOp):
5094    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5097class DatetimeDiff(Func, TimeUnit):
5098    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5101class DatetimeTrunc(Func, TimeUnit):
5102    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5105class DayOfWeek(Func):
5106    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5109class DayOfMonth(Func):
5110    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5113class DayOfYear(Func):
5114    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5117class ToDays(Func):
5118    pass
key = 'todays'
class WeekOfYear(Func):
5121class WeekOfYear(Func):
5122    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5125class MonthsBetween(Func):
5126    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5129class LastDay(Func, TimeUnit):
5130    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5131    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5134class Extract(Func):
5135    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5138class Timestamp(Func):
5139    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5142class TimestampAdd(Func, TimeUnit):
5143    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5146class TimestampSub(Func, TimeUnit):
5147    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5150class TimestampDiff(Func, TimeUnit):
5151    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5152    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5155class TimestampTrunc(Func, TimeUnit):
5156    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5159class TimeAdd(Func, TimeUnit):
5160    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5163class TimeSub(Func, TimeUnit):
5164    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5167class TimeDiff(Func, TimeUnit):
5168    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5171class TimeTrunc(Func, TimeUnit):
5172    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5175class DateFromParts(Func):
5176    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5177    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5180class TimeFromParts(Func):
5181    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5182    arg_types = {
5183        "hour": True,
5184        "min": True,
5185        "sec": True,
5186        "nano": False,
5187        "fractions": False,
5188        "precision": False,
5189    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5192class DateStrToDate(Func):
5193    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5196class DateToDateStr(Func):
5197    pass
key = 'datetodatestr'
class DateToDi(Func):
5200class DateToDi(Func):
5201    pass
key = 'datetodi'
class Date(Func):
5205class Date(Func):
5206    arg_types = {"this": False, "zone": False, "expressions": False}
5207    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5210class Day(Func):
5211    pass
key = 'day'
class Decode(Func):
5214class Decode(Func):
5215    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5218class DiToDate(Func):
5219    pass
key = 'ditodate'
class Encode(Func):
5222class Encode(Func):
5223    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5226class Exp(Func):
5227    pass
key = 'exp'
class Explode(Func):
5231class Explode(Func):
5232    arg_types = {"this": True, "expressions": False}
5233    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5236class ExplodeOuter(Explode):
5237    pass
key = 'explodeouter'
class Posexplode(Explode):
5240class Posexplode(Explode):
5241    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5244class PosexplodeOuter(Posexplode, ExplodeOuter):
5245    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5248class Unnest(Func, UDTF):
5249    arg_types = {
5250        "expressions": True,
5251        "alias": False,
5252        "offset": False,
5253    }
5254
5255    @property
5256    def selects(self) -> t.List[Expression]:
5257        columns = super().selects
5258        offset = self.args.get("offset")
5259        if offset:
5260            columns = columns + [to_identifier("offset") if offset is True else offset]
5261        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5255    @property
5256    def selects(self) -> t.List[Expression]:
5257        columns = super().selects
5258        offset = self.args.get("offset")
5259        if offset:
5260            columns = columns + [to_identifier("offset") if offset is True else offset]
5261        return columns
key = 'unnest'
class Floor(Func):
5264class Floor(Func):
5265    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5268class FromBase64(Func):
5269    pass
key = 'frombase64'
class ToBase64(Func):
5272class ToBase64(Func):
5273    pass
key = 'tobase64'
class GapFill(Func):
5276class GapFill(Func):
5277    arg_types = {
5278        "this": True,
5279        "ts_column": True,
5280        "bucket_width": True,
5281        "partitioning_columns": False,
5282        "value_columns": False,
5283        "origin": False,
5284        "ignore_nulls": False,
5285    }
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):
5288class GenerateDateArray(Func):
5289    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5292class Greatest(Func):
5293    arg_types = {"this": True, "expressions": False}
5294    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5297class GroupConcat(AggFunc):
5298    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5301class Hex(Func):
5302    pass
key = 'hex'
class LowerHex(Hex):
5305class LowerHex(Hex):
5306    pass
key = 'lowerhex'
class Xor(Connector, Func):
5309class Xor(Connector, Func):
5310    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5313class If(Func):
5314    arg_types = {"this": True, "true": True, "false": False}
5315    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5318class Nullif(Func):
5319    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5322class Initcap(Func):
5323    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5326class IsNan(Func):
5327    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5330class IsInf(Func):
5331    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5334class JSONPath(Expression):
5335    arg_types = {"expressions": True}
5336
5337    @property
5338    def output_name(self) -> str:
5339        last_segment = self.expressions[-1].this
5340        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5337    @property
5338    def output_name(self) -> str:
5339        last_segment = self.expressions[-1].this
5340        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):
5343class JSONPathPart(Expression):
5344    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5347class JSONPathFilter(JSONPathPart):
5348    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5351class JSONPathKey(JSONPathPart):
5352    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5355class JSONPathRecursive(JSONPathPart):
5356    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5359class JSONPathRoot(JSONPathPart):
5360    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5363class JSONPathScript(JSONPathPart):
5364    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5367class JSONPathSlice(JSONPathPart):
5368    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5371class JSONPathSelector(JSONPathPart):
5372    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5375class JSONPathSubscript(JSONPathPart):
5376    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5379class JSONPathUnion(JSONPathPart):
5380    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5383class JSONPathWildcard(JSONPathPart):
5384    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5387class FormatJson(Expression):
5388    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5391class JSONKeyValue(Expression):
5392    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5395class JSONObject(Func):
5396    arg_types = {
5397        "expressions": False,
5398        "null_handling": False,
5399        "unique_keys": False,
5400        "return_type": False,
5401        "encoding": False,
5402    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5405class JSONObjectAgg(AggFunc):
5406    arg_types = {
5407        "expressions": False,
5408        "null_handling": False,
5409        "unique_keys": False,
5410        "return_type": False,
5411        "encoding": False,
5412    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5416class JSONArray(Func):
5417    arg_types = {
5418        "expressions": True,
5419        "null_handling": False,
5420        "return_type": False,
5421        "strict": False,
5422    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5426class JSONArrayAgg(Func):
5427    arg_types = {
5428        "this": True,
5429        "order": False,
5430        "null_handling": False,
5431        "return_type": False,
5432        "strict": False,
5433    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5438class JSONColumnDef(Expression):
5439    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):
5442class JSONSchema(Expression):
5443    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5447class JSONTable(Func):
5448    arg_types = {
5449        "this": True,
5450        "schema": True,
5451        "path": False,
5452        "error_handling": False,
5453        "empty_handling": False,
5454    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5457class OpenJSONColumnDef(Expression):
5458    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):
5461class OpenJSON(Func):
5462    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5465class JSONBContains(Binary, Func):
5466    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5469class JSONExtract(Binary, Func):
5470    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5471    _sql_names = ["JSON_EXTRACT"]
5472    is_var_len_args = True
5473
5474    @property
5475    def output_name(self) -> str:
5476        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
5474    @property
5475    def output_name(self) -> str:
5476        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):
5479class JSONExtractScalar(Binary, Func):
5480    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5481    _sql_names = ["JSON_EXTRACT_SCALAR"]
5482    is_var_len_args = True
5483
5484    @property
5485    def output_name(self) -> str:
5486        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
5484    @property
5485    def output_name(self) -> str:
5486        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):
5489class JSONBExtract(Binary, Func):
5490    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5493class JSONBExtractScalar(Binary, Func):
5494    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5497class JSONFormat(Func):
5498    arg_types = {"this": False, "options": False}
5499    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5503class JSONArrayContains(Binary, Predicate, Func):
5504    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5507class ParseJSON(Func):
5508    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5509    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5510    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5511    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5514class Least(Func):
5515    arg_types = {"this": True, "expressions": False}
5516    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5519class Left(Func):
5520    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5527class Length(Func):
5528    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5531class Levenshtein(Func):
5532    arg_types = {
5533        "this": True,
5534        "expression": False,
5535        "ins_cost": False,
5536        "del_cost": False,
5537        "sub_cost": False,
5538    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5541class Ln(Func):
5542    pass
key = 'ln'
class Log(Func):
5545class Log(Func):
5546    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5549class LogicalOr(AggFunc):
5550    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5553class LogicalAnd(AggFunc):
5554    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5557class Lower(Func):
5558    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5561class Map(Func):
5562    arg_types = {"keys": False, "values": False}
5563
5564    @property
5565    def keys(self) -> t.List[Expression]:
5566        keys = self.args.get("keys")
5567        return keys.expressions if keys else []
5568
5569    @property
5570    def values(self) -> t.List[Expression]:
5571        values = self.args.get("values")
5572        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5564    @property
5565    def keys(self) -> t.List[Expression]:
5566        keys = self.args.get("keys")
5567        return keys.expressions if keys else []
values: List[Expression]
5569    @property
5570    def values(self) -> t.List[Expression]:
5571        values = self.args.get("values")
5572        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5576class ToMap(Func):
5577    pass
key = 'tomap'
class MapFromEntries(Func):
5580class MapFromEntries(Func):
5581    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5585class ScopeResolution(Expression):
5586    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class StarMap(Func):
5589class StarMap(Func):
5590    pass
key = 'starmap'
class VarMap(Func):
5593class VarMap(Func):
5594    arg_types = {"keys": True, "values": True}
5595    is_var_len_args = True
5596
5597    @property
5598    def keys(self) -> t.List[Expression]:
5599        return self.args["keys"].expressions
5600
5601    @property
5602    def values(self) -> t.List[Expression]:
5603        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5597    @property
5598    def keys(self) -> t.List[Expression]:
5599        return self.args["keys"].expressions
values: List[Expression]
5601    @property
5602    def values(self) -> t.List[Expression]:
5603        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5607class MatchAgainst(Func):
5608    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5611class Max(AggFunc):
5612    arg_types = {"this": True, "expressions": False}
5613    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5616class MD5(Func):
5617    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5621class MD5Digest(Func):
5622    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5625class Min(AggFunc):
5626    arg_types = {"this": True, "expressions": False}
5627    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5630class Month(Func):
5631    pass
key = 'month'
class AddMonths(Func):
5634class AddMonths(Func):
5635    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5638class Nvl2(Func):
5639    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5643class Predict(Func):
5644    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5647class Pow(Binary, Func):
5648    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5651class PercentileCont(AggFunc):
5652    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5655class PercentileDisc(AggFunc):
5656    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5659class Quantile(AggFunc):
5660    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5663class ApproxQuantile(Quantile):
5664    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):
5667class Quarter(Func):
5668    pass
key = 'quarter'
class Rand(Func):
5671class Rand(Func):
5672    _sql_names = ["RAND", "RANDOM"]
5673    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5676class Randn(Func):
5677    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5680class RangeN(Func):
5681    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5684class ReadCSV(Func):
5685    _sql_names = ["READ_CSV"]
5686    is_var_len_args = True
5687    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5690class Reduce(Func):
5691    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):
5694class RegexpExtract(Func):
5695    arg_types = {
5696        "this": True,
5697        "expression": True,
5698        "position": False,
5699        "occurrence": False,
5700        "parameters": False,
5701        "group": False,
5702    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5705class RegexpReplace(Func):
5706    arg_types = {
5707        "this": True,
5708        "expression": True,
5709        "replacement": False,
5710        "position": False,
5711        "occurrence": False,
5712        "modifiers": False,
5713    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5716class RegexpLike(Binary, Func):
5717    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5720class RegexpILike(Binary, Func):
5721    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5726class RegexpSplit(Func):
5727    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5730class Repeat(Func):
5731    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5736class Round(Func):
5737    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5740class RowNumber(Func):
5741    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5744class SafeDivide(Func):
5745    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5748class SHA(Func):
5749    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5752class SHA2(Func):
5753    _sql_names = ["SHA2"]
5754    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5757class Sign(Func):
5758    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5761class SortArray(Func):
5762    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5765class Split(Func):
5766    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5771class Substring(Func):
5772    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5775class StandardHash(Func):
5776    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5779class StartsWith(Func):
5780    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5781    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5784class StrPosition(Func):
5785    arg_types = {
5786        "this": True,
5787        "substr": True,
5788        "position": False,
5789        "instance": False,
5790    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5793class StrToDate(Func):
5794    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'strtodate'
class StrToTime(Func):
5797class StrToTime(Func):
5798    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5803class StrToUnix(Func):
5804    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5809class StrToMap(Func):
5810    arg_types = {
5811        "this": True,
5812        "pair_delim": False,
5813        "key_value_delim": False,
5814        "duplicate_resolution_callback": False,
5815    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5818class NumberToStr(Func):
5819    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5822class FromBase(Func):
5823    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5826class Struct(Func):
5827    arg_types = {"expressions": False}
5828    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5831class StructExtract(Func):
5832    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5837class Stuff(Func):
5838    _sql_names = ["STUFF", "INSERT"]
5839    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):
5842class Sum(AggFunc):
5843    pass
key = 'sum'
class Sqrt(Func):
5846class Sqrt(Func):
5847    pass
key = 'sqrt'
class Stddev(AggFunc):
5850class Stddev(AggFunc):
5851    pass
key = 'stddev'
class StddevPop(AggFunc):
5854class StddevPop(AggFunc):
5855    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5858class StddevSamp(AggFunc):
5859    pass
key = 'stddevsamp'
class Time(Func):
5863class Time(Func):
5864    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
5867class TimeToStr(Func):
5868    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):
5871class TimeToTimeStr(Func):
5872    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5875class TimeToUnix(Func):
5876    pass
key = 'timetounix'
class TimeStrToDate(Func):
5879class TimeStrToDate(Func):
5880    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5883class TimeStrToTime(Func):
5884    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5887class TimeStrToUnix(Func):
5888    pass
key = 'timestrtounix'
class Trim(Func):
5891class Trim(Func):
5892    arg_types = {
5893        "this": True,
5894        "expression": False,
5895        "position": False,
5896        "collation": False,
5897    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5900class TsOrDsAdd(Func, TimeUnit):
5901    # return_type is used to correctly cast the arguments of this expression when transpiling it
5902    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5903
5904    @property
5905    def return_type(self) -> DataType:
5906        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
5904    @property
5905    def return_type(self) -> DataType:
5906        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5909class TsOrDsDiff(Func, TimeUnit):
5910    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5913class TsOrDsToDateStr(Func):
5914    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5917class TsOrDsToDate(Func):
5918    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5921class TsOrDsToTime(Func):
5922    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5925class TsOrDsToTimestamp(Func):
5926    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5929class TsOrDiToDi(Func):
5930    pass
key = 'tsorditodi'
class Unhex(Func):
5933class Unhex(Func):
5934    pass
key = 'unhex'
class UnixDate(Func):
5938class UnixDate(Func):
5939    pass
key = 'unixdate'
class UnixToStr(Func):
5942class UnixToStr(Func):
5943    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5948class UnixToTime(Func):
5949    arg_types = {
5950        "this": True,
5951        "scale": False,
5952        "zone": False,
5953        "hours": False,
5954        "minutes": False,
5955        "format": False,
5956    }
5957
5958    SECONDS = Literal.number(0)
5959    DECIS = Literal.number(1)
5960    CENTIS = Literal.number(2)
5961    MILLIS = Literal.number(3)
5962    DECIMILLIS = Literal.number(4)
5963    CENTIMILLIS = Literal.number(5)
5964    MICROS = Literal.number(6)
5965    DECIMICROS = Literal.number(7)
5966    CENTIMICROS = Literal.number(8)
5967    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):
5970class UnixToTimeStr(Func):
5971    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5974class TimestampFromParts(Func):
5975    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5976    arg_types = {
5977        "year": True,
5978        "month": True,
5979        "day": True,
5980        "hour": True,
5981        "min": True,
5982        "sec": True,
5983        "nano": False,
5984        "zone": False,
5985        "milli": False,
5986    }
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):
5989class Upper(Func):
5990    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5993class Corr(Binary, AggFunc):
5994    pass
key = 'corr'
class Variance(AggFunc):
5997class Variance(AggFunc):
5998    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6001class VariancePop(AggFunc):
6002    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6005class CovarSamp(Binary, AggFunc):
6006    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6009class CovarPop(Binary, AggFunc):
6010    pass
key = 'covarpop'
class Week(Func):
6013class Week(Func):
6014    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6017class XMLTable(Func):
6018    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):
6021class Year(Func):
6022    pass
key = 'year'
class Use(Expression):
6025class Use(Expression):
6026    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6029class Merge(Expression):
6030    arg_types = {
6031        "this": True,
6032        "using": True,
6033        "on": True,
6034        "expressions": True,
6035        "with": False,
6036    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6039class When(Func):
6040    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):
6045class NextValueFor(Func):
6046    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6051class Semicolon(Expression):
6052    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'Time'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME': <class 'Time'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY': <class 'Try'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UNNEST': <class 'Unnest'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'WHEN': <class 'When'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
PERCENTILES = (<class 'PercentileCont'>, <class 'PercentileDisc'>)
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
6092def maybe_parse(
6093    sql_or_expression: ExpOrStr,
6094    *,
6095    into: t.Optional[IntoType] = None,
6096    dialect: DialectType = None,
6097    prefix: t.Optional[str] = None,
6098    copy: bool = False,
6099    **opts,
6100) -> Expression:
6101    """Gracefully handle a possible string or expression.
6102
6103    Example:
6104        >>> maybe_parse("1")
6105        Literal(this=1, is_string=False)
6106        >>> maybe_parse(to_identifier("x"))
6107        Identifier(this=x, quoted=False)
6108
6109    Args:
6110        sql_or_expression: the SQL code string or an expression
6111        into: the SQLGlot Expression to parse into
6112        dialect: the dialect used to parse the input expressions (in the case that an
6113            input expression is a SQL string).
6114        prefix: a string to prefix the sql with before it gets parsed
6115            (automatically includes a space)
6116        copy: whether to copy the expression.
6117        **opts: other options to use to parse the input expressions (again, in the case
6118            that an input expression is a SQL string).
6119
6120    Returns:
6121        Expression: the parsed or given expression.
6122    """
6123    if isinstance(sql_or_expression, Expression):
6124        if copy:
6125            return sql_or_expression.copy()
6126        return sql_or_expression
6127
6128    if sql_or_expression is None:
6129        raise ParseError("SQL cannot be None")
6130
6131    import sqlglot
6132
6133    sql = str(sql_or_expression)
6134    if prefix:
6135        sql = f"{prefix} {sql}"
6136
6137    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):
6148def maybe_copy(instance, copy=True):
6149    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:
6369def union(
6370    left: ExpOrStr,
6371    right: ExpOrStr,
6372    distinct: bool = True,
6373    dialect: DialectType = None,
6374    copy: bool = True,
6375    **opts,
6376) -> Union:
6377    """
6378    Initializes a syntax tree from one UNION expression.
6379
6380    Example:
6381        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6382        'SELECT * FROM foo UNION SELECT * FROM bla'
6383
6384    Args:
6385        left: the SQL code string corresponding to the left-hand side.
6386            If an `Expression` instance is passed, it will be used as-is.
6387        right: the SQL code string corresponding to the right-hand side.
6388            If an `Expression` instance is passed, it will be used as-is.
6389        distinct: set the DISTINCT flag if and only if this is true.
6390        dialect: the dialect used to parse the input expression.
6391        copy: whether to copy the expression.
6392        opts: other options to use to parse the input expressions.
6393
6394    Returns:
6395        The new Union instance.
6396    """
6397    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6398    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6399
6400    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:
6403def intersect(
6404    left: ExpOrStr,
6405    right: ExpOrStr,
6406    distinct: bool = True,
6407    dialect: DialectType = None,
6408    copy: bool = True,
6409    **opts,
6410) -> Intersect:
6411    """
6412    Initializes a syntax tree from one INTERSECT expression.
6413
6414    Example:
6415        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6416        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6417
6418    Args:
6419        left: the SQL code string corresponding to the left-hand side.
6420            If an `Expression` instance is passed, it will be used as-is.
6421        right: the SQL code string corresponding to the right-hand side.
6422            If an `Expression` instance is passed, it will be used as-is.
6423        distinct: set the DISTINCT flag if and only if this is true.
6424        dialect: the dialect used to parse the input expression.
6425        copy: whether to copy the expression.
6426        opts: other options to use to parse the input expressions.
6427
6428    Returns:
6429        The new Intersect instance.
6430    """
6431    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6432    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6433
6434    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:
6437def except_(
6438    left: ExpOrStr,
6439    right: ExpOrStr,
6440    distinct: bool = True,
6441    dialect: DialectType = None,
6442    copy: bool = True,
6443    **opts,
6444) -> Except:
6445    """
6446    Initializes a syntax tree from one EXCEPT expression.
6447
6448    Example:
6449        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6450        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6451
6452    Args:
6453        left: the SQL code string corresponding to the left-hand side.
6454            If an `Expression` instance is passed, it will be used as-is.
6455        right: the SQL code string corresponding to the right-hand side.
6456            If an `Expression` instance is passed, it will be used as-is.
6457        distinct: set the DISTINCT flag if and only if this is true.
6458        dialect: the dialect used to parse the input expression.
6459        copy: whether to copy the expression.
6460        opts: other options to use to parse the input expressions.
6461
6462    Returns:
6463        The new Except instance.
6464    """
6465    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6466    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6467
6468    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:
6471def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6472    """
6473    Initializes a syntax tree from one or multiple SELECT expressions.
6474
6475    Example:
6476        >>> select("col1", "col2").from_("tbl").sql()
6477        'SELECT col1, col2 FROM tbl'
6478
6479    Args:
6480        *expressions: the SQL code string to parse as the expressions of a
6481            SELECT statement. If an Expression instance is passed, this is used as-is.
6482        dialect: the dialect used to parse the input expressions (in the case that an
6483            input expression is a SQL string).
6484        **opts: other options to use to parse the input expressions (again, in the case
6485            that an input expression is a SQL string).
6486
6487    Returns:
6488        Select: the syntax tree for the SELECT statement.
6489    """
6490    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:
6493def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6494    """
6495    Initializes a syntax tree from a FROM expression.
6496
6497    Example:
6498        >>> from_("tbl").select("col1", "col2").sql()
6499        'SELECT col1, col2 FROM tbl'
6500
6501    Args:
6502        *expression: the SQL code string to parse as the FROM expressions of a
6503            SELECT statement. If an Expression instance is passed, this is used as-is.
6504        dialect: the dialect used to parse the input expression (in the case that the
6505            input expression is a SQL string).
6506        **opts: other options to use to parse the input expressions (again, in the case
6507            that the input expression is a SQL string).
6508
6509    Returns:
6510        Select: the syntax tree for the SELECT statement.
6511    """
6512    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:
6515def update(
6516    table: str | Table,
6517    properties: dict,
6518    where: t.Optional[ExpOrStr] = None,
6519    from_: t.Optional[ExpOrStr] = None,
6520    dialect: DialectType = None,
6521    **opts,
6522) -> Update:
6523    """
6524    Creates an update statement.
6525
6526    Example:
6527        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6528        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6529
6530    Args:
6531        *properties: dictionary of properties to set which are
6532            auto converted to sql objects eg None -> NULL
6533        where: sql conditional parsed into a WHERE statement
6534        from_: sql statement parsed into a FROM statement
6535        dialect: the dialect used to parse the input expressions.
6536        **opts: other options to use to parse the input expressions.
6537
6538    Returns:
6539        Update: the syntax tree for the UPDATE statement.
6540    """
6541    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6542    update_expr.set(
6543        "expressions",
6544        [
6545            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6546            for k, v in properties.items()
6547        ],
6548    )
6549    if from_:
6550        update_expr.set(
6551            "from",
6552            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6553        )
6554    if isinstance(where, Condition):
6555        where = Where(this=where)
6556    if where:
6557        update_expr.set(
6558            "where",
6559            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6560        )
6561    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:
6564def delete(
6565    table: ExpOrStr,
6566    where: t.Optional[ExpOrStr] = None,
6567    returning: t.Optional[ExpOrStr] = None,
6568    dialect: DialectType = None,
6569    **opts,
6570) -> Delete:
6571    """
6572    Builds a delete statement.
6573
6574    Example:
6575        >>> delete("my_table", where="id > 1").sql()
6576        'DELETE FROM my_table WHERE id > 1'
6577
6578    Args:
6579        where: sql conditional parsed into a WHERE statement
6580        returning: sql conditional parsed into a RETURNING statement
6581        dialect: the dialect used to parse the input expressions.
6582        **opts: other options to use to parse the input expressions.
6583
6584    Returns:
6585        Delete: the syntax tree for the DELETE statement.
6586    """
6587    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6588    if where:
6589        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6590    if returning:
6591        delete_expr = t.cast(
6592            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6593        )
6594    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:
6597def insert(
6598    expression: ExpOrStr,
6599    into: ExpOrStr,
6600    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6601    overwrite: t.Optional[bool] = None,
6602    returning: t.Optional[ExpOrStr] = None,
6603    dialect: DialectType = None,
6604    copy: bool = True,
6605    **opts,
6606) -> Insert:
6607    """
6608    Builds an INSERT statement.
6609
6610    Example:
6611        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6612        'INSERT INTO tbl VALUES (1, 2, 3)'
6613
6614    Args:
6615        expression: the sql string or expression of the INSERT statement
6616        into: the tbl to insert data to.
6617        columns: optionally the table's column names.
6618        overwrite: whether to INSERT OVERWRITE or not.
6619        returning: sql conditional parsed into a RETURNING statement
6620        dialect: the dialect used to parse the input expressions.
6621        copy: whether to copy the expression.
6622        **opts: other options to use to parse the input expressions.
6623
6624    Returns:
6625        Insert: the syntax tree for the INSERT statement.
6626    """
6627    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6628    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6629
6630    if columns:
6631        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6632
6633    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6634
6635    if returning:
6636        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6637
6638    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:
6641def condition(
6642    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6643) -> Condition:
6644    """
6645    Initialize a logical condition expression.
6646
6647    Example:
6648        >>> condition("x=1").sql()
6649        'x = 1'
6650
6651        This is helpful for composing larger logical syntax trees:
6652        >>> where = condition("x=1")
6653        >>> where = where.and_("y=1")
6654        >>> Select().from_("tbl").select("*").where(where).sql()
6655        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6656
6657    Args:
6658        *expression: the SQL code string to parse.
6659            If an Expression instance is passed, this is used as-is.
6660        dialect: the dialect used to parse the input expression (in the case that the
6661            input expression is a SQL string).
6662        copy: Whether to copy `expression` (only applies to expressions).
6663        **opts: other options to use to parse the input expressions (again, in the case
6664            that the input expression is a SQL string).
6665
6666    Returns:
6667        The new Condition instance
6668    """
6669    return maybe_parse(
6670        expression,
6671        into=Condition,
6672        dialect=dialect,
6673        copy=copy,
6674        **opts,
6675    )

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:
6678def and_(
6679    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6680) -> Condition:
6681    """
6682    Combine multiple conditions with an AND logical operator.
6683
6684    Example:
6685        >>> and_("x=1", and_("y=1", "z=1")).sql()
6686        'x = 1 AND (y = 1 AND z = 1)'
6687
6688    Args:
6689        *expressions: the SQL code strings to parse.
6690            If an Expression instance is passed, this is used as-is.
6691        dialect: the dialect used to parse the input expression.
6692        copy: whether to copy `expressions` (only applies to Expressions).
6693        **opts: other options to use to parse the input expressions.
6694
6695    Returns:
6696        The new condition
6697    """
6698    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:
6701def or_(
6702    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6703) -> Condition:
6704    """
6705    Combine multiple conditions with an OR logical operator.
6706
6707    Example:
6708        >>> or_("x=1", or_("y=1", "z=1")).sql()
6709        'x = 1 OR (y = 1 OR z = 1)'
6710
6711    Args:
6712        *expressions: the SQL code strings to parse.
6713            If an Expression instance is passed, this is used as-is.
6714        dialect: the dialect used to parse the input expression.
6715        copy: whether to copy `expressions` (only applies to Expressions).
6716        **opts: other options to use to parse the input expressions.
6717
6718    Returns:
6719        The new condition
6720    """
6721    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:
6724def xor(
6725    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6726) -> Condition:
6727    """
6728    Combine multiple conditions with an XOR logical operator.
6729
6730    Example:
6731        >>> xor("x=1", xor("y=1", "z=1")).sql()
6732        'x = 1 XOR (y = 1 XOR z = 1)'
6733
6734    Args:
6735        *expressions: the SQL code strings to parse.
6736            If an Expression instance is passed, this is used as-is.
6737        dialect: the dialect used to parse the input expression.
6738        copy: whether to copy `expressions` (only applies to Expressions).
6739        **opts: other options to use to parse the input expressions.
6740
6741    Returns:
6742        The new condition
6743    """
6744    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:
6747def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6748    """
6749    Wrap a condition with a NOT operator.
6750
6751    Example:
6752        >>> not_("this_suit='black'").sql()
6753        "NOT this_suit = 'black'"
6754
6755    Args:
6756        expression: the SQL code string to parse.
6757            If an Expression instance is passed, this is used as-is.
6758        dialect: the dialect used to parse the input expression.
6759        copy: whether to copy the expression or not.
6760        **opts: other options to use to parse the input expressions.
6761
6762    Returns:
6763        The new condition.
6764    """
6765    this = condition(
6766        expression,
6767        dialect=dialect,
6768        copy=copy,
6769        **opts,
6770    )
6771    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:
6774def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6775    """
6776    Wrap an expression in parentheses.
6777
6778    Example:
6779        >>> paren("5 + 3").sql()
6780        '(5 + 3)'
6781
6782    Args:
6783        expression: the SQL code string to parse.
6784            If an Expression instance is passed, this is used as-is.
6785        copy: whether to copy the expression or not.
6786
6787    Returns:
6788        The wrapped expression.
6789    """
6790    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):
6806def to_identifier(name, quoted=None, copy=True):
6807    """Builds an identifier.
6808
6809    Args:
6810        name: The name to turn into an identifier.
6811        quoted: Whether to force quote the identifier.
6812        copy: Whether to copy name if it's an Identifier.
6813
6814    Returns:
6815        The identifier ast node.
6816    """
6817
6818    if name is None:
6819        return None
6820
6821    if isinstance(name, Identifier):
6822        identifier = maybe_copy(name, copy)
6823    elif isinstance(name, str):
6824        identifier = Identifier(
6825            this=name,
6826            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6827        )
6828    else:
6829        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6830    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:
6833def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6834    """
6835    Parses a given string into an identifier.
6836
6837    Args:
6838        name: The name to parse into an identifier.
6839        dialect: The dialect to parse against.
6840
6841    Returns:
6842        The identifier ast node.
6843    """
6844    try:
6845        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6846    except ParseError:
6847        expression = to_identifier(name)
6848
6849    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:
6855def to_interval(interval: str | Literal) -> Interval:
6856    """Builds an interval expression from a string like '1 day' or '5 months'."""
6857    if isinstance(interval, Literal):
6858        if not interval.is_string:
6859            raise ValueError("Invalid interval string.")
6860
6861        interval = interval.this
6862
6863    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6864
6865    if not interval_parts:
6866        raise ValueError("Invalid interval string.")
6867
6868    return Interval(
6869        this=Literal.string(interval_parts.group(1)),
6870        unit=Var(this=interval_parts.group(2).upper()),
6871    )

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:
6874def to_table(
6875    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6876) -> Table:
6877    """
6878    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6879    If a table is passed in then that table is returned.
6880
6881    Args:
6882        sql_path: a `[catalog].[schema].[table]` string.
6883        dialect: the source dialect according to which the table name will be parsed.
6884        copy: Whether to copy a table if it is passed in.
6885        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6886
6887    Returns:
6888        A table expression.
6889    """
6890    if isinstance(sql_path, Table):
6891        return maybe_copy(sql_path, copy=copy)
6892
6893    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6894
6895    for k, v in kwargs.items():
6896        table.set(k, v)
6897
6898    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:
6901def to_column(
6902    sql_path: str | Column,
6903    quoted: t.Optional[bool] = None,
6904    dialect: DialectType = None,
6905    copy: bool = True,
6906    **kwargs,
6907) -> Column:
6908    """
6909    Create a column from a `[table].[column]` sql path. Table is optional.
6910    If a column is passed in then that column is returned.
6911
6912    Args:
6913        sql_path: a `[table].[column]` string.
6914        quoted: Whether or not to force quote identifiers.
6915        dialect: the source dialect according to which the column name will be parsed.
6916        copy: Whether to copy a column if it is passed in.
6917        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6918
6919    Returns:
6920        A column expression.
6921    """
6922    if isinstance(sql_path, Column):
6923        return maybe_copy(sql_path, copy=copy)
6924
6925    try:
6926        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6927    except ParseError:
6928        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6929
6930    for k, v in kwargs.items():
6931        col.set(k, v)
6932
6933    if quoted:
6934        for i in col.find_all(Identifier):
6935            i.set("quoted", True)
6936
6937    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):
6940def alias_(
6941    expression: ExpOrStr,
6942    alias: t.Optional[str | Identifier],
6943    table: bool | t.Sequence[str | Identifier] = False,
6944    quoted: t.Optional[bool] = None,
6945    dialect: DialectType = None,
6946    copy: bool = True,
6947    **opts,
6948):
6949    """Create an Alias expression.
6950
6951    Example:
6952        >>> alias_('foo', 'bar').sql()
6953        'foo AS bar'
6954
6955        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6956        '(SELECT 1, 2) AS bar(a, b)'
6957
6958    Args:
6959        expression: the SQL code strings to parse.
6960            If an Expression instance is passed, this is used as-is.
6961        alias: the alias name to use. If the name has
6962            special characters it is quoted.
6963        table: Whether to create a table alias, can also be a list of columns.
6964        quoted: whether to quote the alias
6965        dialect: the dialect used to parse the input expression.
6966        copy: Whether to copy the expression.
6967        **opts: other options to use to parse the input expressions.
6968
6969    Returns:
6970        Alias: the aliased expression
6971    """
6972    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6973    alias = to_identifier(alias, quoted=quoted)
6974
6975    if table:
6976        table_alias = TableAlias(this=alias)
6977        exp.set("alias", table_alias)
6978
6979        if not isinstance(table, bool):
6980            for column in table:
6981                table_alias.append("columns", to_identifier(column, quoted=quoted))
6982
6983        return exp
6984
6985    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6986    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6987    # for the complete Window expression.
6988    #
6989    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6990
6991    if "alias" in exp.arg_types and not isinstance(exp, Window):
6992        exp.set("alias", alias)
6993        return exp
6994    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:
6997def subquery(
6998    expression: ExpOrStr,
6999    alias: t.Optional[Identifier | str] = None,
7000    dialect: DialectType = None,
7001    **opts,
7002) -> Select:
7003    """
7004    Build a subquery expression that's selected from.
7005
7006    Example:
7007        >>> subquery('select x from tbl', 'bar').select('x').sql()
7008        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7009
7010    Args:
7011        expression: the SQL code strings to parse.
7012            If an Expression instance is passed, this is used as-is.
7013        alias: the alias name to use.
7014        dialect: the dialect used to parse the input expression.
7015        **opts: other options to use to parse the input expressions.
7016
7017    Returns:
7018        A new Select instance with the subquery expression included.
7019    """
7020
7021    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7022    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):
7053def column(
7054    col,
7055    table=None,
7056    db=None,
7057    catalog=None,
7058    *,
7059    fields=None,
7060    quoted=None,
7061    copy=True,
7062):
7063    """
7064    Build a Column.
7065
7066    Args:
7067        col: Column name.
7068        table: Table name.
7069        db: Database name.
7070        catalog: Catalog name.
7071        fields: Additional fields using dots.
7072        quoted: Whether to force quotes on the column's identifiers.
7073        copy: Whether to copy identifiers if passed in.
7074
7075    Returns:
7076        The new Column instance.
7077    """
7078    this = Column(
7079        this=to_identifier(col, quoted=quoted, copy=copy),
7080        table=to_identifier(table, quoted=quoted, copy=copy),
7081        db=to_identifier(db, quoted=quoted, copy=copy),
7082        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7083    )
7084
7085    if fields:
7086        this = Dot.build(
7087            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7088        )
7089    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:
7092def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7093    """Cast an expression to a data type.
7094
7095    Example:
7096        >>> cast('x + 1', 'int').sql()
7097        'CAST(x + 1 AS INT)'
7098
7099    Args:
7100        expression: The expression to cast.
7101        to: The datatype to cast to.
7102        copy: Whether to copy the supplied expressions.
7103
7104    Returns:
7105        The new Cast instance.
7106    """
7107    expr = maybe_parse(expression, copy=copy, **opts)
7108    data_type = DataType.build(to, copy=copy, **opts)
7109
7110    if expr.is_type(data_type):
7111        return expr
7112
7113    expr = Cast(this=expr, to=data_type)
7114    expr.type = data_type
7115
7116    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:
7119def table_(
7120    table: Identifier | str,
7121    db: t.Optional[Identifier | str] = None,
7122    catalog: t.Optional[Identifier | str] = None,
7123    quoted: t.Optional[bool] = None,
7124    alias: t.Optional[Identifier | str] = None,
7125) -> Table:
7126    """Build a Table.
7127
7128    Args:
7129        table: Table name.
7130        db: Database name.
7131        catalog: Catalog name.
7132        quote: Whether to force quotes on the table's identifiers.
7133        alias: Table's alias.
7134
7135    Returns:
7136        The new Table instance.
7137    """
7138    return Table(
7139        this=to_identifier(table, quoted=quoted) if table else None,
7140        db=to_identifier(db, quoted=quoted) if db else None,
7141        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7142        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7143    )

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:
7146def values(
7147    values: t.Iterable[t.Tuple[t.Any, ...]],
7148    alias: t.Optional[str] = None,
7149    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7150) -> Values:
7151    """Build VALUES statement.
7152
7153    Example:
7154        >>> values([(1, '2')]).sql()
7155        "VALUES (1, '2')"
7156
7157    Args:
7158        values: values statements that will be converted to SQL
7159        alias: optional alias
7160        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7161         If either are provided then an alias is also required.
7162
7163    Returns:
7164        Values: the Values expression object
7165    """
7166    if columns and not alias:
7167        raise ValueError("Alias is required when providing columns")
7168
7169    return Values(
7170        expressions=[convert(tup) for tup in values],
7171        alias=(
7172            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7173            if columns
7174            else (TableAlias(this=to_identifier(alias)) if alias else None)
7175        ),
7176    )

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:
7179def var(name: t.Optional[ExpOrStr]) -> Var:
7180    """Build a SQL variable.
7181
7182    Example:
7183        >>> repr(var('x'))
7184        'Var(this=x)'
7185
7186        >>> repr(var(column('x', table='y')))
7187        'Var(this=x)'
7188
7189    Args:
7190        name: The name of the var or an expression who's name will become the var.
7191
7192    Returns:
7193        The new variable node.
7194    """
7195    if not name:
7196        raise ValueError("Cannot convert empty name into var.")
7197
7198    if isinstance(name, Expression):
7199        name = name.name
7200    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:
7203def rename_table(
7204    old_name: str | Table,
7205    new_name: str | Table,
7206    dialect: DialectType = None,
7207) -> AlterTable:
7208    """Build ALTER TABLE... RENAME... expression
7209
7210    Args:
7211        old_name: The old name of the table
7212        new_name: The new name of the table
7213        dialect: The dialect to parse the table.
7214
7215    Returns:
7216        Alter table expression
7217    """
7218    old_table = to_table(old_name, dialect=dialect)
7219    new_table = to_table(new_name, dialect=dialect)
7220    return AlterTable(
7221        this=old_table,
7222        actions=[
7223            RenameTable(this=new_table),
7224        ],
7225    )

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:
7228def rename_column(
7229    table_name: str | Table,
7230    old_column_name: str | Column,
7231    new_column_name: str | Column,
7232    exists: t.Optional[bool] = None,
7233    dialect: DialectType = None,
7234) -> AlterTable:
7235    """Build ALTER TABLE... RENAME COLUMN... expression
7236
7237    Args:
7238        table_name: Name of the table
7239        old_column: The old name of the column
7240        new_column: The new name of the column
7241        exists: Whether to add the `IF EXISTS` clause
7242        dialect: The dialect to parse the table/column.
7243
7244    Returns:
7245        Alter table expression
7246    """
7247    table = to_table(table_name, dialect=dialect)
7248    old_column = to_column(old_column_name, dialect=dialect)
7249    new_column = to_column(new_column_name, dialect=dialect)
7250    return AlterTable(
7251        this=table,
7252        actions=[
7253            RenameColumn(this=old_column, to=new_column, exists=exists),
7254        ],
7255    )

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

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:
7389def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7390    """Get the full name of a table as a string.
7391
7392    Args:
7393        table: Table expression node or string.
7394        dialect: The dialect to generate the table name for.
7395        identify: Determines when an identifier should be quoted. Possible values are:
7396            False (default): Never quote, except in cases where it's mandatory by the dialect.
7397            True: Always quote.
7398
7399    Examples:
7400        >>> from sqlglot import exp, parse_one
7401        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7402        'a.b.c'
7403
7404    Returns:
7405        The table name.
7406    """
7407
7408    table = maybe_parse(table, into=Table, dialect=dialect)
7409
7410    if not table:
7411        raise ValueError(f"Cannot parse {table}")
7412
7413    return ".".join(
7414        (
7415            part.sql(dialect=dialect, identify=True, copy=False)
7416            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7417            else part.name
7418        )
7419        for part in table.parts
7420    )

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:
7423def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7424    """Returns a case normalized table name without quotes.
7425
7426    Args:
7427        table: the table to normalize
7428        dialect: the dialect to use for normalization rules
7429        copy: whether to copy the expression.
7430
7431    Examples:
7432        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7433        'A-B.c'
7434    """
7435    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7436
7437    return ".".join(
7438        p.name
7439        for p in normalize_identifiers(
7440            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7441        ).parts
7442    )

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

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:
7672def tuple_(
7673    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7674) -> Tuple:
7675    """
7676    Returns an tuple.
7677
7678    Examples:
7679        >>> tuple_(1, 'x').sql()
7680        '(1, x)'
7681
7682    Args:
7683        expressions: the expressions to add to the tuple.
7684        copy: whether to copy the argument expressions.
7685        dialect: the source dialect.
7686        kwargs: the kwargs used to instantiate the function of interest.
7687
7688    Returns:
7689        A tuple expression.
7690    """
7691    return Tuple(
7692        expressions=[
7693            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7694            for expression in expressions
7695        ]
7696    )

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:
7699def true() -> Boolean:
7700    """
7701    Returns a true Boolean expression.
7702    """
7703    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7706def false() -> Boolean:
7707    """
7708    Returns a false Boolean expression.
7709    """
7710    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7713def null() -> Null:
7714    """
7715    Returns a Null expression.
7716    """
7717    return Null()

Returns a Null expression.

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