Edit on GitHub

Expressions

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

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


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

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

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

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

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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

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

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

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

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Checks whether an expression is negative.

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

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

Checks whether a Literal expression is an integer.

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

Checks whether an expression is a star.

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

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

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

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

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

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

Returns a deep copy of the expression.

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

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

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

Sets arg_key to value.

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

Returns the depth of this tree.

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

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

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

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

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

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

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

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

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

The generator object.

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

Returns a nearest parent matching expression_types.

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

The parent node.

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

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

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

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

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

the generator object.

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

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

Returns:

The generator object.

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

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

Returns:

The generator object.

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

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

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

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

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

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

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

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

Returns SQL string representation of this tree.

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

The SQL string.

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

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

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

The transformed tree.

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

Swap out this expression with a new expression.

For example::

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

The new expression or expressions.

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Assert that this Expression is an instance of type_.

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

Examples:

This is useful for type security in chained expressions:

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

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

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

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

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

Dump this Expression to a JSON-serializable dict.

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

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

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

AND this condition with one or multiple expressions.

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

The new And condition.

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

OR this condition with one or multiple expressions.

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

The new Or condition.

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

Wrap this condition with NOT.

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

The new Not instance.

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

Logical conditions like x AND y, or simply x

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

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

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

Returns a Subquery that wraps around this query.

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

Adds a LIMIT clause to this query.

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

A limited Select expression.

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

Set the OFFSET expression.

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

The modified Select expression.

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

Set the ORDER BY expression.

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

The modified Select expression.

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

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

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

Returns the query's projections.

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

Returns the output names of the query's projections.

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

Append to or set the SELECT expressions.

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

The modified Query expression.

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

Append to or set the common table expressions.

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

The modified expression.

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

Builds a UNION expression.

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

The new Union expression.

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

Builds an INTERSECT expression.

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

The new Intersect expression.

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

Builds an EXCEPT expression.

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

The new Except expression.

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

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

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

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

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

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

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

Set the RETURNING expression. Not supported by all dialects.

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

Delete: the modified expression.

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

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

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

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

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

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

Converts the column into a dot expression.

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

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

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

Delete: the modified expression.

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

Append to or set the WHERE expressions.

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

Delete: the modified expression.

key = 'delete'
class Drop(Expression):
1984class Drop(Expression):
1985    arg_types = {
1986        "this": False,
1987        "kind": False,
1988        "expressions": False,
1989        "exists": False,
1990        "temporary": False,
1991        "materialized": False,
1992        "cascade": False,
1993        "constraints": False,
1994        "purge": False,
1995        "cluster": False,
1996    }
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False}
key = 'drop'
class Filter(Expression):
1999class Filter(Expression):
2000    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2003class Check(Expression):
2004    pass
key = 'check'
class Connect(Expression):
2008class Connect(Expression):
2009    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2012class CopyParameter(Expression):
2013    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(Expression):
2016class Copy(Expression):
2017    arg_types = {
2018        "this": True,
2019        "kind": True,
2020        "files": True,
2021        "credentials": False,
2022        "format": False,
2023        "params": False,
2024    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2027class Credentials(Expression):
2028    arg_types = {
2029        "credentials": False,
2030        "encryption": False,
2031        "storage": False,
2032        "iam_role": False,
2033        "region": False,
2034    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2037class Prior(Expression):
2038    pass
key = 'prior'
class Directory(Expression):
2041class Directory(Expression):
2042    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2043    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2046class ForeignKey(Expression):
2047    arg_types = {
2048        "expressions": True,
2049        "reference": False,
2050        "delete": False,
2051        "update": False,
2052    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2055class ColumnPrefix(Expression):
2056    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2059class PrimaryKey(Expression):
2060    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2065class Into(Expression):
2066    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2069class From(Expression):
2070    @property
2071    def name(self) -> str:
2072        return self.this.name
2073
2074    @property
2075    def alias_or_name(self) -> str:
2076        return self.this.alias_or_name
name: str
2070    @property
2071    def name(self) -> str:
2072        return self.this.name
alias_or_name: str
2074    @property
2075    def alias_or_name(self) -> str:
2076        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2079class Having(Expression):
2080    pass
key = 'having'
class Hint(Expression):
2083class Hint(Expression):
2084    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2087class JoinHint(Expression):
2088    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2091class Identifier(Expression):
2092    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2093
2094    @property
2095    def quoted(self) -> bool:
2096        return bool(self.args.get("quoted"))
2097
2098    @property
2099    def hashable_args(self) -> t.Any:
2100        return (self.this, self.quoted)
2101
2102    @property
2103    def output_name(self) -> str:
2104        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2094    @property
2095    def quoted(self) -> bool:
2096        return bool(self.args.get("quoted"))
hashable_args: Any
2098    @property
2099    def hashable_args(self) -> t.Any:
2100        return (self.this, self.quoted)
output_name: str
2102    @property
2103    def output_name(self) -> str:
2104        return self.name

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

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

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

Append to or set the common table expressions.

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

The modified expression.

key = 'insert'
class OnConflict(Expression):
2191class OnConflict(Expression):
2192    arg_types = {
2193        "duplicate": False,
2194        "expressions": False,
2195        "action": False,
2196        "conflict_keys": False,
2197        "constraint": False,
2198    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2201class Returning(Expression):
2202    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2206class Introducer(Expression):
2207    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2211class National(Expression):
2212    pass
key = 'national'
class LoadData(Expression):
2215class LoadData(Expression):
2216    arg_types = {
2217        "this": True,
2218        "local": False,
2219        "overwrite": False,
2220        "inpath": True,
2221        "partition": False,
2222        "input_format": False,
2223        "serde": False,
2224    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2227class Partition(Expression):
2228    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2231class PartitionRange(Expression):
2232    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2236class PartitionId(Expression):
2237    pass
key = 'partitionid'
class Fetch(Expression):
2240class Fetch(Expression):
2241    arg_types = {
2242        "direction": False,
2243        "count": False,
2244        "percent": False,
2245        "with_ties": False,
2246    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2249class Group(Expression):
2250    arg_types = {
2251        "expressions": False,
2252        "grouping_sets": False,
2253        "cube": False,
2254        "rollup": False,
2255        "totals": False,
2256        "all": False,
2257    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2260class Lambda(Expression):
2261    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2264class Limit(Expression):
2265    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
arg_types = {'this': False, 'expression': True, 'offset': False, 'expressions': False}
key = 'limit'
class Literal(Condition):
2268class Literal(Condition):
2269    arg_types = {"this": True, "is_string": True}
2270
2271    @property
2272    def hashable_args(self) -> t.Any:
2273        return (self.this, self.args.get("is_string"))
2274
2275    @classmethod
2276    def number(cls, number) -> Literal:
2277        return cls(this=str(number), is_string=False)
2278
2279    @classmethod
2280    def string(cls, string) -> Literal:
2281        return cls(this=str(string), is_string=True)
2282
2283    @property
2284    def output_name(self) -> str:
2285        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2271    @property
2272    def hashable_args(self) -> t.Any:
2273        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2275    @classmethod
2276    def number(cls, number) -> Literal:
2277        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2279    @classmethod
2280    def string(cls, string) -> Literal:
2281        return cls(this=str(string), is_string=True)
output_name: str
2283    @property
2284    def output_name(self) -> str:
2285        return self.name

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

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

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

Append to or set the ON expressions.

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

The modified Join expression.

def using( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2365    def using(
2366        self,
2367        *expressions: t.Optional[ExpOrStr],
2368        append: bool = True,
2369        dialect: DialectType = None,
2370        copy: bool = True,
2371        **opts,
2372    ) -> Join:
2373        """
2374        Append to or set the USING expressions.
2375
2376        Example:
2377            >>> import sqlglot
2378            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2379            'JOIN x USING (foo, bla)'
2380
2381        Args:
2382            *expressions: the SQL code strings to parse.
2383                If an `Expression` instance is passed, it will be used as-is.
2384            append: if `True`, concatenate the new expressions to the existing "using" list.
2385                Otherwise, this resets the expression.
2386            dialect: the dialect used to parse the input expressions.
2387            copy: if `False`, modify this expression instance in-place.
2388            opts: other options to use to parse the input expressions.
2389
2390        Returns:
2391            The modified Join expression.
2392        """
2393        join = _apply_list_builder(
2394            *expressions,
2395            instance=self,
2396            arg="using",
2397            append=append,
2398            dialect=dialect,
2399            copy=copy,
2400            **opts,
2401        )
2402
2403        if join.kind == "CROSS":
2404            join.set("kind", None)
2405
2406        return join

Append to or set the USING expressions.

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

The modified Join expression.

key = 'join'
class Lateral(UDTF):
2409class Lateral(UDTF):
2410    arg_types = {
2411        "this": True,
2412        "view": False,
2413        "outer": False,
2414        "alias": False,
2415        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2416    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2419class MatchRecognizeMeasure(Expression):
2420    arg_types = {
2421        "this": True,
2422        "window_frame": False,
2423    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2426class MatchRecognize(Expression):
2427    arg_types = {
2428        "partition_by": False,
2429        "order": False,
2430        "measures": False,
2431        "rows": False,
2432        "after": False,
2433        "pattern": False,
2434        "define": False,
2435        "alias": False,
2436    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2441class Final(Expression):
2442    pass
key = 'final'
class Offset(Expression):
2445class Offset(Expression):
2446    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2449class Order(Expression):
2450    arg_types = {
2451        "this": False,
2452        "expressions": True,
2453        "interpolate": False,
2454        "siblings": False,
2455    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2459class WithFill(Expression):
2460    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2465class Cluster(Order):
2466    pass
key = 'cluster'
class Distribute(Order):
2469class Distribute(Order):
2470    pass
key = 'distribute'
class Sort(Order):
2473class Sort(Order):
2474    pass
key = 'sort'
class Ordered(Expression):
2477class Ordered(Expression):
2478    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
key = 'ordered'
class Property(Expression):
2481class Property(Expression):
2482    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2485class AllowedValuesProperty(Expression):
2486    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2489class AlgorithmProperty(Property):
2490    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2493class AutoIncrementProperty(Property):
2494    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2498class AutoRefreshProperty(Property):
2499    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2502class BackupProperty(Property):
2503    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2506class BlockCompressionProperty(Property):
2507    arg_types = {
2508        "autotemp": False,
2509        "always": False,
2510        "default": False,
2511        "manual": False,
2512        "never": False,
2513    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2516class CharacterSetProperty(Property):
2517    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2520class ChecksumProperty(Property):
2521    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2524class CollateProperty(Property):
2525    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2528class CopyGrantsProperty(Property):
2529    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2532class DataBlocksizeProperty(Property):
2533    arg_types = {
2534        "size": False,
2535        "units": False,
2536        "minimum": False,
2537        "maximum": False,
2538        "default": False,
2539    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2542class DataDeletionProperty(Property):
2543    arg_types = {"on": True, "filter_col": False, "retention_period": False}
arg_types = {'on': True, 'filter_col': False, 'retention_period': False}
key = 'datadeletionproperty'
class DefinerProperty(Property):
2546class DefinerProperty(Property):
2547    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2550class DistKeyProperty(Property):
2551    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2554class DistStyleProperty(Property):
2555    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2558class EngineProperty(Property):
2559    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2562class HeapProperty(Property):
2563    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2566class ToTableProperty(Property):
2567    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2570class ExecuteAsProperty(Property):
2571    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2574class ExternalProperty(Property):
2575    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2578class FallbackProperty(Property):
2579    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2582class FileFormatProperty(Property):
2583    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2586class FreespaceProperty(Property):
2587    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2590class GlobalProperty(Property):
2591    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2594class IcebergProperty(Property):
2595    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2598class InheritsProperty(Property):
2599    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2602class InputModelProperty(Property):
2603    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2606class OutputModelProperty(Property):
2607    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2610class IsolatedLoadingProperty(Property):
2611    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2614class JournalProperty(Property):
2615    arg_types = {
2616        "no": False,
2617        "dual": False,
2618        "before": False,
2619        "local": False,
2620        "after": False,
2621    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2624class LanguageProperty(Property):
2625    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2629class ClusteredByProperty(Property):
2630    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2633class DictProperty(Property):
2634    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2637class DictSubProperty(Property):
2638    pass
key = 'dictsubproperty'
class DictRange(Property):
2641class DictRange(Property):
2642    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2647class OnCluster(Property):
2648    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2651class LikeProperty(Property):
2652    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2655class LocationProperty(Property):
2656    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2659class LockProperty(Property):
2660    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2663class LockingProperty(Property):
2664    arg_types = {
2665        "this": False,
2666        "kind": True,
2667        "for_or_in": False,
2668        "lock_type": True,
2669        "override": False,
2670    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2673class LogProperty(Property):
2674    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2677class MaterializedProperty(Property):
2678    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2681class MergeBlockRatioProperty(Property):
2682    arg_types = {"this": False, "no": False, "default": False, "percent": False}
arg_types = {'this': False, 'no': False, 'default': False, 'percent': False}
key = 'mergeblockratioproperty'
class NoPrimaryIndexProperty(Property):
2685class NoPrimaryIndexProperty(Property):
2686    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2689class OnProperty(Property):
2690    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2693class OnCommitProperty(Property):
2694    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2697class PartitionedByProperty(Property):
2698    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2702class PartitionBoundSpec(Expression):
2703    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2704    arg_types = {
2705        "this": False,
2706        "expression": False,
2707        "from_expressions": False,
2708        "to_expressions": False,
2709    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2712class PartitionedOfProperty(Property):
2713    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2714    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2717class RemoteWithConnectionModelProperty(Property):
2718    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2721class ReturnsProperty(Property):
2722    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
arg_types = {'this': False, 'is_table': False, 'table': False, 'null': False}
key = 'returnsproperty'
class StrictProperty(Property):
2725class StrictProperty(Property):
2726    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2729class RowFormatProperty(Property):
2730    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2733class RowFormatDelimitedProperty(Property):
2734    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2735    arg_types = {
2736        "fields": False,
2737        "escaped": False,
2738        "collection_items": False,
2739        "map_keys": False,
2740        "lines": False,
2741        "null": False,
2742        "serde": False,
2743    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2746class RowFormatSerdeProperty(Property):
2747    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2751class QueryTransform(Expression):
2752    arg_types = {
2753        "expressions": True,
2754        "command_script": True,
2755        "schema": False,
2756        "row_format_before": False,
2757        "record_writer": False,
2758        "row_format_after": False,
2759        "record_reader": False,
2760    }
arg_types = {'expressions': True, 'command_script': True, 'schema': False, 'row_format_before': False, 'record_writer': False, 'row_format_after': False, 'record_reader': False}
key = 'querytransform'
class SampleProperty(Property):
2763class SampleProperty(Property):
2764    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2767class SchemaCommentProperty(Property):
2768    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2771class SerdeProperties(Property):
2772    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2775class SetProperty(Property):
2776    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2779class SharingProperty(Property):
2780    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2783class SetConfigProperty(Property):
2784    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2787class SettingsProperty(Property):
2788    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2791class SortKeyProperty(Property):
2792    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2795class SqlReadWriteProperty(Property):
2796    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2799class SqlSecurityProperty(Property):
2800    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2803class StabilityProperty(Property):
2804    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2807class TemporaryProperty(Property):
2808    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2811class SecureProperty(Property):
2812    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2815class TransformModelProperty(Property):
2816    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2819class TransientProperty(Property):
2820    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2823class UnloggedProperty(Property):
2824    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2828class ViewAttributeProperty(Property):
2829    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2832class VolatileProperty(Property):
2833    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2836class WithDataProperty(Property):
2837    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2840class WithJournalTableProperty(Property):
2841    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2844class WithSystemVersioningProperty(Property):
2845    arg_types = {
2846        "on": False,
2847        "this": False,
2848        "data_consistency": False,
2849        "retention_period": False,
2850        "with": True,
2851    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2854class Properties(Expression):
2855    arg_types = {"expressions": True}
2856
2857    NAME_TO_PROPERTY = {
2858        "ALGORITHM": AlgorithmProperty,
2859        "AUTO_INCREMENT": AutoIncrementProperty,
2860        "CHARACTER SET": CharacterSetProperty,
2861        "CLUSTERED_BY": ClusteredByProperty,
2862        "COLLATE": CollateProperty,
2863        "COMMENT": SchemaCommentProperty,
2864        "DEFINER": DefinerProperty,
2865        "DISTKEY": DistKeyProperty,
2866        "DISTSTYLE": DistStyleProperty,
2867        "ENGINE": EngineProperty,
2868        "EXECUTE AS": ExecuteAsProperty,
2869        "FORMAT": FileFormatProperty,
2870        "LANGUAGE": LanguageProperty,
2871        "LOCATION": LocationProperty,
2872        "LOCK": LockProperty,
2873        "PARTITIONED_BY": PartitionedByProperty,
2874        "RETURNS": ReturnsProperty,
2875        "ROW_FORMAT": RowFormatProperty,
2876        "SORTKEY": SortKeyProperty,
2877    }
2878
2879    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2880
2881    # CREATE property locations
2882    # Form: schema specified
2883    #   create [POST_CREATE]
2884    #     table a [POST_NAME]
2885    #     (b int) [POST_SCHEMA]
2886    #     with ([POST_WITH])
2887    #     index (b) [POST_INDEX]
2888    #
2889    # Form: alias selection
2890    #   create [POST_CREATE]
2891    #     table a [POST_NAME]
2892    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2893    #     index (c) [POST_INDEX]
2894    class Location(AutoName):
2895        POST_CREATE = auto()
2896        POST_NAME = auto()
2897        POST_SCHEMA = auto()
2898        POST_WITH = auto()
2899        POST_ALIAS = auto()
2900        POST_EXPRESSION = auto()
2901        POST_INDEX = auto()
2902        UNSUPPORTED = auto()
2903
2904    @classmethod
2905    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2906        expressions = []
2907        for key, value in properties_dict.items():
2908            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2909            if property_cls:
2910                expressions.append(property_cls(this=convert(value)))
2911            else:
2912                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2913
2914        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:
2904    @classmethod
2905    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2906        expressions = []
2907        for key, value in properties_dict.items():
2908            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2909            if property_cls:
2910                expressions.append(property_cls(this=convert(value)))
2911            else:
2912                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2913
2914        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2894    class Location(AutoName):
2895        POST_CREATE = auto()
2896        POST_NAME = auto()
2897        POST_SCHEMA = auto()
2898        POST_WITH = auto()
2899        POST_ALIAS = auto()
2900        POST_EXPRESSION = auto()
2901        POST_INDEX = auto()
2902        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):
2917class Qualify(Expression):
2918    pass
key = 'qualify'
class InputOutputFormat(Expression):
2921class InputOutputFormat(Expression):
2922    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2926class Return(Expression):
2927    pass
key = 'return'
class Reference(Expression):
2930class Reference(Expression):
2931    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2934class Tuple(Expression):
2935    arg_types = {"expressions": False}
2936
2937    def isin(
2938        self,
2939        *expressions: t.Any,
2940        query: t.Optional[ExpOrStr] = None,
2941        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2942        copy: bool = True,
2943        **opts,
2944    ) -> In:
2945        return In(
2946            this=maybe_copy(self, copy),
2947            expressions=[convert(e, copy=copy) for e in expressions],
2948            query=maybe_parse(query, copy=copy, **opts) if query else None,
2949            unnest=(
2950                Unnest(
2951                    expressions=[
2952                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2953                        for e in ensure_list(unnest)
2954                    ]
2955                )
2956                if unnest
2957                else None
2958            ),
2959        )
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:
2937    def isin(
2938        self,
2939        *expressions: t.Any,
2940        query: t.Optional[ExpOrStr] = None,
2941        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2942        copy: bool = True,
2943        **opts,
2944    ) -> In:
2945        return In(
2946            this=maybe_copy(self, copy),
2947            expressions=[convert(e, copy=copy) for e in expressions],
2948            query=maybe_parse(query, copy=copy, **opts) if query else None,
2949            unnest=(
2950                Unnest(
2951                    expressions=[
2952                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2953                        for e in ensure_list(unnest)
2954                    ]
2955                )
2956                if unnest
2957                else None
2958            ),
2959        )
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):
2990class QueryOption(Expression):
2991    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2995class WithTableHint(Expression):
2996    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3000class IndexTableHint(Expression):
3001    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3005class HistoricalData(Expression):
3006    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3009class Table(Expression):
3010    arg_types = {
3011        "this": False,
3012        "alias": False,
3013        "db": False,
3014        "catalog": False,
3015        "laterals": False,
3016        "joins": False,
3017        "pivots": False,
3018        "hints": False,
3019        "system_time": False,
3020        "version": False,
3021        "format": False,
3022        "pattern": False,
3023        "ordinality": False,
3024        "when": False,
3025        "only": False,
3026        "partition": False,
3027    }
3028
3029    @property
3030    def name(self) -> str:
3031        if isinstance(self.this, Func):
3032            return ""
3033        return self.this.name
3034
3035    @property
3036    def db(self) -> str:
3037        return self.text("db")
3038
3039    @property
3040    def catalog(self) -> str:
3041        return self.text("catalog")
3042
3043    @property
3044    def selects(self) -> t.List[Expression]:
3045        return []
3046
3047    @property
3048    def named_selects(self) -> t.List[str]:
3049        return []
3050
3051    @property
3052    def parts(self) -> t.List[Expression]:
3053        """Return the parts of a table in order catalog, db, table."""
3054        parts: t.List[Expression] = []
3055
3056        for arg in ("catalog", "db", "this"):
3057            part = self.args.get(arg)
3058
3059            if isinstance(part, Dot):
3060                parts.extend(part.flatten())
3061            elif isinstance(part, Expression):
3062                parts.append(part)
3063
3064        return parts
3065
3066    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3067        parts = self.parts
3068        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3069        alias = self.args.get("alias")
3070        if alias:
3071            col = alias_(col, alias.this, copy=copy)
3072        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
3029    @property
3030    def name(self) -> str:
3031        if isinstance(self.this, Func):
3032            return ""
3033        return self.this.name
db: str
3035    @property
3036    def db(self) -> str:
3037        return self.text("db")
catalog: str
3039    @property
3040    def catalog(self) -> str:
3041        return self.text("catalog")
selects: List[Expression]
3043    @property
3044    def selects(self) -> t.List[Expression]:
3045        return []
named_selects: List[str]
3047    @property
3048    def named_selects(self) -> t.List[str]:
3049        return []
parts: List[Expression]
3051    @property
3052    def parts(self) -> t.List[Expression]:
3053        """Return the parts of a table in order catalog, db, table."""
3054        parts: t.List[Expression] = []
3055
3056        for arg in ("catalog", "db", "this"):
3057            part = self.args.get(arg)
3058
3059            if isinstance(part, Dot):
3060                parts.extend(part.flatten())
3061            elif isinstance(part, Expression):
3062                parts.append(part)
3063
3064        return parts

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

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

Returns the output names of the query's projections.

is_star: bool
3104    @property
3105    def is_star(self) -> bool:
3106        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3108    @property
3109    def selects(self) -> t.List[Expression]:
3110        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3736    @property
3737    def selects(self) -> t.List[Expression]:
3738        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

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

Checks whether an expression is a star.

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

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

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

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

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

Automatically converts unit arg into a var.

TimeUnit(**args)
4587    def __init__(self, **args):
4588        unit = args.get("unit")
4589        if isinstance(unit, self.VAR_LIKE):
4590            args["unit"] = Var(
4591                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4592            )
4593        elif isinstance(unit, Week):
4594            unit.set("this", Var(this=unit.this.name.upper()))
4595
4596        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]
4598    @property
4599    def unit(self) -> t.Optional[Var | IntervalSpan]:
4600        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4603class IntervalOp(TimeUnit):
4604    arg_types = {"unit": True, "expression": True}
4605
4606    def interval(self):
4607        return Interval(
4608            this=self.expression.copy(),
4609            unit=self.unit.copy(),
4610        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4606    def interval(self):
4607        return Interval(
4608            this=self.expression.copy(),
4609            unit=self.unit.copy(),
4610        )
key = 'intervalop'
class IntervalSpan(DataType):
4616class IntervalSpan(DataType):
4617    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4620class Interval(TimeUnit):
4621    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4624class IgnoreNulls(Expression):
4625    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4628class RespectNulls(Expression):
4629    pass
key = 'respectnulls'
class HavingMax(Expression):
4633class HavingMax(Expression):
4634    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4638class Func(Condition):
4639    """
4640    The base class for all function expressions.
4641
4642    Attributes:
4643        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4644            treated as a variable length argument and the argument's value will be stored as a list.
4645        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4646            function expression. These values are used to map this node to a name during parsing as
4647            well as to provide the function's name during SQL string generation. By default the SQL
4648            name is set to the expression's class name transformed to snake case.
4649    """
4650
4651    is_var_len_args = False
4652
4653    @classmethod
4654    def from_arg_list(cls, args):
4655        if cls.is_var_len_args:
4656            all_arg_keys = list(cls.arg_types)
4657            # If this function supports variable length argument treat the last argument as such.
4658            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4659            num_non_var = len(non_var_len_arg_keys)
4660
4661            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4662            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4663        else:
4664            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4665
4666        return cls(**args_dict)
4667
4668    @classmethod
4669    def sql_names(cls):
4670        if cls is Func:
4671            raise NotImplementedError(
4672                "SQL name is only supported by concrete function implementations"
4673            )
4674        if "_sql_names" not in cls.__dict__:
4675            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4676        return cls._sql_names
4677
4678    @classmethod
4679    def sql_name(cls):
4680        return cls.sql_names()[0]
4681
4682    @classmethod
4683    def default_parser_mappings(cls):
4684        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):
4653    @classmethod
4654    def from_arg_list(cls, args):
4655        if cls.is_var_len_args:
4656            all_arg_keys = list(cls.arg_types)
4657            # If this function supports variable length argument treat the last argument as such.
4658            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4659            num_non_var = len(non_var_len_arg_keys)
4660
4661            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4662            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4663        else:
4664            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4665
4666        return cls(**args_dict)
@classmethod
def sql_names(cls):
4668    @classmethod
4669    def sql_names(cls):
4670        if cls is Func:
4671            raise NotImplementedError(
4672                "SQL name is only supported by concrete function implementations"
4673            )
4674        if "_sql_names" not in cls.__dict__:
4675            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4676        return cls._sql_names
@classmethod
def sql_name(cls):
4678    @classmethod
4679    def sql_name(cls):
4680        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4682    @classmethod
4683    def default_parser_mappings(cls):
4684        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4687class AggFunc(Func):
4688    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4691class ParameterizedAgg(AggFunc):
4692    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4695class Abs(Func):
4696    pass
key = 'abs'
class ArgMax(AggFunc):
4699class ArgMax(AggFunc):
4700    arg_types = {"this": True, "expression": True, "count": False}
4701    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4704class ArgMin(AggFunc):
4705    arg_types = {"this": True, "expression": True, "count": False}
4706    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4709class ApproxTopK(AggFunc):
4710    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4713class Flatten(Func):
4714    pass
key = 'flatten'
class Transform(Func):
4718class Transform(Func):
4719    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4722class Anonymous(Func):
4723    arg_types = {"this": True, "expressions": False}
4724    is_var_len_args = True
4725
4726    @property
4727    def name(self) -> str:
4728        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
4726    @property
4727    def name(self) -> str:
4728        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4731class AnonymousAggFunc(AggFunc):
4732    arg_types = {"this": True, "expressions": False}
4733    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4737class CombinedAggFunc(AnonymousAggFunc):
4738    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4741class CombinedParameterizedAgg(ParameterizedAgg):
4742    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):
4747class Hll(AggFunc):
4748    arg_types = {"this": True, "expressions": False}
4749    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4752class ApproxDistinct(AggFunc):
4753    arg_types = {"this": True, "accuracy": False}
4754    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4757class Array(Func):
4758    arg_types = {"expressions": False}
4759    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4763class ToArray(Func):
4764    pass
key = 'toarray'
class List(Func):
4768class List(Func):
4769    arg_types = {"expressions": False}
4770    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class ToChar(Func):
4775class ToChar(Func):
4776    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4781class ToNumber(Func):
4782    arg_types = {
4783        "this": True,
4784        "format": False,
4785        "nlsparam": False,
4786        "precision": False,
4787        "scale": False,
4788    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4792class Convert(Func):
4793    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4796class GenerateSeries(Func):
4797    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):
4800class ArrayAgg(AggFunc):
4801    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4804class ArrayUniqueAgg(AggFunc):
4805    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4808class ArrayAll(Func):
4809    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4813class ArrayAny(Func):
4814    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4817class ArrayConcat(Func):
4818    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4819    arg_types = {"this": True, "expressions": False}
4820    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4823class ArrayConstructCompact(Func):
4824    arg_types = {"expressions": True}
4825    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4828class ArrayContains(Binary, Func):
4829    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4832class ArrayContainsAll(Binary, Func):
4833    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4836class ArrayFilter(Func):
4837    arg_types = {"this": True, "expression": True}
4838    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4841class ArrayToString(Func):
4842    arg_types = {"this": True, "expression": True, "null": False}
4843    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4846class StringToArray(Func):
4847    arg_types = {"this": True, "expression": True, "null": False}
4848    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4851class ArrayOverlaps(Binary, Func):
4852    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4855class ArraySize(Func):
4856    arg_types = {"this": True, "expression": False}
4857    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4860class ArraySort(Func):
4861    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4864class ArraySum(Func):
4865    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4868class ArrayUnionAgg(AggFunc):
4869    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4872class Avg(AggFunc):
4873    pass
key = 'avg'
class AnyValue(AggFunc):
4876class AnyValue(AggFunc):
4877    pass
key = 'anyvalue'
class Lag(AggFunc):
4880class Lag(AggFunc):
4881    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4884class Lead(AggFunc):
4885    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4890class First(AggFunc):
4891    pass
key = 'first'
class Last(AggFunc):
4894class Last(AggFunc):
4895    pass
key = 'last'
class FirstValue(AggFunc):
4898class FirstValue(AggFunc):
4899    pass
key = 'firstvalue'
class LastValue(AggFunc):
4902class LastValue(AggFunc):
4903    pass
key = 'lastvalue'
class NthValue(AggFunc):
4906class NthValue(AggFunc):
4907    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4910class Case(Func):
4911    arg_types = {"this": False, "ifs": True, "default": False}
4912
4913    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4914        instance = maybe_copy(self, copy)
4915        instance.append(
4916            "ifs",
4917            If(
4918                this=maybe_parse(condition, copy=copy, **opts),
4919                true=maybe_parse(then, copy=copy, **opts),
4920            ),
4921        )
4922        return instance
4923
4924    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4925        instance = maybe_copy(self, copy)
4926        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4927        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:
4913    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4914        instance = maybe_copy(self, copy)
4915        instance.append(
4916            "ifs",
4917            If(
4918                this=maybe_parse(condition, copy=copy, **opts),
4919                true=maybe_parse(then, copy=copy, **opts),
4920            ),
4921        )
4922        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4924    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4925        instance = maybe_copy(self, copy)
4926        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4927        return instance
key = 'case'
class Cast(Func):
4930class Cast(Func):
4931    arg_types = {
4932        "this": True,
4933        "to": True,
4934        "format": False,
4935        "safe": False,
4936        "action": False,
4937    }
4938
4939    @property
4940    def name(self) -> str:
4941        return self.this.name
4942
4943    @property
4944    def to(self) -> DataType:
4945        return self.args["to"]
4946
4947    @property
4948    def output_name(self) -> str:
4949        return self.name
4950
4951    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4952        """
4953        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4954        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4955        array<int> != array<float>.
4956
4957        Args:
4958            dtypes: the data types to compare this Cast's DataType to.
4959
4960        Returns:
4961            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4962        """
4963        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4939    @property
4940    def name(self) -> str:
4941        return self.this.name
to: DataType
4943    @property
4944    def to(self) -> DataType:
4945        return self.args["to"]
output_name: str
4947    @property
4948    def output_name(self) -> str:
4949        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:
4951    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4952        """
4953        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4954        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4955        array<int> != array<float>.
4956
4957        Args:
4958            dtypes: the data types to compare this Cast's DataType to.
4959
4960        Returns:
4961            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4962        """
4963        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):
4966class TryCast(Cast):
4967    pass
key = 'trycast'
class Try(Func):
4970class Try(Func):
4971    pass
key = 'try'
class CastToStrType(Func):
4974class CastToStrType(Func):
4975    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4978class Collate(Binary, Func):
4979    pass
key = 'collate'
class Ceil(Func):
4982class Ceil(Func):
4983    arg_types = {"this": True, "decimals": False}
4984    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4987class Coalesce(Func):
4988    arg_types = {"this": True, "expressions": False}
4989    is_var_len_args = True
4990    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4993class Chr(Func):
4994    arg_types = {"this": True, "charset": False, "expressions": False}
4995    is_var_len_args = True
4996    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4999class Concat(Func):
5000    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5001    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5004class ConcatWs(Concat):
5005    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5009class ConnectByRoot(Func):
5010    pass
key = 'connectbyroot'
class Count(AggFunc):
5013class Count(AggFunc):
5014    arg_types = {"this": False, "expressions": False}
5015    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5018class CountIf(AggFunc):
5019    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5023class Cbrt(Func):
5024    pass
key = 'cbrt'
class CurrentDate(Func):
5027class CurrentDate(Func):
5028    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5031class CurrentDatetime(Func):
5032    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5035class CurrentTime(Func):
5036    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5039class CurrentTimestamp(Func):
5040    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5043class CurrentUser(Func):
5044    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5047class DateAdd(Func, IntervalOp):
5048    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5051class DateSub(Func, IntervalOp):
5052    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5055class DateDiff(Func, TimeUnit):
5056    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5057    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5060class DateTrunc(Func):
5061    arg_types = {"unit": True, "this": True, "zone": False}
5062
5063    def __init__(self, **args):
5064        unit = args.get("unit")
5065        if isinstance(unit, TimeUnit.VAR_LIKE):
5066            args["unit"] = Literal.string(
5067                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5068            )
5069        elif isinstance(unit, Week):
5070            unit.set("this", Literal.string(unit.this.name.upper()))
5071
5072        super().__init__(**args)
5073
5074    @property
5075    def unit(self) -> Expression:
5076        return self.args["unit"]
DateTrunc(**args)
5063    def __init__(self, **args):
5064        unit = args.get("unit")
5065        if isinstance(unit, TimeUnit.VAR_LIKE):
5066            args["unit"] = Literal.string(
5067                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5068            )
5069        elif isinstance(unit, Week):
5070            unit.set("this", Literal.string(unit.this.name.upper()))
5071
5072        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5074    @property
5075    def unit(self) -> Expression:
5076        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5081class Datetime(Func):
5082    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5085class DatetimeAdd(Func, IntervalOp):
5086    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5089class DatetimeSub(Func, IntervalOp):
5090    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5093class DatetimeDiff(Func, TimeUnit):
5094    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5097class DatetimeTrunc(Func, TimeUnit):
5098    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5101class DayOfWeek(Func):
5102    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5105class DayOfMonth(Func):
5106    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5109class DayOfYear(Func):
5110    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5113class ToDays(Func):
5114    pass
key = 'todays'
class WeekOfYear(Func):
5117class WeekOfYear(Func):
5118    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5121class MonthsBetween(Func):
5122    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5125class LastDay(Func, TimeUnit):
5126    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5127    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5130class Extract(Func):
5131    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5134class Timestamp(Func):
5135    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5138class TimestampAdd(Func, TimeUnit):
5139    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5142class TimestampSub(Func, TimeUnit):
5143    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5146class TimestampDiff(Func, TimeUnit):
5147    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5148    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5151class TimestampTrunc(Func, TimeUnit):
5152    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5155class TimeAdd(Func, TimeUnit):
5156    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5159class TimeSub(Func, TimeUnit):
5160    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5163class TimeDiff(Func, TimeUnit):
5164    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5167class TimeTrunc(Func, TimeUnit):
5168    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5171class DateFromParts(Func):
5172    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5173    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5176class TimeFromParts(Func):
5177    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5178    arg_types = {
5179        "hour": True,
5180        "min": True,
5181        "sec": True,
5182        "nano": False,
5183        "fractions": False,
5184        "precision": False,
5185    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5188class DateStrToDate(Func):
5189    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5192class DateToDateStr(Func):
5193    pass
key = 'datetodatestr'
class DateToDi(Func):
5196class DateToDi(Func):
5197    pass
key = 'datetodi'
class Date(Func):
5201class Date(Func):
5202    arg_types = {"this": False, "zone": False, "expressions": False}
5203    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5206class Day(Func):
5207    pass
key = 'day'
class Decode(Func):
5210class Decode(Func):
5211    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5214class DiToDate(Func):
5215    pass
key = 'ditodate'
class Encode(Func):
5218class Encode(Func):
5219    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5222class Exp(Func):
5223    pass
key = 'exp'
class Explode(Func):
5227class Explode(Func):
5228    arg_types = {"this": True, "expressions": False}
5229    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5232class ExplodeOuter(Explode):
5233    pass
key = 'explodeouter'
class Posexplode(Explode):
5236class Posexplode(Explode):
5237    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5240class PosexplodeOuter(Posexplode, ExplodeOuter):
5241    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5244class Unnest(Func, UDTF):
5245    arg_types = {
5246        "expressions": True,
5247        "alias": False,
5248        "offset": False,
5249    }
5250
5251    @property
5252    def selects(self) -> t.List[Expression]:
5253        columns = super().selects
5254        offset = self.args.get("offset")
5255        if offset:
5256            columns = columns + [to_identifier("offset") if offset is True else offset]
5257        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5251    @property
5252    def selects(self) -> t.List[Expression]:
5253        columns = super().selects
5254        offset = self.args.get("offset")
5255        if offset:
5256            columns = columns + [to_identifier("offset") if offset is True else offset]
5257        return columns
key = 'unnest'
class Floor(Func):
5260class Floor(Func):
5261    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5264class FromBase64(Func):
5265    pass
key = 'frombase64'
class ToBase64(Func):
5268class ToBase64(Func):
5269    pass
key = 'tobase64'
class GapFill(Func):
5272class GapFill(Func):
5273    arg_types = {
5274        "this": True,
5275        "ts_column": True,
5276        "bucket_width": True,
5277        "partitioning_columns": False,
5278        "value_columns": False,
5279        "origin": False,
5280        "ignore_nulls": False,
5281    }
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):
5284class GenerateDateArray(Func):
5285    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5288class Greatest(Func):
5289    arg_types = {"this": True, "expressions": False}
5290    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5293class GroupConcat(AggFunc):
5294    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5297class Hex(Func):
5298    pass
key = 'hex'
class LowerHex(Hex):
5301class LowerHex(Hex):
5302    pass
key = 'lowerhex'
class Xor(Connector, Func):
5305class Xor(Connector, Func):
5306    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5309class If(Func):
5310    arg_types = {"this": True, "true": True, "false": False}
5311    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5314class Nullif(Func):
5315    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5318class Initcap(Func):
5319    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5322class IsNan(Func):
5323    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5326class IsInf(Func):
5327    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5330class JSONPath(Expression):
5331    arg_types = {"expressions": True}
5332
5333    @property
5334    def output_name(self) -> str:
5335        last_segment = self.expressions[-1].this
5336        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5333    @property
5334    def output_name(self) -> str:
5335        last_segment = self.expressions[-1].this
5336        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):
5339class JSONPathPart(Expression):
5340    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5343class JSONPathFilter(JSONPathPart):
5344    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5347class JSONPathKey(JSONPathPart):
5348    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5351class JSONPathRecursive(JSONPathPart):
5352    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5355class JSONPathRoot(JSONPathPart):
5356    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5359class JSONPathScript(JSONPathPart):
5360    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5363class JSONPathSlice(JSONPathPart):
5364    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5367class JSONPathSelector(JSONPathPart):
5368    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5371class JSONPathSubscript(JSONPathPart):
5372    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5375class JSONPathUnion(JSONPathPart):
5376    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5379class JSONPathWildcard(JSONPathPart):
5380    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5383class FormatJson(Expression):
5384    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5387class JSONKeyValue(Expression):
5388    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5391class JSONObject(Func):
5392    arg_types = {
5393        "expressions": False,
5394        "null_handling": False,
5395        "unique_keys": False,
5396        "return_type": False,
5397        "encoding": False,
5398    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5401class JSONObjectAgg(AggFunc):
5402    arg_types = {
5403        "expressions": False,
5404        "null_handling": False,
5405        "unique_keys": False,
5406        "return_type": False,
5407        "encoding": False,
5408    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5412class JSONArray(Func):
5413    arg_types = {
5414        "expressions": True,
5415        "null_handling": False,
5416        "return_type": False,
5417        "strict": False,
5418    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5422class JSONArrayAgg(Func):
5423    arg_types = {
5424        "this": True,
5425        "order": False,
5426        "null_handling": False,
5427        "return_type": False,
5428        "strict": False,
5429    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5434class JSONColumnDef(Expression):
5435    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):
5438class JSONSchema(Expression):
5439    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5443class JSONTable(Func):
5444    arg_types = {
5445        "this": True,
5446        "schema": True,
5447        "path": False,
5448        "error_handling": False,
5449        "empty_handling": False,
5450    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5453class OpenJSONColumnDef(Expression):
5454    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):
5457class OpenJSON(Func):
5458    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5461class JSONBContains(Binary, Func):
5462    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5465class JSONExtract(Binary, Func):
5466    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5467    _sql_names = ["JSON_EXTRACT"]
5468    is_var_len_args = True
5469
5470    @property
5471    def output_name(self) -> str:
5472        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
5470    @property
5471    def output_name(self) -> str:
5472        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):
5475class JSONExtractScalar(Binary, Func):
5476    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5477    _sql_names = ["JSON_EXTRACT_SCALAR"]
5478    is_var_len_args = True
5479
5480    @property
5481    def output_name(self) -> str:
5482        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
5480    @property
5481    def output_name(self) -> str:
5482        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):
5485class JSONBExtract(Binary, Func):
5486    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5489class JSONBExtractScalar(Binary, Func):
5490    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5493class JSONFormat(Func):
5494    arg_types = {"this": False, "options": False}
5495    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5499class JSONArrayContains(Binary, Predicate, Func):
5500    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5503class ParseJSON(Func):
5504    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5505    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5506    arg_types = {"this": True, "expressions": False}
5507    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5510class Least(Func):
5511    arg_types = {"this": True, "expressions": False}
5512    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5515class Left(Func):
5516    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5523class Length(Func):
5524    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5527class Levenshtein(Func):
5528    arg_types = {
5529        "this": True,
5530        "expression": False,
5531        "ins_cost": False,
5532        "del_cost": False,
5533        "sub_cost": False,
5534    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5537class Ln(Func):
5538    pass
key = 'ln'
class Log(Func):
5541class Log(Func):
5542    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5545class LogicalOr(AggFunc):
5546    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5549class LogicalAnd(AggFunc):
5550    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5553class Lower(Func):
5554    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5557class Map(Func):
5558    arg_types = {"keys": False, "values": False}
5559
5560    @property
5561    def keys(self) -> t.List[Expression]:
5562        keys = self.args.get("keys")
5563        return keys.expressions if keys else []
5564
5565    @property
5566    def values(self) -> t.List[Expression]:
5567        values = self.args.get("values")
5568        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5560    @property
5561    def keys(self) -> t.List[Expression]:
5562        keys = self.args.get("keys")
5563        return keys.expressions if keys else []
values: List[Expression]
5565    @property
5566    def values(self) -> t.List[Expression]:
5567        values = self.args.get("values")
5568        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5572class ToMap(Func):
5573    pass
key = 'tomap'
class MapFromEntries(Func):
5576class MapFromEntries(Func):
5577    pass
key = 'mapfromentries'
class StarMap(Func):
5580class StarMap(Func):
5581    pass
key = 'starmap'
class VarMap(Func):
5584class VarMap(Func):
5585    arg_types = {"keys": True, "values": True}
5586    is_var_len_args = True
5587
5588    @property
5589    def keys(self) -> t.List[Expression]:
5590        return self.args["keys"].expressions
5591
5592    @property
5593    def values(self) -> t.List[Expression]:
5594        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5588    @property
5589    def keys(self) -> t.List[Expression]:
5590        return self.args["keys"].expressions
values: List[Expression]
5592    @property
5593    def values(self) -> t.List[Expression]:
5594        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5598class MatchAgainst(Func):
5599    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5602class Max(AggFunc):
5603    arg_types = {"this": True, "expressions": False}
5604    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5607class MD5(Func):
5608    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5612class MD5Digest(Func):
5613    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5616class Min(AggFunc):
5617    arg_types = {"this": True, "expressions": False}
5618    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5621class Month(Func):
5622    pass
key = 'month'
class AddMonths(Func):
5625class AddMonths(Func):
5626    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5629class Nvl2(Func):
5630    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5634class Predict(Func):
5635    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5638class Pow(Binary, Func):
5639    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5642class PercentileCont(AggFunc):
5643    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5646class PercentileDisc(AggFunc):
5647    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5650class Quantile(AggFunc):
5651    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5654class ApproxQuantile(Quantile):
5655    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):
5658class Quarter(Func):
5659    pass
key = 'quarter'
class Rand(Func):
5662class Rand(Func):
5663    _sql_names = ["RAND", "RANDOM"]
5664    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5667class Randn(Func):
5668    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5671class RangeN(Func):
5672    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5675class ReadCSV(Func):
5676    _sql_names = ["READ_CSV"]
5677    is_var_len_args = True
5678    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5681class Reduce(Func):
5682    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):
5685class RegexpExtract(Func):
5686    arg_types = {
5687        "this": True,
5688        "expression": True,
5689        "position": False,
5690        "occurrence": False,
5691        "parameters": False,
5692        "group": False,
5693    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5696class RegexpReplace(Func):
5697    arg_types = {
5698        "this": True,
5699        "expression": True,
5700        "replacement": False,
5701        "position": False,
5702        "occurrence": False,
5703        "modifiers": False,
5704    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5707class RegexpLike(Binary, Func):
5708    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5711class RegexpILike(Binary, Func):
5712    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5717class RegexpSplit(Func):
5718    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5721class Repeat(Func):
5722    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5727class Round(Func):
5728    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5731class RowNumber(Func):
5732    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5735class SafeDivide(Func):
5736    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5739class SHA(Func):
5740    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5743class SHA2(Func):
5744    _sql_names = ["SHA2"]
5745    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5748class Sign(Func):
5749    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5752class SortArray(Func):
5753    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5756class Split(Func):
5757    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5762class Substring(Func):
5763    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5766class StandardHash(Func):
5767    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5770class StartsWith(Func):
5771    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5772    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5775class StrPosition(Func):
5776    arg_types = {
5777        "this": True,
5778        "substr": True,
5779        "position": False,
5780        "instance": False,
5781    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5784class StrToDate(Func):
5785    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'strtodate'
class StrToTime(Func):
5788class StrToTime(Func):
5789    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5794class StrToUnix(Func):
5795    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5800class StrToMap(Func):
5801    arg_types = {
5802        "this": True,
5803        "pair_delim": False,
5804        "key_value_delim": False,
5805        "duplicate_resolution_callback": False,
5806    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5809class NumberToStr(Func):
5810    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5813class FromBase(Func):
5814    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5817class Struct(Func):
5818    arg_types = {"expressions": False}
5819    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5822class StructExtract(Func):
5823    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5828class Stuff(Func):
5829    _sql_names = ["STUFF", "INSERT"]
5830    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):
5833class Sum(AggFunc):
5834    pass
key = 'sum'
class Sqrt(Func):
5837class Sqrt(Func):
5838    pass
key = 'sqrt'
class Stddev(AggFunc):
5841class Stddev(AggFunc):
5842    pass
key = 'stddev'
class StddevPop(AggFunc):
5845class StddevPop(AggFunc):
5846    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5849class StddevSamp(AggFunc):
5850    pass
key = 'stddevsamp'
class Time(Func):
5854class Time(Func):
5855    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
5858class TimeToStr(Func):
5859    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):
5862class TimeToTimeStr(Func):
5863    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5866class TimeToUnix(Func):
5867    pass
key = 'timetounix'
class TimeStrToDate(Func):
5870class TimeStrToDate(Func):
5871    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5874class TimeStrToTime(Func):
5875    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5878class TimeStrToUnix(Func):
5879    pass
key = 'timestrtounix'
class Trim(Func):
5882class Trim(Func):
5883    arg_types = {
5884        "this": True,
5885        "expression": False,
5886        "position": False,
5887        "collation": False,
5888    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5891class TsOrDsAdd(Func, TimeUnit):
5892    # return_type is used to correctly cast the arguments of this expression when transpiling it
5893    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5894
5895    @property
5896    def return_type(self) -> DataType:
5897        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
5895    @property
5896    def return_type(self) -> DataType:
5897        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5900class TsOrDsDiff(Func, TimeUnit):
5901    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5904class TsOrDsToDateStr(Func):
5905    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5908class TsOrDsToDate(Func):
5909    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5912class TsOrDsToTime(Func):
5913    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5916class TsOrDsToTimestamp(Func):
5917    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5920class TsOrDiToDi(Func):
5921    pass
key = 'tsorditodi'
class Unhex(Func):
5924class Unhex(Func):
5925    pass
key = 'unhex'
class UnixDate(Func):
5929class UnixDate(Func):
5930    pass
key = 'unixdate'
class UnixToStr(Func):
5933class UnixToStr(Func):
5934    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5939class UnixToTime(Func):
5940    arg_types = {
5941        "this": True,
5942        "scale": False,
5943        "zone": False,
5944        "hours": False,
5945        "minutes": False,
5946        "format": False,
5947    }
5948
5949    SECONDS = Literal.number(0)
5950    DECIS = Literal.number(1)
5951    CENTIS = Literal.number(2)
5952    MILLIS = Literal.number(3)
5953    DECIMILLIS = Literal.number(4)
5954    CENTIMILLIS = Literal.number(5)
5955    MICROS = Literal.number(6)
5956    DECIMICROS = Literal.number(7)
5957    CENTIMICROS = Literal.number(8)
5958    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):
5961class UnixToTimeStr(Func):
5962    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5965class TimestampFromParts(Func):
5966    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5967    arg_types = {
5968        "year": True,
5969        "month": True,
5970        "day": True,
5971        "hour": True,
5972        "min": True,
5973        "sec": True,
5974        "nano": False,
5975        "zone": False,
5976        "milli": False,
5977    }
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):
5980class Upper(Func):
5981    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5984class Corr(Binary, AggFunc):
5985    pass
key = 'corr'
class Variance(AggFunc):
5988class Variance(AggFunc):
5989    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5992class VariancePop(AggFunc):
5993    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
5996class CovarSamp(Binary, AggFunc):
5997    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6000class CovarPop(Binary, AggFunc):
6001    pass
key = 'covarpop'
class Week(Func):
6004class Week(Func):
6005    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6008class XMLTable(Func):
6009    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):
6012class Year(Func):
6013    pass
key = 'year'
class Use(Expression):
6016class Use(Expression):
6017    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6020class Merge(Expression):
6021    arg_types = {
6022        "this": True,
6023        "using": True,
6024        "on": True,
6025        "expressions": True,
6026        "with": False,
6027    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6030class When(Func):
6031    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):
6036class NextValueFor(Func):
6037    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6042class Semicolon(Expression):
6043    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:
6083def maybe_parse(
6084    sql_or_expression: ExpOrStr,
6085    *,
6086    into: t.Optional[IntoType] = None,
6087    dialect: DialectType = None,
6088    prefix: t.Optional[str] = None,
6089    copy: bool = False,
6090    **opts,
6091) -> Expression:
6092    """Gracefully handle a possible string or expression.
6093
6094    Example:
6095        >>> maybe_parse("1")
6096        Literal(this=1, is_string=False)
6097        >>> maybe_parse(to_identifier("x"))
6098        Identifier(this=x, quoted=False)
6099
6100    Args:
6101        sql_or_expression: the SQL code string or an expression
6102        into: the SQLGlot Expression to parse into
6103        dialect: the dialect used to parse the input expressions (in the case that an
6104            input expression is a SQL string).
6105        prefix: a string to prefix the sql with before it gets parsed
6106            (automatically includes a space)
6107        copy: whether to copy the expression.
6108        **opts: other options to use to parse the input expressions (again, in the case
6109            that an input expression is a SQL string).
6110
6111    Returns:
6112        Expression: the parsed or given expression.
6113    """
6114    if isinstance(sql_or_expression, Expression):
6115        if copy:
6116            return sql_or_expression.copy()
6117        return sql_or_expression
6118
6119    if sql_or_expression is None:
6120        raise ParseError("SQL cannot be None")
6121
6122    import sqlglot
6123
6124    sql = str(sql_or_expression)
6125    if prefix:
6126        sql = f"{prefix} {sql}"
6127
6128    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):
6139def maybe_copy(instance, copy=True):
6140    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:
6360def union(
6361    left: ExpOrStr,
6362    right: ExpOrStr,
6363    distinct: bool = True,
6364    dialect: DialectType = None,
6365    copy: bool = True,
6366    **opts,
6367) -> Union:
6368    """
6369    Initializes a syntax tree from one UNION expression.
6370
6371    Example:
6372        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6373        'SELECT * FROM foo UNION SELECT * FROM bla'
6374
6375    Args:
6376        left: the SQL code string corresponding to the left-hand side.
6377            If an `Expression` instance is passed, it will be used as-is.
6378        right: the SQL code string corresponding to the right-hand side.
6379            If an `Expression` instance is passed, it will be used as-is.
6380        distinct: set the DISTINCT flag if and only if this is true.
6381        dialect: the dialect used to parse the input expression.
6382        copy: whether to copy the expression.
6383        opts: other options to use to parse the input expressions.
6384
6385    Returns:
6386        The new Union instance.
6387    """
6388    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6389    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6390
6391    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:
6394def intersect(
6395    left: ExpOrStr,
6396    right: ExpOrStr,
6397    distinct: bool = True,
6398    dialect: DialectType = None,
6399    copy: bool = True,
6400    **opts,
6401) -> Intersect:
6402    """
6403    Initializes a syntax tree from one INTERSECT expression.
6404
6405    Example:
6406        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6407        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6408
6409    Args:
6410        left: the SQL code string corresponding to the left-hand side.
6411            If an `Expression` instance is passed, it will be used as-is.
6412        right: the SQL code string corresponding to the right-hand side.
6413            If an `Expression` instance is passed, it will be used as-is.
6414        distinct: set the DISTINCT flag if and only if this is true.
6415        dialect: the dialect used to parse the input expression.
6416        copy: whether to copy the expression.
6417        opts: other options to use to parse the input expressions.
6418
6419    Returns:
6420        The new Intersect instance.
6421    """
6422    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6423    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6424
6425    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:
6428def except_(
6429    left: ExpOrStr,
6430    right: ExpOrStr,
6431    distinct: bool = True,
6432    dialect: DialectType = None,
6433    copy: bool = True,
6434    **opts,
6435) -> Except:
6436    """
6437    Initializes a syntax tree from one EXCEPT expression.
6438
6439    Example:
6440        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6441        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6442
6443    Args:
6444        left: the SQL code string corresponding to the left-hand side.
6445            If an `Expression` instance is passed, it will be used as-is.
6446        right: the SQL code string corresponding to the right-hand side.
6447            If an `Expression` instance is passed, it will be used as-is.
6448        distinct: set the DISTINCT flag if and only if this is true.
6449        dialect: the dialect used to parse the input expression.
6450        copy: whether to copy the expression.
6451        opts: other options to use to parse the input expressions.
6452
6453    Returns:
6454        The new Except instance.
6455    """
6456    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6457    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6458
6459    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:
6462def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6463    """
6464    Initializes a syntax tree from one or multiple SELECT expressions.
6465
6466    Example:
6467        >>> select("col1", "col2").from_("tbl").sql()
6468        'SELECT col1, col2 FROM tbl'
6469
6470    Args:
6471        *expressions: the SQL code string to parse as the expressions of a
6472            SELECT statement. If an Expression instance is passed, this is used as-is.
6473        dialect: the dialect used to parse the input expressions (in the case that an
6474            input expression is a SQL string).
6475        **opts: other options to use to parse the input expressions (again, in the case
6476            that an input expression is a SQL string).
6477
6478    Returns:
6479        Select: the syntax tree for the SELECT statement.
6480    """
6481    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:
6484def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6485    """
6486    Initializes a syntax tree from a FROM expression.
6487
6488    Example:
6489        >>> from_("tbl").select("col1", "col2").sql()
6490        'SELECT col1, col2 FROM tbl'
6491
6492    Args:
6493        *expression: the SQL code string to parse as the FROM expressions of a
6494            SELECT statement. If an Expression instance is passed, this is used as-is.
6495        dialect: the dialect used to parse the input expression (in the case that the
6496            input expression is a SQL string).
6497        **opts: other options to use to parse the input expressions (again, in the case
6498            that the input expression is a SQL string).
6499
6500    Returns:
6501        Select: the syntax tree for the SELECT statement.
6502    """
6503    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:
6506def update(
6507    table: str | Table,
6508    properties: dict,
6509    where: t.Optional[ExpOrStr] = None,
6510    from_: t.Optional[ExpOrStr] = None,
6511    dialect: DialectType = None,
6512    **opts,
6513) -> Update:
6514    """
6515    Creates an update statement.
6516
6517    Example:
6518        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6519        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6520
6521    Args:
6522        *properties: dictionary of properties to set which are
6523            auto converted to sql objects eg None -> NULL
6524        where: sql conditional parsed into a WHERE statement
6525        from_: sql statement parsed into a FROM statement
6526        dialect: the dialect used to parse the input expressions.
6527        **opts: other options to use to parse the input expressions.
6528
6529    Returns:
6530        Update: the syntax tree for the UPDATE statement.
6531    """
6532    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6533    update_expr.set(
6534        "expressions",
6535        [
6536            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6537            for k, v in properties.items()
6538        ],
6539    )
6540    if from_:
6541        update_expr.set(
6542            "from",
6543            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6544        )
6545    if isinstance(where, Condition):
6546        where = Where(this=where)
6547    if where:
6548        update_expr.set(
6549            "where",
6550            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6551        )
6552    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:
6555def delete(
6556    table: ExpOrStr,
6557    where: t.Optional[ExpOrStr] = None,
6558    returning: t.Optional[ExpOrStr] = None,
6559    dialect: DialectType = None,
6560    **opts,
6561) -> Delete:
6562    """
6563    Builds a delete statement.
6564
6565    Example:
6566        >>> delete("my_table", where="id > 1").sql()
6567        'DELETE FROM my_table WHERE id > 1'
6568
6569    Args:
6570        where: sql conditional parsed into a WHERE statement
6571        returning: sql conditional parsed into a RETURNING statement
6572        dialect: the dialect used to parse the input expressions.
6573        **opts: other options to use to parse the input expressions.
6574
6575    Returns:
6576        Delete: the syntax tree for the DELETE statement.
6577    """
6578    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6579    if where:
6580        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6581    if returning:
6582        delete_expr = t.cast(
6583            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6584        )
6585    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:
6588def insert(
6589    expression: ExpOrStr,
6590    into: ExpOrStr,
6591    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6592    overwrite: t.Optional[bool] = None,
6593    returning: t.Optional[ExpOrStr] = None,
6594    dialect: DialectType = None,
6595    copy: bool = True,
6596    **opts,
6597) -> Insert:
6598    """
6599    Builds an INSERT statement.
6600
6601    Example:
6602        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6603        'INSERT INTO tbl VALUES (1, 2, 3)'
6604
6605    Args:
6606        expression: the sql string or expression of the INSERT statement
6607        into: the tbl to insert data to.
6608        columns: optionally the table's column names.
6609        overwrite: whether to INSERT OVERWRITE or not.
6610        returning: sql conditional parsed into a RETURNING statement
6611        dialect: the dialect used to parse the input expressions.
6612        copy: whether to copy the expression.
6613        **opts: other options to use to parse the input expressions.
6614
6615    Returns:
6616        Insert: the syntax tree for the INSERT statement.
6617    """
6618    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6619    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6620
6621    if columns:
6622        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6623
6624    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6625
6626    if returning:
6627        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6628
6629    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:
6632def condition(
6633    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6634) -> Condition:
6635    """
6636    Initialize a logical condition expression.
6637
6638    Example:
6639        >>> condition("x=1").sql()
6640        'x = 1'
6641
6642        This is helpful for composing larger logical syntax trees:
6643        >>> where = condition("x=1")
6644        >>> where = where.and_("y=1")
6645        >>> Select().from_("tbl").select("*").where(where).sql()
6646        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6647
6648    Args:
6649        *expression: the SQL code string to parse.
6650            If an Expression instance is passed, this is used as-is.
6651        dialect: the dialect used to parse the input expression (in the case that the
6652            input expression is a SQL string).
6653        copy: Whether to copy `expression` (only applies to expressions).
6654        **opts: other options to use to parse the input expressions (again, in the case
6655            that the input expression is a SQL string).
6656
6657    Returns:
6658        The new Condition instance
6659    """
6660    return maybe_parse(
6661        expression,
6662        into=Condition,
6663        dialect=dialect,
6664        copy=copy,
6665        **opts,
6666    )

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

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

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

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

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

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

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

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

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

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

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:
7690def true() -> Boolean:
7691    """
7692    Returns a true Boolean expression.
7693    """
7694    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7697def false() -> Boolean:
7698    """
7699    Returns a false Boolean expression.
7700    """
7701    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7704def null() -> Null:
7705    """
7706    Returns a Null expression.
7707    """
7708    return Null()

Returns a Null expression.

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