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

Retrieves the argument with key "this".

expression: Any
133    @property
134    def expression(self) -> t.Any:
135        """
136        Retrieves the argument with key "expression".
137        """
138        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
140    @property
141    def expressions(self) -> t.List[t.Any]:
142        """
143        Retrieves the argument with key "expressions".
144        """
145        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
147    def text(self, key) -> str:
148        """
149        Returns a textual representation of the argument corresponding to "key". This can only be used
150        for args that are strings or leaf Expression instances, such as identifiers and literals.
151        """
152        field = self.args.get(key)
153        if isinstance(field, str):
154            return field
155        if isinstance(field, (Identifier, Literal, Var)):
156            return field.this
157        if isinstance(field, (Star, Null)):
158            return field.name
159        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
161    @property
162    def is_string(self) -> bool:
163        """
164        Checks whether a Literal expression is a string.
165        """
166        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

is_int: bool
175    @property
176    def is_int(self) -> bool:
177        """
178        Checks whether a Literal expression is an integer.
179        """
180        if self.is_number:
181            try:
182                int(self.name)
183                return True
184            except ValueError:
185                pass
186        return False

Checks whether a Literal expression is an integer.

is_star: bool
188    @property
189    def is_star(self) -> bool:
190        """Checks whether an expression is a star."""
191        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
193    @property
194    def alias(self) -> str:
195        """
196        Returns the alias of the expression, or an empty string if it's not aliased.
197        """
198        if isinstance(self.args.get("alias"), TableAlias):
199            return self.args["alias"].name
200        return self.text("alias")

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

alias_column_names: List[str]
202    @property
203    def alias_column_names(self) -> t.List[str]:
204        table_alias = self.args.get("alias")
205        if not table_alias:
206            return []
207        return [c.name for c in table_alias.args.get("columns") or []]
name: str
209    @property
210    def name(self) -> str:
211        return self.text("this")
alias_or_name: str
213    @property
214    def alias_or_name(self) -> str:
215        return self.alias or self.name
output_name: str
217    @property
218    def output_name(self) -> str:
219        """
220        Name of the output column if this expression is a selection.
221
222        If the Expression has no output name, an empty string is returned.
223
224        Example:
225            >>> from sqlglot import parse_one
226            >>> parse_one("SELECT a").expressions[0].output_name
227            'a'
228            >>> parse_one("SELECT b AS c").expressions[0].output_name
229            'c'
230            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
231            ''
232        """
233        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]
235    @property
236    def type(self) -> t.Optional[DataType]:
237        return self._type
def is_type(self, *dtypes) -> bool:
245    def is_type(self, *dtypes) -> bool:
246        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
248    def is_leaf(self) -> bool:
249        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
251    @property
252    def meta(self) -> t.Dict[str, t.Any]:
253        if self._meta is None:
254            self._meta = {}
255        return self._meta
def copy(self):
270    def copy(self):
271        """
272        Returns a deep copy of the expression.
273        """
274        new = deepcopy(self)
275        new.parent = self.parent
276        return new

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
278    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
279        if self.comments is None:
280            self.comments = []
281        if comments:
282            for comment in comments:
283                _, *meta = comment.split(SQLGLOT_META)
284                if meta:
285                    for kv in "".join(meta).split(","):
286                        k, *v = kv.split("=")
287                        value = v[0].strip() if v else True
288                        self.meta[k.strip()] = value
289                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
291    def append(self, arg_key: str, value: t.Any) -> None:
292        """
293        Appends value to arg_key if it's a list or sets it as a new list.
294
295        Args:
296            arg_key (str): name of the list expression arg
297            value (Any): value to append to the list
298        """
299        if not isinstance(self.args.get(arg_key), list):
300            self.args[arg_key] = []
301        self.args[arg_key].append(value)
302        self._set_parent(arg_key, 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) -> None:
304    def set(self, arg_key: str, value: t.Any) -> None:
305        """
306        Sets arg_key to value.
307
308        Args:
309            arg_key: name of the expression arg.
310            value: value to set the arg to.
311        """
312        if value is None:
313            self.args.pop(arg_key, None)
314            return
315
316        self.args[arg_key] = value
317        self._set_parent(arg_key, value)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
depth: int
329    @property
330    def depth(self) -> int:
331        """
332        Returns the depth of this tree.
333        """
334        if self.parent:
335            return self.parent.depth + 1
336        return 0

Returns the depth of this tree.

def iter_expressions(self) -> Iterator[Tuple[str, Expression]]:
338    def iter_expressions(self) -> t.Iterator[t.Tuple[str, Expression]]:
339        """Yields the key and expression for all arguments, exploding list args."""
340        for k, vs in self.args.items():
341            if type(vs) is list:
342                for v in vs:
343                    if hasattr(v, "parent"):
344                        yield k, v
345            else:
346                if hasattr(vs, "parent"):
347                    yield k, vs

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

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
349    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
350        """
351        Returns the first node in this tree which matches at least one of
352        the specified types.
353
354        Args:
355            expression_types: the expression type(s) to match.
356            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
357
358        Returns:
359            The node which matches the criteria or None if no such node was found.
360        """
361        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]:
363    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
364        """
365        Returns a generator object which visits all nodes in this tree and only
366        yields those that match at least one of the specified expression types.
367
368        Args:
369            expression_types: the expression type(s) to match.
370            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
371
372        Returns:
373            The generator object.
374        """
375        for expression, *_ in self.walk(bfs=bfs):
376            if isinstance(expression, expression_types):
377                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]:
379    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
380        """
381        Returns a nearest parent matching expression_types.
382
383        Args:
384            expression_types: the expression type(s) to match.
385
386        Returns:
387            The parent node.
388        """
389        ancestor = self.parent
390        while ancestor and not isinstance(ancestor, expression_types):
391            ancestor = ancestor.parent
392        return t.cast(E, ancestor)

Returns a nearest parent matching expression_types.

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

The parent node.

parent_select: Optional[Select]
394    @property
395    def parent_select(self) -> t.Optional[Select]:
396        """
397        Returns the parent select statement.
398        """
399        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
401    @property
402    def same_parent(self) -> bool:
403        """Returns if the parent is the same class as itself."""
404        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
406    def root(self) -> Expression:
407        """
408        Returns the root expression of this tree.
409        """
410        expression = self
411        while expression.parent:
412            expression = expression.parent
413        return expression

Returns the root expression of this tree.

def walk(self, bfs=True, prune=None):
415    def walk(self, bfs=True, prune=None):
416        """
417        Returns a generator object which visits all nodes in this tree.
418
419        Args:
420            bfs (bool): if set to True the BFS traversal order will be applied,
421                otherwise the DFS traversal will be used instead.
422            prune ((node, parent, arg_key) -> bool): callable that returns True if
423                the generator should stop traversing this branch of the tree.
424
425        Returns:
426            the generator object.
427        """
428        if bfs:
429            yield from self.bfs(prune=prune)
430        else:
431            yield from self.dfs(prune=prune)

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

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

the generator object.

def dfs(self, parent=None, key=None, prune=None):
433    def dfs(self, parent=None, key=None, prune=None):
434        """
435        Returns a generator object which visits all nodes in this tree in
436        the DFS (Depth-first) order.
437
438        Returns:
439            The generator object.
440        """
441        parent = parent or self.parent
442        yield self, parent, key
443        if prune and prune(self, parent, key):
444            return
445
446        for k, v in self.iter_expressions():
447            yield from v.dfs(self, k, prune)

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=None):
449    def bfs(self, prune=None):
450        """
451        Returns a generator object which visits all nodes in this tree in
452        the BFS (Breadth-first) order.
453
454        Returns:
455            The generator object.
456        """
457        queue = deque([(self, self.parent, None)])
458
459        while queue:
460            item, parent, key = queue.popleft()
461
462            yield item, parent, key
463            if prune and prune(item, parent, key):
464                continue
465
466            for k, v in item.iter_expressions():
467                queue.append((v, item, k))

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

Returns:

The generator object.

def unnest(self):
469    def unnest(self):
470        """
471        Returns the first non parenthesis child or self.
472        """
473        expression = self
474        while type(expression) is Paren:
475            expression = expression.this
476        return expression

Returns the first non parenthesis child or self.

def unalias(self):
478    def unalias(self):
479        """
480        Returns the inner expression if this is an Alias.
481        """
482        if isinstance(self, Alias):
483            return self.this
484        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
486    def unnest_operands(self):
487        """
488        Returns unnested operands as a tuple.
489        """
490        return tuple(arg.unnest() for _, arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
492    def flatten(self, unnest=True):
493        """
494        Returns a generator which yields child nodes whose parents are the same class.
495
496        A AND B AND C -> [A, B, C]
497        """
498        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and not type(n) is self.__class__):
499            if not type(node) is self.__class__:
500                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:
508    def to_s(self) -> str:
509        """
510        Same as __repr__, but includes additional information which can be useful
511        for debugging, like empty or missing args and the AST nodes' object IDs.
512        """
513        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:
515    def sql(self, dialect: DialectType = None, **opts) -> str:
516        """
517        Returns SQL string representation of this tree.
518
519        Args:
520            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
521            opts: other `sqlglot.generator.Generator` options.
522
523        Returns:
524            The SQL string.
525        """
526        from sqlglot.dialects import Dialect
527
528        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, *args, copy=True, **kwargs):
530    def transform(self, fun, *args, copy=True, **kwargs):
531        """
532        Recursively visits all tree nodes (excluding already transformed ones)
533        and applies the given transformation function to each node.
534
535        Args:
536            fun (function): a function which takes a node as an argument and returns a
537                new transformed node or the same node without modifications. If the function
538                returns None, then the corresponding node will be removed from the syntax tree.
539            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
540                modified in place.
541
542        Returns:
543            The transformed tree.
544        """
545        node = self.copy() if copy else self
546        new_node = fun(node, *args, **kwargs)
547
548        if new_node is None or not isinstance(new_node, Expression):
549            return new_node
550        if new_node is not node:
551            new_node.parent = node.parent
552            return new_node
553
554        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
555        return new_node

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

Arguments:
  • fun (function): 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 (bool): 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):
565    def replace(self, expression):
566        """
567        Swap out this expression with a new expression.
568
569        For example::
570
571            >>> tree = Select().select("x").from_("tbl")
572            >>> tree.find(Column).replace(column("y"))
573            Column(
574              this=Identifier(this=y, quoted=False))
575            >>> tree.sql()
576            'SELECT y FROM tbl'
577
578        Args:
579            expression: new node
580
581        Returns:
582            The new expression or expressions.
583        """
584        if not self.parent:
585            return expression
586
587        parent = self.parent
588        self.parent = None
589
590        replace_children(parent, lambda child: expression if child is self else child)
591        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:
593    def pop(self: E) -> E:
594        """
595        Remove this expression from its AST.
596
597        Returns:
598            The popped expression.
599        """
600        self.replace(None)
601        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
603    def assert_is(self, type_: t.Type[E]) -> E:
604        """
605        Assert that this `Expression` is an instance of `type_`.
606
607        If it is NOT an instance of `type_`, this raises an assertion error.
608        Otherwise, this returns this expression.
609
610        Examples:
611            This is useful for type security in chained expressions:
612
613            >>> import sqlglot
614            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
615            'SELECT x, z FROM y'
616        """
617        assert isinstance(self, type_)
618        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]:
620    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
621        """
622        Checks if this expression is valid (e.g. all mandatory args are set).
623
624        Args:
625            args: a sequence of values that were used to instantiate a Func expression. This is used
626                to check that the provided arguments don't exceed the function argument limit.
627
628        Returns:
629            A list of error messages for all possible errors that were found.
630        """
631        errors: t.List[str] = []
632
633        for k in self.args:
634            if k not in self.arg_types:
635                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
636        for k, mandatory in self.arg_types.items():
637            v = self.args.get(k)
638            if mandatory and (v is None or (isinstance(v, list) and not v)):
639                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
640
641        if (
642            args
643            and isinstance(self, Func)
644            and len(args) > len(self.arg_types)
645            and not self.is_var_len_args
646        ):
647            errors.append(
648                f"The number of provided arguments ({len(args)}) is greater than "
649                f"the maximum number of supported arguments ({len(self.arg_types)})"
650            )
651
652        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):
654    def dump(self):
655        """
656        Dump this Expression to a JSON-serializable dict.
657        """
658        from sqlglot.serde import dump
659
660        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
662    @classmethod
663    def load(cls, obj):
664        """
665        Load a dict (as returned by `Expression.dump`) into an Expression instance.
666        """
667        from sqlglot.serde import load
668
669        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:
671    def and_(
672        self,
673        *expressions: t.Optional[ExpOrStr],
674        dialect: DialectType = None,
675        copy: bool = True,
676        **opts,
677    ) -> Condition:
678        """
679        AND this condition with one or multiple expressions.
680
681        Example:
682            >>> condition("x=1").and_("y=1").sql()
683            'x = 1 AND y = 1'
684
685        Args:
686            *expressions: the SQL code strings to parse.
687                If an `Expression` instance is passed, it will be used as-is.
688            dialect: the dialect used to parse the input expression.
689            copy: whether or not to copy the involved expressions (only applies to Expressions).
690            opts: other options to use to parse the input expressions.
691
692        Returns:
693            The new And condition.
694        """
695        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 or not 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:
697    def or_(
698        self,
699        *expressions: t.Optional[ExpOrStr],
700        dialect: DialectType = None,
701        copy: bool = True,
702        **opts,
703    ) -> Condition:
704        """
705        OR this condition with one or multiple expressions.
706
707        Example:
708            >>> condition("x=1").or_("y=1").sql()
709            'x = 1 OR y = 1'
710
711        Args:
712            *expressions: the SQL code strings to parse.
713                If an `Expression` instance is passed, it will be used as-is.
714            dialect: the dialect used to parse the input expression.
715            copy: whether or not to copy the involved expressions (only applies to Expressions).
716            opts: other options to use to parse the input expressions.
717
718        Returns:
719            The new Or condition.
720        """
721        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 or not 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):
723    def not_(self, copy: bool = True):
724        """
725        Wrap this condition with NOT.
726
727        Example:
728            >>> condition("x=1").not_().sql()
729            'NOT x = 1'
730
731        Args:
732            copy: whether or not to copy this object.
733
734        Returns:
735            The new Not instance.
736        """
737        return not_(self, copy=copy)

Wrap this condition with NOT.

Example:
>>> condition("x=1").not_().sql()
'NOT x = 1'
Arguments:
  • copy: whether or not 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:
739    def as_(
740        self,
741        alias: str | Identifier,
742        quoted: t.Optional[bool] = None,
743        dialect: DialectType = None,
744        copy: bool = True,
745        **opts,
746    ) -> Alias:
747        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:
772    def isin(
773        self,
774        *expressions: t.Any,
775        query: t.Optional[ExpOrStr] = None,
776        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
777        copy: bool = True,
778        **opts,
779    ) -> In:
780        return In(
781            this=maybe_copy(self, copy),
782            expressions=[convert(e, copy=copy) for e in expressions],
783            query=maybe_parse(query, copy=copy, **opts) if query else None,
784            unnest=Unnest(
785                expressions=[
786                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
787                ]
788            )
789            if unnest
790            else None,
791        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
793    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
794        return Between(
795            this=maybe_copy(self, copy),
796            low=convert(low, copy=copy, **opts),
797            high=convert(high, copy=copy, **opts),
798        )
def is_( self, other: Union[str, Expression]) -> Is:
800    def is_(self, other: ExpOrStr) -> Is:
801        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
803    def like(self, other: ExpOrStr) -> Like:
804        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
806    def ilike(self, other: ExpOrStr) -> ILike:
807        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
809    def eq(self, other: t.Any) -> EQ:
810        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
812    def neq(self, other: t.Any) -> NEQ:
813        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
815    def rlike(self, other: ExpOrStr) -> RegexpLike:
816        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
818    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
819        div = self._binop(Div, other)
820        div.args["typed"] = typed
821        div.args["safe"] = safe
822        return div
def desc(self, nulls_first: bool = False) -> Ordered:
824    def desc(self, nulls_first: bool = False) -> Ordered:
825        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):
908class Condition(Expression):
909    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
916class DerivedTable(Expression):
917    @property
918    def selects(self) -> t.List[Expression]:
919        return self.this.selects if isinstance(self.this, Subqueryable) else []
920
921    @property
922    def named_selects(self) -> t.List[str]:
923        return [select.output_name for select in self.selects]
selects: List[Expression]
917    @property
918    def selects(self) -> t.List[Expression]:
919        return self.this.selects if isinstance(self.this, Subqueryable) else []
named_selects: List[str]
921    @property
922    def named_selects(self) -> t.List[str]:
923        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Unionable(Expression):
926class Unionable(Expression):
927    def union(
928        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
929    ) -> Unionable:
930        """
931        Builds a UNION expression.
932
933        Example:
934            >>> import sqlglot
935            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
936            'SELECT * FROM foo UNION SELECT * FROM bla'
937
938        Args:
939            expression: the SQL code string.
940                If an `Expression` instance is passed, it will be used as-is.
941            distinct: set the DISTINCT flag if and only if this is true.
942            dialect: the dialect used to parse the input expression.
943            opts: other options to use to parse the input expressions.
944
945        Returns:
946            The new Union expression.
947        """
948        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
949
950    def intersect(
951        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
952    ) -> Unionable:
953        """
954        Builds an INTERSECT expression.
955
956        Example:
957            >>> import sqlglot
958            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
959            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
960
961        Args:
962            expression: the SQL code string.
963                If an `Expression` instance is passed, it will be used as-is.
964            distinct: set the DISTINCT flag if and only if this is true.
965            dialect: the dialect used to parse the input expression.
966            opts: other options to use to parse the input expressions.
967
968        Returns:
969            The new Intersect expression.
970        """
971        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
972
973    def except_(
974        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
975    ) -> Unionable:
976        """
977        Builds an EXCEPT expression.
978
979        Example:
980            >>> import sqlglot
981            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
982            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
983
984        Args:
985            expression: the SQL code string.
986                If an `Expression` instance is passed, it will be used as-is.
987            distinct: set the DISTINCT flag if and only if this is true.
988            dialect: the dialect used to parse the input expression.
989            opts: other options to use to parse the input expressions.
990
991        Returns:
992            The new Except expression.
993        """
994        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
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) -> Unionable:
927    def union(
928        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
929    ) -> Unionable:
930        """
931        Builds a UNION expression.
932
933        Example:
934            >>> import sqlglot
935            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
936            'SELECT * FROM foo UNION SELECT * FROM bla'
937
938        Args:
939            expression: the SQL code string.
940                If an `Expression` instance is passed, it will be used as-is.
941            distinct: set the DISTINCT flag if and only if this is true.
942            dialect: the dialect used to parse the input expression.
943            opts: other options to use to parse the input expressions.
944
945        Returns:
946            The new Union expression.
947        """
948        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) -> Unionable:
950    def intersect(
951        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
952    ) -> Unionable:
953        """
954        Builds an INTERSECT expression.
955
956        Example:
957            >>> import sqlglot
958            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
959            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
960
961        Args:
962            expression: the SQL code string.
963                If an `Expression` instance is passed, it will be used as-is.
964            distinct: set the DISTINCT flag if and only if this is true.
965            dialect: the dialect used to parse the input expression.
966            opts: other options to use to parse the input expressions.
967
968        Returns:
969            The new Intersect expression.
970        """
971        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) -> Unionable:
973    def except_(
974        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
975    ) -> Unionable:
976        """
977        Builds an EXCEPT expression.
978
979        Example:
980            >>> import sqlglot
981            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
982            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
983
984        Args:
985            expression: the SQL code string.
986                If an `Expression` instance is passed, it will be used as-is.
987            distinct: set the DISTINCT flag if and only if this is true.
988            dialect: the dialect used to parse the input expression.
989            opts: other options to use to parse the input expressions.
990
991        Returns:
992            The new Except expression.
993        """
994        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 = 'unionable'
class UDTF(DerivedTable, Unionable):
 997class UDTF(DerivedTable, Unionable):
 998    @property
 999    def selects(self) -> t.List[Expression]:
1000        alias = self.args.get("alias")
1001        return alias.columns if alias else []
selects: List[Expression]
 998    @property
 999    def selects(self) -> t.List[Expression]:
1000        alias = self.args.get("alias")
1001        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1004class Cache(Expression):
1005    arg_types = {
1006        "this": True,
1007        "lazy": False,
1008        "options": False,
1009        "expression": False,
1010    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1013class Uncache(Expression):
1014    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1017class Refresh(Expression):
1018    pass
key = 'refresh'
class DDL(Expression):
1021class DDL(Expression):
1022    @property
1023    def ctes(self):
1024        with_ = self.args.get("with")
1025        if not with_:
1026            return []
1027        return with_.expressions
1028
1029    @property
1030    def named_selects(self) -> t.List[str]:
1031        if isinstance(self.expression, Subqueryable):
1032            return self.expression.named_selects
1033        return []
1034
1035    @property
1036    def selects(self) -> t.List[Expression]:
1037        if isinstance(self.expression, Subqueryable):
1038            return self.expression.selects
1039        return []
ctes
1022    @property
1023    def ctes(self):
1024        with_ = self.args.get("with")
1025        if not with_:
1026            return []
1027        return with_.expressions
named_selects: List[str]
1029    @property
1030    def named_selects(self) -> t.List[str]:
1031        if isinstance(self.expression, Subqueryable):
1032            return self.expression.named_selects
1033        return []
selects: List[Expression]
1035    @property
1036    def selects(self) -> t.List[Expression]:
1037        if isinstance(self.expression, Subqueryable):
1038            return self.expression.selects
1039        return []
key = 'ddl'
class DML(Expression):
1042class DML(Expression):
1043    def returning(
1044        self,
1045        expression: ExpOrStr,
1046        dialect: DialectType = None,
1047        copy: bool = True,
1048        **opts,
1049    ) -> DML:
1050        """
1051        Set the RETURNING expression. Not supported by all dialects.
1052
1053        Example:
1054            >>> delete("tbl").returning("*", dialect="postgres").sql()
1055            'DELETE FROM tbl RETURNING *'
1056
1057        Args:
1058            expression: the SQL code strings to parse.
1059                If an `Expression` instance is passed, it will be used as-is.
1060            dialect: the dialect used to parse the input expressions.
1061            copy: if `False`, modify this expression instance in-place.
1062            opts: other options to use to parse the input expressions.
1063
1064        Returns:
1065            Delete: the modified expression.
1066        """
1067        return _apply_builder(
1068            expression=expression,
1069            instance=self,
1070            arg="returning",
1071            prefix="RETURNING",
1072            dialect=dialect,
1073            copy=copy,
1074            into=Returning,
1075            **opts,
1076        )
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:
1043    def returning(
1044        self,
1045        expression: ExpOrStr,
1046        dialect: DialectType = None,
1047        copy: bool = True,
1048        **opts,
1049    ) -> DML:
1050        """
1051        Set the RETURNING expression. Not supported by all dialects.
1052
1053        Example:
1054            >>> delete("tbl").returning("*", dialect="postgres").sql()
1055            'DELETE FROM tbl RETURNING *'
1056
1057        Args:
1058            expression: the SQL code strings to parse.
1059                If an `Expression` instance is passed, it will be used as-is.
1060            dialect: the dialect used to parse the input expressions.
1061            copy: if `False`, modify this expression instance in-place.
1062            opts: other options to use to parse the input expressions.
1063
1064        Returns:
1065            Delete: the modified expression.
1066        """
1067        return _apply_builder(
1068            expression=expression,
1069            instance=self,
1070            arg="returning",
1071            prefix="RETURNING",
1072            dialect=dialect,
1073            copy=copy,
1074            into=Returning,
1075            **opts,
1076        )

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):
1079class Create(DDL):
1080    arg_types = {
1081        "with": False,
1082        "this": True,
1083        "kind": True,
1084        "expression": False,
1085        "exists": False,
1086        "properties": False,
1087        "replace": False,
1088        "unique": False,
1089        "indexes": False,
1090        "no_schema_binding": False,
1091        "begin": False,
1092        "end": False,
1093        "clone": False,
1094    }
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}
key = 'create'
class Clone(Expression):
1100class Clone(Expression):
1101    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1104class Describe(Expression):
1105    arg_types = {"this": True, "extended": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'extended': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1108class Kill(Expression):
1109    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1112class Pragma(Expression):
1113    pass
key = 'pragma'
class Set(Expression):
1116class Set(Expression):
1117    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1120class Heredoc(Expression):
1121    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1124class SetItem(Expression):
1125    arg_types = {
1126        "this": False,
1127        "expressions": False,
1128        "kind": False,
1129        "collate": False,  # MySQL SET NAMES statement
1130        "global": False,
1131    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1134class Show(Expression):
1135    arg_types = {
1136        "this": True,
1137        "terse": False,
1138        "target": False,
1139        "offset": False,
1140        "starts_with": False,
1141        "limit": False,
1142        "from": False,
1143        "like": False,
1144        "where": False,
1145        "db": False,
1146        "scope": False,
1147        "scope_kind": False,
1148        "full": False,
1149        "mutex": False,
1150        "query": False,
1151        "channel": False,
1152        "global": False,
1153        "log": False,
1154        "position": False,
1155        "types": False,
1156    }
arg_types = {'this': True, '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):
1159class UserDefinedFunction(Expression):
1160    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1163class CharacterSet(Expression):
1164    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1167class With(Expression):
1168    arg_types = {"expressions": True, "recursive": False}
1169
1170    @property
1171    def recursive(self) -> bool:
1172        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1170    @property
1171    def recursive(self) -> bool:
1172        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1175class WithinGroup(Expression):
1176    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1181class CTE(DerivedTable):
1182    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1185class TableAlias(Expression):
1186    arg_types = {"this": False, "columns": False}
1187
1188    @property
1189    def columns(self):
1190        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1188    @property
1189    def columns(self):
1190        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1193class BitString(Condition):
1194    pass
key = 'bitstring'
class HexString(Condition):
1197class HexString(Condition):
1198    pass
key = 'hexstring'
class ByteString(Condition):
1201class ByteString(Condition):
1202    pass
key = 'bytestring'
class RawString(Condition):
1205class RawString(Condition):
1206    pass
key = 'rawstring'
class UnicodeString(Condition):
1209class UnicodeString(Condition):
1210    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1213class Column(Condition):
1214    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1215
1216    @property
1217    def table(self) -> str:
1218        return self.text("table")
1219
1220    @property
1221    def db(self) -> str:
1222        return self.text("db")
1223
1224    @property
1225    def catalog(self) -> str:
1226        return self.text("catalog")
1227
1228    @property
1229    def output_name(self) -> str:
1230        return self.name
1231
1232    @property
1233    def parts(self) -> t.List[Identifier]:
1234        """Return the parts of a column in order catalog, db, table, name."""
1235        return [
1236            t.cast(Identifier, self.args[part])
1237            for part in ("catalog", "db", "table", "this")
1238            if self.args.get(part)
1239        ]
1240
1241    def to_dot(self) -> Dot | Identifier:
1242        """Converts the column into a dot expression."""
1243        parts = self.parts
1244        parent = self.parent
1245
1246        while parent:
1247            if isinstance(parent, Dot):
1248                parts.append(parent.expression)
1249            parent = parent.parent
1250
1251        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
1216    @property
1217    def table(self) -> str:
1218        return self.text("table")
db: str
1220    @property
1221    def db(self) -> str:
1222        return self.text("db")
catalog: str
1224    @property
1225    def catalog(self) -> str:
1226        return self.text("catalog")
output_name: str
1228    @property
1229    def output_name(self) -> str:
1230        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]
1232    @property
1233    def parts(self) -> t.List[Identifier]:
1234        """Return the parts of a column in order catalog, db, table, name."""
1235        return [
1236            t.cast(Identifier, self.args[part])
1237            for part in ("catalog", "db", "table", "this")
1238            if self.args.get(part)
1239        ]

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

def to_dot(self) -> Dot | Identifier:
1241    def to_dot(self) -> Dot | Identifier:
1242        """Converts the column into a dot expression."""
1243        parts = self.parts
1244        parent = self.parent
1245
1246        while parent:
1247            if isinstance(parent, Dot):
1248                parts.append(parent.expression)
1249            parent = parent.parent
1250
1251        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1254class ColumnPosition(Expression):
1255    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1258class ColumnDef(Expression):
1259    arg_types = {
1260        "this": True,
1261        "kind": False,
1262        "constraints": False,
1263        "exists": False,
1264        "position": False,
1265    }
1266
1267    @property
1268    def constraints(self) -> t.List[ColumnConstraint]:
1269        return self.args.get("constraints") or []
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1267    @property
1268    def constraints(self) -> t.List[ColumnConstraint]:
1269        return self.args.get("constraints") or []
key = 'columndef'
class AlterColumn(Expression):
1272class AlterColumn(Expression):
1273    arg_types = {
1274        "this": True,
1275        "dtype": False,
1276        "collate": False,
1277        "using": False,
1278        "default": False,
1279        "drop": False,
1280    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False}
key = 'altercolumn'
class RenameColumn(Expression):
1283class RenameColumn(Expression):
1284    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1287class RenameTable(Expression):
1288    pass
key = 'renametable'
class SwapTable(Expression):
1291class SwapTable(Expression):
1292    pass
key = 'swaptable'
class Comment(Expression):
1295class Comment(Expression):
1296    arg_types = {"this": True, "kind": True, "expression": True, "exists": False}
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False}
key = 'comment'
class Comprehension(Expression):
1299class Comprehension(Expression):
1300    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):
1304class MergeTreeTTLAction(Expression):
1305    arg_types = {
1306        "this": True,
1307        "delete": False,
1308        "recompress": False,
1309        "to_disk": False,
1310        "to_volume": False,
1311    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1315class MergeTreeTTL(Expression):
1316    arg_types = {
1317        "expressions": True,
1318        "where": False,
1319        "group": False,
1320        "aggregates": False,
1321    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1325class IndexConstraintOption(Expression):
1326    arg_types = {
1327        "key_block_size": False,
1328        "using": False,
1329        "parser": False,
1330        "comment": False,
1331        "visible": False,
1332        "engine_attr": False,
1333        "secondary_engine_attr": False,
1334    }
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):
1337class ColumnConstraint(Expression):
1338    arg_types = {"this": False, "kind": True}
1339
1340    @property
1341    def kind(self) -> ColumnConstraintKind:
1342        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1340    @property
1341    def kind(self) -> ColumnConstraintKind:
1342        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1345class ColumnConstraintKind(Expression):
1346    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1349class AutoIncrementColumnConstraint(ColumnConstraintKind):
1350    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1353class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1354    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1357class CaseSpecificColumnConstraint(ColumnConstraintKind):
1358    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1361class CharacterSetColumnConstraint(ColumnConstraintKind):
1362    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1365class CheckColumnConstraint(ColumnConstraintKind):
1366    pass
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1369class ClusteredColumnConstraint(ColumnConstraintKind):
1370    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1373class CollateColumnConstraint(ColumnConstraintKind):
1374    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1377class CommentColumnConstraint(ColumnConstraintKind):
1378    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1381class CompressColumnConstraint(ColumnConstraintKind):
1382    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1385class DateFormatColumnConstraint(ColumnConstraintKind):
1386    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1389class DefaultColumnConstraint(ColumnConstraintKind):
1390    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1393class EncodeColumnConstraint(ColumnConstraintKind):
1394    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1397class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1398    # this: True -> ALWAYS, this: False -> BY DEFAULT
1399    arg_types = {
1400        "this": False,
1401        "expression": False,
1402        "on_null": False,
1403        "start": False,
1404        "increment": False,
1405        "minvalue": False,
1406        "maxvalue": False,
1407        "cycle": False,
1408    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1411class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1412    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1416class IndexColumnConstraint(ColumnConstraintKind):
1417    arg_types = {
1418        "this": False,
1419        "schema": True,
1420        "kind": False,
1421        "index_type": False,
1422        "options": False,
1423    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1426class InlineLengthColumnConstraint(ColumnConstraintKind):
1427    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1430class NonClusteredColumnConstraint(ColumnConstraintKind):
1431    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1434class NotForReplicationColumnConstraint(ColumnConstraintKind):
1435    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1438class NotNullColumnConstraint(ColumnConstraintKind):
1439    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1443class OnUpdateColumnConstraint(ColumnConstraintKind):
1444    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1448class TransformColumnConstraint(ColumnConstraintKind):
1449    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1452class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1453    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1456class TitleColumnConstraint(ColumnConstraintKind):
1457    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1460class UniqueColumnConstraint(ColumnConstraintKind):
1461    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1464class UppercaseColumnConstraint(ColumnConstraintKind):
1465    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1468class PathColumnConstraint(ColumnConstraintKind):
1469    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1474class ComputedColumnConstraint(ColumnConstraintKind):
1475    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1478class Constraint(Expression):
1479    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1482class Delete(DML):
1483    arg_types = {
1484        "with": False,
1485        "this": False,
1486        "using": False,
1487        "where": False,
1488        "returning": False,
1489        "limit": False,
1490        "tables": False,  # Multiple-Table Syntax (MySQL)
1491    }
1492
1493    def delete(
1494        self,
1495        table: ExpOrStr,
1496        dialect: DialectType = None,
1497        copy: bool = True,
1498        **opts,
1499    ) -> Delete:
1500        """
1501        Create a DELETE expression or replace the table on an existing DELETE expression.
1502
1503        Example:
1504            >>> delete("tbl").sql()
1505            'DELETE FROM tbl'
1506
1507        Args:
1508            table: the table from which to delete.
1509            dialect: the dialect used to parse the input expression.
1510            copy: if `False`, modify this expression instance in-place.
1511            opts: other options to use to parse the input expressions.
1512
1513        Returns:
1514            Delete: the modified expression.
1515        """
1516        return _apply_builder(
1517            expression=table,
1518            instance=self,
1519            arg="this",
1520            dialect=dialect,
1521            into=Table,
1522            copy=copy,
1523            **opts,
1524        )
1525
1526    def where(
1527        self,
1528        *expressions: t.Optional[ExpOrStr],
1529        append: bool = True,
1530        dialect: DialectType = None,
1531        copy: bool = True,
1532        **opts,
1533    ) -> Delete:
1534        """
1535        Append to or set the WHERE expressions.
1536
1537        Example:
1538            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1539            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1540
1541        Args:
1542            *expressions: the SQL code strings to parse.
1543                If an `Expression` instance is passed, it will be used as-is.
1544                Multiple expressions are combined with an AND operator.
1545            append: if `True`, AND the new expressions to any existing expression.
1546                Otherwise, this resets the expression.
1547            dialect: the dialect used to parse the input expressions.
1548            copy: if `False`, modify this expression instance in-place.
1549            opts: other options to use to parse the input expressions.
1550
1551        Returns:
1552            Delete: the modified expression.
1553        """
1554        return _apply_conjunction_builder(
1555            *expressions,
1556            instance=self,
1557            arg="where",
1558            append=append,
1559            into=Where,
1560            dialect=dialect,
1561            copy=copy,
1562            **opts,
1563        )
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:
1493    def delete(
1494        self,
1495        table: ExpOrStr,
1496        dialect: DialectType = None,
1497        copy: bool = True,
1498        **opts,
1499    ) -> Delete:
1500        """
1501        Create a DELETE expression or replace the table on an existing DELETE expression.
1502
1503        Example:
1504            >>> delete("tbl").sql()
1505            'DELETE FROM tbl'
1506
1507        Args:
1508            table: the table from which to delete.
1509            dialect: the dialect used to parse the input expression.
1510            copy: if `False`, modify this expression instance in-place.
1511            opts: other options to use to parse the input expressions.
1512
1513        Returns:
1514            Delete: the modified expression.
1515        """
1516        return _apply_builder(
1517            expression=table,
1518            instance=self,
1519            arg="this",
1520            dialect=dialect,
1521            into=Table,
1522            copy=copy,
1523            **opts,
1524        )

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:
1526    def where(
1527        self,
1528        *expressions: t.Optional[ExpOrStr],
1529        append: bool = True,
1530        dialect: DialectType = None,
1531        copy: bool = True,
1532        **opts,
1533    ) -> Delete:
1534        """
1535        Append to or set the WHERE expressions.
1536
1537        Example:
1538            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1539            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1540
1541        Args:
1542            *expressions: the SQL code strings to parse.
1543                If an `Expression` instance is passed, it will be used as-is.
1544                Multiple expressions are combined with an AND operator.
1545            append: if `True`, AND the new expressions to any existing expression.
1546                Otherwise, this resets the expression.
1547            dialect: the dialect used to parse the input expressions.
1548            copy: if `False`, modify this expression instance in-place.
1549            opts: other options to use to parse the input expressions.
1550
1551        Returns:
1552            Delete: the modified expression.
1553        """
1554        return _apply_conjunction_builder(
1555            *expressions,
1556            instance=self,
1557            arg="where",
1558            append=append,
1559            into=Where,
1560            dialect=dialect,
1561            copy=copy,
1562            **opts,
1563        )

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):
1566class Drop(Expression):
1567    arg_types = {
1568        "this": False,
1569        "kind": False,
1570        "exists": False,
1571        "temporary": False,
1572        "materialized": False,
1573        "cascade": False,
1574        "constraints": False,
1575        "purge": False,
1576    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1579class Filter(Expression):
1580    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1583class Check(Expression):
1584    pass
key = 'check'
class Connect(Expression):
1588class Connect(Expression):
1589    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1592class Prior(Expression):
1593    pass
key = 'prior'
class Directory(Expression):
1596class Directory(Expression):
1597    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1598    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1601class ForeignKey(Expression):
1602    arg_types = {
1603        "expressions": True,
1604        "reference": False,
1605        "delete": False,
1606        "update": False,
1607    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1610class ColumnPrefix(Expression):
1611    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1614class PrimaryKey(Expression):
1615    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1620class Into(Expression):
1621    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1624class From(Expression):
1625    @property
1626    def name(self) -> str:
1627        return self.this.name
1628
1629    @property
1630    def alias_or_name(self) -> str:
1631        return self.this.alias_or_name
name: str
1625    @property
1626    def name(self) -> str:
1627        return self.this.name
alias_or_name: str
1629    @property
1630    def alias_or_name(self) -> str:
1631        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1634class Having(Expression):
1635    pass
key = 'having'
class Hint(Expression):
1638class Hint(Expression):
1639    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1642class JoinHint(Expression):
1643    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1646class Identifier(Expression):
1647    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1648
1649    @property
1650    def quoted(self) -> bool:
1651        return bool(self.args.get("quoted"))
1652
1653    @property
1654    def hashable_args(self) -> t.Any:
1655        return (self.this, self.quoted)
1656
1657    @property
1658    def output_name(self) -> str:
1659        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1649    @property
1650    def quoted(self) -> bool:
1651        return bool(self.args.get("quoted"))
hashable_args: Any
1653    @property
1654    def hashable_args(self) -> t.Any:
1655        return (self.this, self.quoted)
output_name: str
1657    @property
1658    def output_name(self) -> str:
1659        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):
1663class Opclass(Expression):
1664    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1667class Index(Expression):
1668    arg_types = {
1669        "this": False,
1670        "table": False,
1671        "using": False,
1672        "where": False,
1673        "columns": False,
1674        "unique": False,
1675        "primary": False,
1676        "amp": False,  # teradata
1677        "include": False,
1678        "partition_by": False,  # teradata
1679        "where": False,  # postgres partial indexes
1680    }
arg_types = {'this': False, 'table': False, 'using': False, 'where': False, 'columns': False, 'unique': False, 'primary': False, 'amp': False, 'include': False, 'partition_by': False}
key = 'index'
class Insert(DDL, DML):
1683class Insert(DDL, DML):
1684    arg_types = {
1685        "with": False,
1686        "this": True,
1687        "expression": False,
1688        "conflict": False,
1689        "returning": False,
1690        "overwrite": False,
1691        "exists": False,
1692        "partition": False,
1693        "alternative": False,
1694        "where": False,
1695        "ignore": False,
1696        "by_name": False,
1697    }
1698
1699    def with_(
1700        self,
1701        alias: ExpOrStr,
1702        as_: ExpOrStr,
1703        recursive: t.Optional[bool] = None,
1704        append: bool = True,
1705        dialect: DialectType = None,
1706        copy: bool = True,
1707        **opts,
1708    ) -> Insert:
1709        """
1710        Append to or set the common table expressions.
1711
1712        Example:
1713            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1714            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1715
1716        Args:
1717            alias: the SQL code string to parse as the table name.
1718                If an `Expression` instance is passed, this is used as-is.
1719            as_: the SQL code string to parse as the table expression.
1720                If an `Expression` instance is passed, it will be used as-is.
1721            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1722            append: if `True`, add to any existing expressions.
1723                Otherwise, this resets the expressions.
1724            dialect: the dialect used to parse the input expression.
1725            copy: if `False`, modify this expression instance in-place.
1726            opts: other options to use to parse the input expressions.
1727
1728        Returns:
1729            The modified expression.
1730        """
1731        return _apply_cte_builder(
1732            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1733        )
arg_types = {'with': False, 'this': True, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'partition': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': 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:
1699    def with_(
1700        self,
1701        alias: ExpOrStr,
1702        as_: ExpOrStr,
1703        recursive: t.Optional[bool] = None,
1704        append: bool = True,
1705        dialect: DialectType = None,
1706        copy: bool = True,
1707        **opts,
1708    ) -> Insert:
1709        """
1710        Append to or set the common table expressions.
1711
1712        Example:
1713            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1714            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1715
1716        Args:
1717            alias: the SQL code string to parse as the table name.
1718                If an `Expression` instance is passed, this is used as-is.
1719            as_: the SQL code string to parse as the table expression.
1720                If an `Expression` instance is passed, it will be used as-is.
1721            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1722            append: if `True`, add to any existing expressions.
1723                Otherwise, this resets the expressions.
1724            dialect: the dialect used to parse the input expression.
1725            copy: if `False`, modify this expression instance in-place.
1726            opts: other options to use to parse the input expressions.
1727
1728        Returns:
1729            The modified expression.
1730        """
1731        return _apply_cte_builder(
1732            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1733        )

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):
1736class OnConflict(Expression):
1737    arg_types = {
1738        "duplicate": False,
1739        "expressions": False,
1740        "nothing": False,
1741        "key": False,
1742        "constraint": False,
1743    }
arg_types = {'duplicate': False, 'expressions': False, 'nothing': False, 'key': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1746class Returning(Expression):
1747    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1751class Introducer(Expression):
1752    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1756class National(Expression):
1757    pass
key = 'national'
class LoadData(Expression):
1760class LoadData(Expression):
1761    arg_types = {
1762        "this": True,
1763        "local": False,
1764        "overwrite": False,
1765        "inpath": True,
1766        "partition": False,
1767        "input_format": False,
1768        "serde": False,
1769    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1772class Partition(Expression):
1773    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class Fetch(Expression):
1776class Fetch(Expression):
1777    arg_types = {
1778        "direction": False,
1779        "count": False,
1780        "percent": False,
1781        "with_ties": False,
1782    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1785class Group(Expression):
1786    arg_types = {
1787        "expressions": False,
1788        "grouping_sets": False,
1789        "cube": False,
1790        "rollup": False,
1791        "totals": False,
1792        "all": False,
1793    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1796class Lambda(Expression):
1797    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1800class Limit(Expression):
1801    arg_types = {"this": False, "expression": True, "offset": False}
arg_types = {'this': False, 'expression': True, 'offset': False}
key = 'limit'
class Literal(Condition):
1804class Literal(Condition):
1805    arg_types = {"this": True, "is_string": True}
1806
1807    @property
1808    def hashable_args(self) -> t.Any:
1809        return (self.this, self.args.get("is_string"))
1810
1811    @classmethod
1812    def number(cls, number) -> Literal:
1813        return cls(this=str(number), is_string=False)
1814
1815    @classmethod
1816    def string(cls, string) -> Literal:
1817        return cls(this=str(string), is_string=True)
1818
1819    @property
1820    def output_name(self) -> str:
1821        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
1807    @property
1808    def hashable_args(self) -> t.Any:
1809        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
1811    @classmethod
1812    def number(cls, number) -> Literal:
1813        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
1815    @classmethod
1816    def string(cls, string) -> Literal:
1817        return cls(this=str(string), is_string=True)
output_name: str
1819    @property
1820    def output_name(self) -> str:
1821        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):
1824class Join(Expression):
1825    arg_types = {
1826        "this": True,
1827        "on": False,
1828        "side": False,
1829        "kind": False,
1830        "using": False,
1831        "method": False,
1832        "global": False,
1833        "hint": False,
1834    }
1835
1836    @property
1837    def method(self) -> str:
1838        return self.text("method").upper()
1839
1840    @property
1841    def kind(self) -> str:
1842        return self.text("kind").upper()
1843
1844    @property
1845    def side(self) -> str:
1846        return self.text("side").upper()
1847
1848    @property
1849    def hint(self) -> str:
1850        return self.text("hint").upper()
1851
1852    @property
1853    def alias_or_name(self) -> str:
1854        return self.this.alias_or_name
1855
1856    def on(
1857        self,
1858        *expressions: t.Optional[ExpOrStr],
1859        append: bool = True,
1860        dialect: DialectType = None,
1861        copy: bool = True,
1862        **opts,
1863    ) -> Join:
1864        """
1865        Append to or set the ON expressions.
1866
1867        Example:
1868            >>> import sqlglot
1869            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1870            'JOIN x ON y = 1'
1871
1872        Args:
1873            *expressions: the SQL code strings to parse.
1874                If an `Expression` instance is passed, it will be used as-is.
1875                Multiple expressions are combined with an AND operator.
1876            append: if `True`, AND the new expressions to any existing expression.
1877                Otherwise, this resets the expression.
1878            dialect: the dialect used to parse the input expressions.
1879            copy: if `False`, modify this expression instance in-place.
1880            opts: other options to use to parse the input expressions.
1881
1882        Returns:
1883            The modified Join expression.
1884        """
1885        join = _apply_conjunction_builder(
1886            *expressions,
1887            instance=self,
1888            arg="on",
1889            append=append,
1890            dialect=dialect,
1891            copy=copy,
1892            **opts,
1893        )
1894
1895        if join.kind == "CROSS":
1896            join.set("kind", None)
1897
1898        return join
1899
1900    def using(
1901        self,
1902        *expressions: t.Optional[ExpOrStr],
1903        append: bool = True,
1904        dialect: DialectType = None,
1905        copy: bool = True,
1906        **opts,
1907    ) -> Join:
1908        """
1909        Append to or set the USING expressions.
1910
1911        Example:
1912            >>> import sqlglot
1913            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1914            'JOIN x USING (foo, bla)'
1915
1916        Args:
1917            *expressions: the SQL code strings to parse.
1918                If an `Expression` instance is passed, it will be used as-is.
1919            append: if `True`, concatenate the new expressions to the existing "using" list.
1920                Otherwise, this resets the expression.
1921            dialect: the dialect used to parse the input expressions.
1922            copy: if `False`, modify this expression instance in-place.
1923            opts: other options to use to parse the input expressions.
1924
1925        Returns:
1926            The modified Join expression.
1927        """
1928        join = _apply_list_builder(
1929            *expressions,
1930            instance=self,
1931            arg="using",
1932            append=append,
1933            dialect=dialect,
1934            copy=copy,
1935            **opts,
1936        )
1937
1938        if join.kind == "CROSS":
1939            join.set("kind", None)
1940
1941        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
1836    @property
1837    def method(self) -> str:
1838        return self.text("method").upper()
kind: str
1840    @property
1841    def kind(self) -> str:
1842        return self.text("kind").upper()
side: str
1844    @property
1845    def side(self) -> str:
1846        return self.text("side").upper()
hint: str
1848    @property
1849    def hint(self) -> str:
1850        return self.text("hint").upper()
alias_or_name: str
1852    @property
1853    def alias_or_name(self) -> str:
1854        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:
1856    def on(
1857        self,
1858        *expressions: t.Optional[ExpOrStr],
1859        append: bool = True,
1860        dialect: DialectType = None,
1861        copy: bool = True,
1862        **opts,
1863    ) -> Join:
1864        """
1865        Append to or set the ON expressions.
1866
1867        Example:
1868            >>> import sqlglot
1869            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1870            'JOIN x ON y = 1'
1871
1872        Args:
1873            *expressions: the SQL code strings to parse.
1874                If an `Expression` instance is passed, it will be used as-is.
1875                Multiple expressions are combined with an AND operator.
1876            append: if `True`, AND the new expressions to any existing expression.
1877                Otherwise, this resets the expression.
1878            dialect: the dialect used to parse the input expressions.
1879            copy: if `False`, modify this expression instance in-place.
1880            opts: other options to use to parse the input expressions.
1881
1882        Returns:
1883            The modified Join expression.
1884        """
1885        join = _apply_conjunction_builder(
1886            *expressions,
1887            instance=self,
1888            arg="on",
1889            append=append,
1890            dialect=dialect,
1891            copy=copy,
1892            **opts,
1893        )
1894
1895        if join.kind == "CROSS":
1896            join.set("kind", None)
1897
1898        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:
1900    def using(
1901        self,
1902        *expressions: t.Optional[ExpOrStr],
1903        append: bool = True,
1904        dialect: DialectType = None,
1905        copy: bool = True,
1906        **opts,
1907    ) -> Join:
1908        """
1909        Append to or set the USING expressions.
1910
1911        Example:
1912            >>> import sqlglot
1913            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1914            'JOIN x USING (foo, bla)'
1915
1916        Args:
1917            *expressions: the SQL code strings to parse.
1918                If an `Expression` instance is passed, it will be used as-is.
1919            append: if `True`, concatenate the new expressions to the existing "using" list.
1920                Otherwise, this resets the expression.
1921            dialect: the dialect used to parse the input expressions.
1922            copy: if `False`, modify this expression instance in-place.
1923            opts: other options to use to parse the input expressions.
1924
1925        Returns:
1926            The modified Join expression.
1927        """
1928        join = _apply_list_builder(
1929            *expressions,
1930            instance=self,
1931            arg="using",
1932            append=append,
1933            dialect=dialect,
1934            copy=copy,
1935            **opts,
1936        )
1937
1938        if join.kind == "CROSS":
1939            join.set("kind", None)
1940
1941        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):
1944class Lateral(UDTF):
1945    arg_types = {
1946        "this": True,
1947        "view": False,
1948        "outer": False,
1949        "alias": False,
1950        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
1951    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
1954class MatchRecognize(Expression):
1955    arg_types = {
1956        "partition_by": False,
1957        "order": False,
1958        "measures": False,
1959        "rows": False,
1960        "after": False,
1961        "pattern": False,
1962        "define": False,
1963        "alias": False,
1964    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
1969class Final(Expression):
1970    pass
key = 'final'
class Offset(Expression):
1973class Offset(Expression):
1974    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'offset'
class Order(Expression):
1977class Order(Expression):
1978    arg_types = {
1979        "this": False,
1980        "expressions": True,
1981        "interpolate": False,
1982        "siblings": False,
1983    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
1987class WithFill(Expression):
1988    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
1993class Cluster(Order):
1994    pass
key = 'cluster'
class Distribute(Order):
1997class Distribute(Order):
1998    pass
key = 'distribute'
class Sort(Order):
2001class Sort(Order):
2002    pass
key = 'sort'
class Ordered(Expression):
2005class Ordered(Expression):
2006    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):
2009class Property(Expression):
2010    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2013class AlgorithmProperty(Property):
2014    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2017class AutoIncrementProperty(Property):
2018    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2022class AutoRefreshProperty(Property):
2023    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BlockCompressionProperty(Property):
2026class BlockCompressionProperty(Property):
2027    arg_types = {
2028        "autotemp": False,
2029        "always": False,
2030        "default": False,
2031        "manual": False,
2032        "never": False,
2033    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2036class CharacterSetProperty(Property):
2037    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2040class ChecksumProperty(Property):
2041    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2044class CollateProperty(Property):
2045    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2048class CopyGrantsProperty(Property):
2049    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2052class DataBlocksizeProperty(Property):
2053    arg_types = {
2054        "size": False,
2055        "units": False,
2056        "minimum": False,
2057        "maximum": False,
2058        "default": False,
2059    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2062class DefinerProperty(Property):
2063    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2066class DistKeyProperty(Property):
2067    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2070class DistStyleProperty(Property):
2071    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2074class EngineProperty(Property):
2075    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2078class HeapProperty(Property):
2079    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2082class ToTableProperty(Property):
2083    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2086class ExecuteAsProperty(Property):
2087    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2090class ExternalProperty(Property):
2091    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2094class FallbackProperty(Property):
2095    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2098class FileFormatProperty(Property):
2099    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2102class FreespaceProperty(Property):
2103    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InheritsProperty(Property):
2106class InheritsProperty(Property):
2107    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2110class InputModelProperty(Property):
2111    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2114class OutputModelProperty(Property):
2115    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2118class IsolatedLoadingProperty(Property):
2119    arg_types = {
2120        "no": False,
2121        "concurrent": False,
2122        "for_all": False,
2123        "for_insert": False,
2124        "for_none": False,
2125    }
arg_types = {'no': False, 'concurrent': False, 'for_all': False, 'for_insert': False, 'for_none': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2128class JournalProperty(Property):
2129    arg_types = {
2130        "no": False,
2131        "dual": False,
2132        "before": False,
2133        "local": False,
2134        "after": False,
2135    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2138class LanguageProperty(Property):
2139    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2143class ClusteredByProperty(Property):
2144    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2147class DictProperty(Property):
2148    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2151class DictSubProperty(Property):
2152    pass
key = 'dictsubproperty'
class DictRange(Property):
2155class DictRange(Property):
2156    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2161class OnCluster(Property):
2162    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2165class LikeProperty(Property):
2166    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2169class LocationProperty(Property):
2170    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockingProperty(Property):
2173class LockingProperty(Property):
2174    arg_types = {
2175        "this": False,
2176        "kind": True,
2177        "for_or_in": False,
2178        "lock_type": True,
2179        "override": False,
2180    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2183class LogProperty(Property):
2184    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2187class MaterializedProperty(Property):
2188    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2191class MergeBlockRatioProperty(Property):
2192    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):
2195class NoPrimaryIndexProperty(Property):
2196    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2199class OnProperty(Property):
2200    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2203class OnCommitProperty(Property):
2204    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2207class PartitionedByProperty(Property):
2208    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2212class PartitionBoundSpec(Expression):
2213    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2214    arg_types = {
2215        "this": False,
2216        "expression": False,
2217        "from_expressions": False,
2218        "to_expressions": False,
2219    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2222class PartitionedOfProperty(Property):
2223    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2224    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2227class RemoteWithConnectionModelProperty(Property):
2228    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2231class ReturnsProperty(Property):
2232    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2235class RowFormatProperty(Property):
2236    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2239class RowFormatDelimitedProperty(Property):
2240    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2241    arg_types = {
2242        "fields": False,
2243        "escaped": False,
2244        "collection_items": False,
2245        "map_keys": False,
2246        "lines": False,
2247        "null": False,
2248        "serde": False,
2249    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2252class RowFormatSerdeProperty(Property):
2253    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2257class QueryTransform(Expression):
2258    arg_types = {
2259        "expressions": True,
2260        "command_script": True,
2261        "schema": False,
2262        "row_format_before": False,
2263        "record_writer": False,
2264        "row_format_after": False,
2265        "record_reader": False,
2266    }
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):
2269class SampleProperty(Property):
2270    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2273class SchemaCommentProperty(Property):
2274    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2277class SerdeProperties(Property):
2278    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2281class SetProperty(Property):
2282    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SetConfigProperty(Property):
2285class SetConfigProperty(Property):
2286    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2289class SettingsProperty(Property):
2290    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2293class SortKeyProperty(Property):
2294    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2297class SqlReadWriteProperty(Property):
2298    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2301class SqlSecurityProperty(Property):
2302    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2305class StabilityProperty(Property):
2306    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2309class TemporaryProperty(Property):
2310    arg_types = {}
arg_types = {}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2313class TransformModelProperty(Property):
2314    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2317class TransientProperty(Property):
2318    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2321class VolatileProperty(Property):
2322    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2325class WithDataProperty(Property):
2326    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2329class WithJournalTableProperty(Property):
2330    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2333class WithSystemVersioningProperty(Property):
2334    # this -> history table name, expression -> data consistency check
2335    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2338class Properties(Expression):
2339    arg_types = {"expressions": True}
2340
2341    NAME_TO_PROPERTY = {
2342        "ALGORITHM": AlgorithmProperty,
2343        "AUTO_INCREMENT": AutoIncrementProperty,
2344        "CHARACTER SET": CharacterSetProperty,
2345        "CLUSTERED_BY": ClusteredByProperty,
2346        "COLLATE": CollateProperty,
2347        "COMMENT": SchemaCommentProperty,
2348        "DEFINER": DefinerProperty,
2349        "DISTKEY": DistKeyProperty,
2350        "DISTSTYLE": DistStyleProperty,
2351        "ENGINE": EngineProperty,
2352        "EXECUTE AS": ExecuteAsProperty,
2353        "FORMAT": FileFormatProperty,
2354        "LANGUAGE": LanguageProperty,
2355        "LOCATION": LocationProperty,
2356        "PARTITIONED_BY": PartitionedByProperty,
2357        "RETURNS": ReturnsProperty,
2358        "ROW_FORMAT": RowFormatProperty,
2359        "SORTKEY": SortKeyProperty,
2360    }
2361
2362    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2363
2364    # CREATE property locations
2365    # Form: schema specified
2366    #   create [POST_CREATE]
2367    #     table a [POST_NAME]
2368    #     (b int) [POST_SCHEMA]
2369    #     with ([POST_WITH])
2370    #     index (b) [POST_INDEX]
2371    #
2372    # Form: alias selection
2373    #   create [POST_CREATE]
2374    #     table a [POST_NAME]
2375    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2376    #     index (c) [POST_INDEX]
2377    class Location(AutoName):
2378        POST_CREATE = auto()
2379        POST_NAME = auto()
2380        POST_SCHEMA = auto()
2381        POST_WITH = auto()
2382        POST_ALIAS = auto()
2383        POST_EXPRESSION = auto()
2384        POST_INDEX = auto()
2385        UNSUPPORTED = auto()
2386
2387    @classmethod
2388    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2389        expressions = []
2390        for key, value in properties_dict.items():
2391            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2392            if property_cls:
2393                expressions.append(property_cls(this=convert(value)))
2394            else:
2395                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2396
2397        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'>, '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 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
2387    @classmethod
2388    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2389        expressions = []
2390        for key, value in properties_dict.items():
2391            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2392            if property_cls:
2393                expressions.append(property_cls(this=convert(value)))
2394            else:
2395                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2396
2397        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2377    class Location(AutoName):
2378        POST_CREATE = auto()
2379        POST_NAME = auto()
2380        POST_SCHEMA = auto()
2381        POST_WITH = auto()
2382        POST_ALIAS = auto()
2383        POST_EXPRESSION = auto()
2384        POST_INDEX = auto()
2385        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):
2400class Qualify(Expression):
2401    pass
key = 'qualify'
class InputOutputFormat(Expression):
2404class InputOutputFormat(Expression):
2405    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2409class Return(Expression):
2410    pass
key = 'return'
class Reference(Expression):
2413class Reference(Expression):
2414    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2417class Tuple(Expression):
2418    arg_types = {"expressions": False}
2419
2420    def isin(
2421        self,
2422        *expressions: t.Any,
2423        query: t.Optional[ExpOrStr] = None,
2424        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2425        copy: bool = True,
2426        **opts,
2427    ) -> In:
2428        return In(
2429            this=maybe_copy(self, copy),
2430            expressions=[convert(e, copy=copy) for e in expressions],
2431            query=maybe_parse(query, copy=copy, **opts) if query else None,
2432            unnest=Unnest(
2433                expressions=[
2434                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2435                ]
2436            )
2437            if unnest
2438            else None,
2439        )
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:
2420    def isin(
2421        self,
2422        *expressions: t.Any,
2423        query: t.Optional[ExpOrStr] = None,
2424        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2425        copy: bool = True,
2426        **opts,
2427    ) -> In:
2428        return In(
2429            this=maybe_copy(self, copy),
2430            expressions=[convert(e, copy=copy) for e in expressions],
2431            query=maybe_parse(query, copy=copy, **opts) if query else None,
2432            unnest=Unnest(
2433                expressions=[
2434                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2435                ]
2436            )
2437            if unnest
2438            else None,
2439        )
key = 'tuple'
class Subqueryable(Unionable):
2442class Subqueryable(Unionable):
2443    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2444        """
2445        Convert this expression to an aliased expression that can be used as a Subquery.
2446
2447        Example:
2448            >>> subquery = Select().select("x").from_("tbl").subquery()
2449            >>> Select().select("x").from_(subquery).sql()
2450            'SELECT x FROM (SELECT x FROM tbl)'
2451
2452        Args:
2453            alias (str | Identifier): an optional alias for the subquery
2454            copy (bool): if `False`, modify this expression instance in-place.
2455
2456        Returns:
2457            Alias: the subquery
2458        """
2459        instance = maybe_copy(self, copy)
2460        if not isinstance(alias, Expression):
2461            alias = TableAlias(this=to_identifier(alias)) if alias else None
2462
2463        return Subquery(this=instance, alias=alias)
2464
2465    def limit(
2466        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2467    ) -> Select:
2468        raise NotImplementedError
2469
2470    @property
2471    def ctes(self):
2472        with_ = self.args.get("with")
2473        if not with_:
2474            return []
2475        return with_.expressions
2476
2477    @property
2478    def selects(self) -> t.List[Expression]:
2479        raise NotImplementedError("Subqueryable objects must implement `selects`")
2480
2481    @property
2482    def named_selects(self) -> t.List[str]:
2483        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2484
2485    def select(
2486        self,
2487        *expressions: t.Optional[ExpOrStr],
2488        append: bool = True,
2489        dialect: DialectType = None,
2490        copy: bool = True,
2491        **opts,
2492    ) -> Subqueryable:
2493        raise NotImplementedError("Subqueryable objects must implement `select`")
2494
2495    def with_(
2496        self,
2497        alias: ExpOrStr,
2498        as_: ExpOrStr,
2499        recursive: t.Optional[bool] = None,
2500        append: bool = True,
2501        dialect: DialectType = None,
2502        copy: bool = True,
2503        **opts,
2504    ) -> Subqueryable:
2505        """
2506        Append to or set the common table expressions.
2507
2508        Example:
2509            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2510            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2511
2512        Args:
2513            alias: the SQL code string to parse as the table name.
2514                If an `Expression` instance is passed, this is used as-is.
2515            as_: the SQL code string to parse as the table expression.
2516                If an `Expression` instance is passed, it will be used as-is.
2517            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2518            append: if `True`, add to any existing expressions.
2519                Otherwise, this resets the expressions.
2520            dialect: the dialect used to parse the input expression.
2521            copy: if `False`, modify this expression instance in-place.
2522            opts: other options to use to parse the input expressions.
2523
2524        Returns:
2525            The modified expression.
2526        """
2527        return _apply_cte_builder(
2528            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2529        )
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
2443    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2444        """
2445        Convert this expression to an aliased expression that can be used as a Subquery.
2446
2447        Example:
2448            >>> subquery = Select().select("x").from_("tbl").subquery()
2449            >>> Select().select("x").from_(subquery).sql()
2450            'SELECT x FROM (SELECT x FROM tbl)'
2451
2452        Args:
2453            alias (str | Identifier): an optional alias for the subquery
2454            copy (bool): if `False`, modify this expression instance in-place.
2455
2456        Returns:
2457            Alias: the subquery
2458        """
2459        instance = maybe_copy(self, copy)
2460        if not isinstance(alias, Expression):
2461            alias = TableAlias(this=to_identifier(alias)) if alias else None
2462
2463        return Subquery(this=instance, alias=alias)

Convert this expression to an aliased expression that can be used as a Subquery.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias (str | Identifier): an optional alias for the subquery
  • copy (bool): if False, modify this expression instance in-place.
Returns:

Alias: the subquery

def limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
2465    def limit(
2466        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2467    ) -> Select:
2468        raise NotImplementedError
ctes
2470    @property
2471    def ctes(self):
2472        with_ = self.args.get("with")
2473        if not with_:
2474            return []
2475        return with_.expressions
selects: List[Expression]
2477    @property
2478    def selects(self) -> t.List[Expression]:
2479        raise NotImplementedError("Subqueryable objects must implement `selects`")
named_selects: List[str]
2481    @property
2482    def named_selects(self) -> t.List[str]:
2483        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
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) -> Subqueryable:
2485    def select(
2486        self,
2487        *expressions: t.Optional[ExpOrStr],
2488        append: bool = True,
2489        dialect: DialectType = None,
2490        copy: bool = True,
2491        **opts,
2492    ) -> Subqueryable:
2493        raise NotImplementedError("Subqueryable objects must implement `select`")
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) -> Subqueryable:
2495    def with_(
2496        self,
2497        alias: ExpOrStr,
2498        as_: ExpOrStr,
2499        recursive: t.Optional[bool] = None,
2500        append: bool = True,
2501        dialect: DialectType = None,
2502        copy: bool = True,
2503        **opts,
2504    ) -> Subqueryable:
2505        """
2506        Append to or set the common table expressions.
2507
2508        Example:
2509            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2510            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2511
2512        Args:
2513            alias: the SQL code string to parse as the table name.
2514                If an `Expression` instance is passed, this is used as-is.
2515            as_: the SQL code string to parse as the table expression.
2516                If an `Expression` instance is passed, it will be used as-is.
2517            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2518            append: if `True`, add to any existing expressions.
2519                Otherwise, this resets the expressions.
2520            dialect: the dialect used to parse the input expression.
2521            copy: if `False`, modify this expression instance in-place.
2522            opts: other options to use to parse the input expressions.
2523
2524        Returns:
2525            The modified expression.
2526        """
2527        return _apply_cte_builder(
2528            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2529        )

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.

key = 'subqueryable'
QUERY_MODIFIERS = {'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': 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}
class WithTableHint(Expression):
2557class WithTableHint(Expression):
2558    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2562class IndexTableHint(Expression):
2563    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2567class HistoricalData(Expression):
2568    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2571class Table(Expression):
2572    arg_types = {
2573        "this": True,
2574        "alias": False,
2575        "db": False,
2576        "catalog": False,
2577        "laterals": False,
2578        "joins": False,
2579        "pivots": False,
2580        "hints": False,
2581        "system_time": False,
2582        "version": False,
2583        "format": False,
2584        "pattern": False,
2585        "ordinality": False,
2586        "when": False,
2587    }
2588
2589    @property
2590    def name(self) -> str:
2591        if isinstance(self.this, Func):
2592            return ""
2593        return self.this.name
2594
2595    @property
2596    def db(self) -> str:
2597        return self.text("db")
2598
2599    @property
2600    def catalog(self) -> str:
2601        return self.text("catalog")
2602
2603    @property
2604    def selects(self) -> t.List[Expression]:
2605        return []
2606
2607    @property
2608    def named_selects(self) -> t.List[str]:
2609        return []
2610
2611    @property
2612    def parts(self) -> t.List[Expression]:
2613        """Return the parts of a table in order catalog, db, table."""
2614        parts: t.List[Expression] = []
2615
2616        for arg in ("catalog", "db", "this"):
2617            part = self.args.get(arg)
2618
2619            if isinstance(part, Dot):
2620                parts.extend(part.flatten())
2621            elif isinstance(part, Expression):
2622                parts.append(part)
2623
2624        return parts
2625
2626    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2627        parts = self.parts
2628        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2629        alias = self.args.get("alias")
2630        if alias:
2631            col = alias_(col, alias.this, copy=copy)
2632        return col
arg_types = {'this': True, '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}
name: str
2589    @property
2590    def name(self) -> str:
2591        if isinstance(self.this, Func):
2592            return ""
2593        return self.this.name
db: str
2595    @property
2596    def db(self) -> str:
2597        return self.text("db")
catalog: str
2599    @property
2600    def catalog(self) -> str:
2601        return self.text("catalog")
selects: List[Expression]
2603    @property
2604    def selects(self) -> t.List[Expression]:
2605        return []
named_selects: List[str]
2607    @property
2608    def named_selects(self) -> t.List[str]:
2609        return []
parts: List[Expression]
2611    @property
2612    def parts(self) -> t.List[Expression]:
2613        """Return the parts of a table in order catalog, db, table."""
2614        parts: t.List[Expression] = []
2615
2616        for arg in ("catalog", "db", "this"):
2617            part = self.args.get(arg)
2618
2619            if isinstance(part, Dot):
2620                parts.extend(part.flatten())
2621            elif isinstance(part, Expression):
2622                parts.append(part)
2623
2624        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2626    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2627        parts = self.parts
2628        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
2629        alias = self.args.get("alias")
2630        if alias:
2631            col = alias_(col, alias.this, copy=copy)
2632        return col
key = 'table'
class Union(Subqueryable):
2635class Union(Subqueryable):
2636    arg_types = {
2637        "with": False,
2638        "this": True,
2639        "expression": True,
2640        "distinct": False,
2641        "by_name": False,
2642        **QUERY_MODIFIERS,
2643    }
2644
2645    def limit(
2646        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2647    ) -> Select:
2648        """
2649        Set the LIMIT expression.
2650
2651        Example:
2652            >>> select("1").union(select("1")).limit(1).sql()
2653            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2654
2655        Args:
2656            expression: the SQL code string to parse.
2657                This can also be an integer.
2658                If a `Limit` instance is passed, this is used as-is.
2659                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2660            dialect: the dialect used to parse the input expression.
2661            copy: if `False`, modify this expression instance in-place.
2662            opts: other options to use to parse the input expressions.
2663
2664        Returns:
2665            The limited subqueryable.
2666        """
2667        return (
2668            select("*")
2669            .from_(self.subquery(alias="_l_0", copy=copy))
2670            .limit(expression, dialect=dialect, copy=False, **opts)
2671        )
2672
2673    def select(
2674        self,
2675        *expressions: t.Optional[ExpOrStr],
2676        append: bool = True,
2677        dialect: DialectType = None,
2678        copy: bool = True,
2679        **opts,
2680    ) -> Union:
2681        """Append to or set the SELECT of the union recursively.
2682
2683        Example:
2684            >>> from sqlglot import parse_one
2685            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2686            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2687
2688        Args:
2689            *expressions: the SQL code strings to parse.
2690                If an `Expression` instance is passed, it will be used as-is.
2691            append: if `True`, add to any existing expressions.
2692                Otherwise, this resets the expressions.
2693            dialect: the dialect used to parse the input expressions.
2694            copy: if `False`, modify this expression instance in-place.
2695            opts: other options to use to parse the input expressions.
2696
2697        Returns:
2698            Union: the modified expression.
2699        """
2700        this = self.copy() if copy else self
2701        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2702        this.expression.unnest().select(
2703            *expressions, append=append, dialect=dialect, copy=False, **opts
2704        )
2705        return this
2706
2707    @property
2708    def named_selects(self) -> t.List[str]:
2709        return self.this.unnest().named_selects
2710
2711    @property
2712    def is_star(self) -> bool:
2713        return self.this.is_star or self.expression.is_star
2714
2715    @property
2716    def selects(self) -> t.List[Expression]:
2717        return self.this.unnest().selects
2718
2719    @property
2720    def left(self) -> Expression:
2721        return self.this
2722
2723    @property
2724    def right(self) -> Expression:
2725        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, '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}
def limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
2645    def limit(
2646        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2647    ) -> Select:
2648        """
2649        Set the LIMIT expression.
2650
2651        Example:
2652            >>> select("1").union(select("1")).limit(1).sql()
2653            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2654
2655        Args:
2656            expression: the SQL code string to parse.
2657                This can also be an integer.
2658                If a `Limit` instance is passed, this is used as-is.
2659                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2660            dialect: the dialect used to parse the input expression.
2661            copy: if `False`, modify this expression instance in-place.
2662            opts: other options to use to parse the input expressions.
2663
2664        Returns:
2665            The limited subqueryable.
2666        """
2667        return (
2668            select("*")
2669            .from_(self.subquery(alias="_l_0", copy=copy))
2670            .limit(expression, dialect=dialect, copy=False, **opts)
2671        )

Set the LIMIT expression.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, this is 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:

The limited subqueryable.

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) -> Union:
2673    def select(
2674        self,
2675        *expressions: t.Optional[ExpOrStr],
2676        append: bool = True,
2677        dialect: DialectType = None,
2678        copy: bool = True,
2679        **opts,
2680    ) -> Union:
2681        """Append to or set the SELECT of the union recursively.
2682
2683        Example:
2684            >>> from sqlglot import parse_one
2685            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2686            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2687
2688        Args:
2689            *expressions: the SQL code strings to parse.
2690                If an `Expression` instance is passed, it will be used as-is.
2691            append: if `True`, add to any existing expressions.
2692                Otherwise, this resets the expressions.
2693            dialect: the dialect used to parse the input expressions.
2694            copy: if `False`, modify this expression instance in-place.
2695            opts: other options to use to parse the input expressions.
2696
2697        Returns:
2698            Union: the modified expression.
2699        """
2700        this = self.copy() if copy else self
2701        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2702        this.expression.unnest().select(
2703            *expressions, append=append, dialect=dialect, copy=False, **opts
2704        )
2705        return this

Append to or set the SELECT of the union recursively.

Example:
>>> from sqlglot import parse_one
>>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM 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:

Union: the modified expression.

named_selects: List[str]
2707    @property
2708    def named_selects(self) -> t.List[str]:
2709        return self.this.unnest().named_selects
is_star: bool
2711    @property
2712    def is_star(self) -> bool:
2713        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
2715    @property
2716    def selects(self) -> t.List[Expression]:
2717        return self.this.unnest().selects
left: Expression
2719    @property
2720    def left(self) -> Expression:
2721        return self.this
right: Expression
2723    @property
2724    def right(self) -> Expression:
2725        return self.expression
key = 'union'
class Except(Union):
2728class Except(Union):
2729    pass
key = 'except'
class Intersect(Union):
2732class Intersect(Union):
2733    pass
key = 'intersect'
class Unnest(UDTF):
2736class Unnest(UDTF):
2737    arg_types = {
2738        "expressions": True,
2739        "alias": False,
2740        "offset": False,
2741    }
2742
2743    @property
2744    def selects(self) -> t.List[Expression]:
2745        columns = super().selects
2746        offset = self.args.get("offset")
2747        if offset:
2748            columns = columns + [to_identifier("offset") if offset is True else offset]
2749        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
2743    @property
2744    def selects(self) -> t.List[Expression]:
2745        columns = super().selects
2746        offset = self.args.get("offset")
2747        if offset:
2748            columns = columns + [to_identifier("offset") if offset is True else offset]
2749        return columns
key = 'unnest'
class Update(Expression):
2752class Update(Expression):
2753    arg_types = {
2754        "with": False,
2755        "this": False,
2756        "expressions": True,
2757        "from": False,
2758        "where": False,
2759        "returning": False,
2760        "order": False,
2761        "limit": False,
2762    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
2765class Values(UDTF):
2766    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
2769class Var(Expression):
2770    pass
key = 'var'
class Version(Expression):
2773class Version(Expression):
2774    """
2775    Time travel, iceberg, bigquery etc
2776    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
2777    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
2778    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
2779    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
2780    this is either TIMESTAMP or VERSION
2781    kind is ("AS OF", "BETWEEN")
2782    """
2783
2784    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
2787class Schema(Expression):
2788    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
2793class Lock(Expression):
2794    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Subqueryable):
2797class Select(Subqueryable):
2798    arg_types = {
2799        "with": False,
2800        "kind": False,
2801        "expressions": False,
2802        "hint": False,
2803        "distinct": False,
2804        "into": False,
2805        "from": False,
2806        **QUERY_MODIFIERS,
2807    }
2808
2809    def from_(
2810        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2811    ) -> Select:
2812        """
2813        Set the FROM expression.
2814
2815        Example:
2816            >>> Select().from_("tbl").select("x").sql()
2817            'SELECT x FROM tbl'
2818
2819        Args:
2820            expression : the SQL code strings to parse.
2821                If a `From` instance is passed, this is used as-is.
2822                If another `Expression` instance is passed, it will be wrapped in a `From`.
2823            dialect: the dialect used to parse the input expression.
2824            copy: if `False`, modify this expression instance in-place.
2825            opts: other options to use to parse the input expressions.
2826
2827        Returns:
2828            The modified Select expression.
2829        """
2830        return _apply_builder(
2831            expression=expression,
2832            instance=self,
2833            arg="from",
2834            into=From,
2835            prefix="FROM",
2836            dialect=dialect,
2837            copy=copy,
2838            **opts,
2839        )
2840
2841    def group_by(
2842        self,
2843        *expressions: t.Optional[ExpOrStr],
2844        append: bool = True,
2845        dialect: DialectType = None,
2846        copy: bool = True,
2847        **opts,
2848    ) -> Select:
2849        """
2850        Set the GROUP BY expression.
2851
2852        Example:
2853            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2854            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2855
2856        Args:
2857            *expressions: the SQL code strings to parse.
2858                If a `Group` instance is passed, this is used as-is.
2859                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2860                If nothing is passed in then a group by is not applied to the expression
2861            append: if `True`, add to any existing expressions.
2862                Otherwise, this flattens all the `Group` expression into a single expression.
2863            dialect: the dialect used to parse the input expression.
2864            copy: if `False`, modify this expression instance in-place.
2865            opts: other options to use to parse the input expressions.
2866
2867        Returns:
2868            The modified Select expression.
2869        """
2870        if not expressions:
2871            return self if not copy else self.copy()
2872
2873        return _apply_child_list_builder(
2874            *expressions,
2875            instance=self,
2876            arg="group",
2877            append=append,
2878            copy=copy,
2879            prefix="GROUP BY",
2880            into=Group,
2881            dialect=dialect,
2882            **opts,
2883        )
2884
2885    def order_by(
2886        self,
2887        *expressions: t.Optional[ExpOrStr],
2888        append: bool = True,
2889        dialect: DialectType = None,
2890        copy: bool = True,
2891        **opts,
2892    ) -> Select:
2893        """
2894        Set the ORDER BY expression.
2895
2896        Example:
2897            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2898            'SELECT x FROM tbl ORDER BY x DESC'
2899
2900        Args:
2901            *expressions: the SQL code strings to parse.
2902                If a `Group` instance is passed, this is used as-is.
2903                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2904            append: if `True`, add to any existing expressions.
2905                Otherwise, this flattens all the `Order` expression into a single expression.
2906            dialect: the dialect used to parse the input expression.
2907            copy: if `False`, modify this expression instance in-place.
2908            opts: other options to use to parse the input expressions.
2909
2910        Returns:
2911            The modified Select expression.
2912        """
2913        return _apply_child_list_builder(
2914            *expressions,
2915            instance=self,
2916            arg="order",
2917            append=append,
2918            copy=copy,
2919            prefix="ORDER BY",
2920            into=Order,
2921            dialect=dialect,
2922            **opts,
2923        )
2924
2925    def sort_by(
2926        self,
2927        *expressions: t.Optional[ExpOrStr],
2928        append: bool = True,
2929        dialect: DialectType = None,
2930        copy: bool = True,
2931        **opts,
2932    ) -> Select:
2933        """
2934        Set the SORT BY expression.
2935
2936        Example:
2937            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2938            'SELECT x FROM tbl SORT BY x DESC'
2939
2940        Args:
2941            *expressions: the SQL code strings to parse.
2942                If a `Group` instance is passed, this is used as-is.
2943                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2944            append: if `True`, add to any existing expressions.
2945                Otherwise, this flattens all the `Order` expression into a single expression.
2946            dialect: the dialect used to parse the input expression.
2947            copy: if `False`, modify this expression instance in-place.
2948            opts: other options to use to parse the input expressions.
2949
2950        Returns:
2951            The modified Select expression.
2952        """
2953        return _apply_child_list_builder(
2954            *expressions,
2955            instance=self,
2956            arg="sort",
2957            append=append,
2958            copy=copy,
2959            prefix="SORT BY",
2960            into=Sort,
2961            dialect=dialect,
2962            **opts,
2963        )
2964
2965    def cluster_by(
2966        self,
2967        *expressions: t.Optional[ExpOrStr],
2968        append: bool = True,
2969        dialect: DialectType = None,
2970        copy: bool = True,
2971        **opts,
2972    ) -> Select:
2973        """
2974        Set the CLUSTER BY expression.
2975
2976        Example:
2977            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2978            'SELECT x FROM tbl CLUSTER BY x DESC'
2979
2980        Args:
2981            *expressions: the SQL code strings to parse.
2982                If a `Group` instance is passed, this is used as-is.
2983                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2984            append: if `True`, add to any existing expressions.
2985                Otherwise, this flattens all the `Order` expression into a single expression.
2986            dialect: the dialect used to parse the input expression.
2987            copy: if `False`, modify this expression instance in-place.
2988            opts: other options to use to parse the input expressions.
2989
2990        Returns:
2991            The modified Select expression.
2992        """
2993        return _apply_child_list_builder(
2994            *expressions,
2995            instance=self,
2996            arg="cluster",
2997            append=append,
2998            copy=copy,
2999            prefix="CLUSTER BY",
3000            into=Cluster,
3001            dialect=dialect,
3002            **opts,
3003        )
3004
3005    def limit(
3006        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3007    ) -> Select:
3008        """
3009        Set the LIMIT expression.
3010
3011        Example:
3012            >>> Select().from_("tbl").select("x").limit(10).sql()
3013            'SELECT x FROM tbl LIMIT 10'
3014
3015        Args:
3016            expression: the SQL code string to parse.
3017                This can also be an integer.
3018                If a `Limit` instance is passed, this is used as-is.
3019                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
3020            dialect: the dialect used to parse the input expression.
3021            copy: if `False`, modify this expression instance in-place.
3022            opts: other options to use to parse the input expressions.
3023
3024        Returns:
3025            Select: the modified expression.
3026        """
3027        return _apply_builder(
3028            expression=expression,
3029            instance=self,
3030            arg="limit",
3031            into=Limit,
3032            prefix="LIMIT",
3033            dialect=dialect,
3034            copy=copy,
3035            into_arg="expression",
3036            **opts,
3037        )
3038
3039    def offset(
3040        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3041    ) -> Select:
3042        """
3043        Set the OFFSET expression.
3044
3045        Example:
3046            >>> Select().from_("tbl").select("x").offset(10).sql()
3047            'SELECT x FROM tbl OFFSET 10'
3048
3049        Args:
3050            expression: the SQL code string to parse.
3051                This can also be an integer.
3052                If a `Offset` instance is passed, this is used as-is.
3053                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3054            dialect: the dialect used to parse the input expression.
3055            copy: if `False`, modify this expression instance in-place.
3056            opts: other options to use to parse the input expressions.
3057
3058        Returns:
3059            The modified Select expression.
3060        """
3061        return _apply_builder(
3062            expression=expression,
3063            instance=self,
3064            arg="offset",
3065            into=Offset,
3066            prefix="OFFSET",
3067            dialect=dialect,
3068            copy=copy,
3069            into_arg="expression",
3070            **opts,
3071        )
3072
3073    def select(
3074        self,
3075        *expressions: t.Optional[ExpOrStr],
3076        append: bool = True,
3077        dialect: DialectType = None,
3078        copy: bool = True,
3079        **opts,
3080    ) -> Select:
3081        """
3082        Append to or set the SELECT expressions.
3083
3084        Example:
3085            >>> Select().select("x", "y").sql()
3086            'SELECT x, y'
3087
3088        Args:
3089            *expressions: the SQL code strings to parse.
3090                If an `Expression` instance is passed, it will be used as-is.
3091            append: if `True`, add to any existing expressions.
3092                Otherwise, this resets the expressions.
3093            dialect: the dialect used to parse the input expressions.
3094            copy: if `False`, modify this expression instance in-place.
3095            opts: other options to use to parse the input expressions.
3096
3097        Returns:
3098            The modified Select expression.
3099        """
3100        return _apply_list_builder(
3101            *expressions,
3102            instance=self,
3103            arg="expressions",
3104            append=append,
3105            dialect=dialect,
3106            copy=copy,
3107            **opts,
3108        )
3109
3110    def lateral(
3111        self,
3112        *expressions: t.Optional[ExpOrStr],
3113        append: bool = True,
3114        dialect: DialectType = None,
3115        copy: bool = True,
3116        **opts,
3117    ) -> Select:
3118        """
3119        Append to or set the LATERAL expressions.
3120
3121        Example:
3122            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3123            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3124
3125        Args:
3126            *expressions: the SQL code strings to parse.
3127                If an `Expression` instance is passed, it will be used as-is.
3128            append: if `True`, add to any existing expressions.
3129                Otherwise, this resets the expressions.
3130            dialect: the dialect used to parse the input expressions.
3131            copy: if `False`, modify this expression instance in-place.
3132            opts: other options to use to parse the input expressions.
3133
3134        Returns:
3135            The modified Select expression.
3136        """
3137        return _apply_list_builder(
3138            *expressions,
3139            instance=self,
3140            arg="laterals",
3141            append=append,
3142            into=Lateral,
3143            prefix="LATERAL VIEW",
3144            dialect=dialect,
3145            copy=copy,
3146            **opts,
3147        )
3148
3149    def join(
3150        self,
3151        expression: ExpOrStr,
3152        on: t.Optional[ExpOrStr] = None,
3153        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3154        append: bool = True,
3155        join_type: t.Optional[str] = None,
3156        join_alias: t.Optional[Identifier | str] = None,
3157        dialect: DialectType = None,
3158        copy: bool = True,
3159        **opts,
3160    ) -> Select:
3161        """
3162        Append to or set the JOIN expressions.
3163
3164        Example:
3165            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3166            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3167
3168            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3169            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3170
3171            Use `join_type` to change the type of join:
3172
3173            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3174            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3175
3176        Args:
3177            expression: the SQL code string to parse.
3178                If an `Expression` instance is passed, it will be used as-is.
3179            on: optionally specify the join "on" criteria as a SQL string.
3180                If an `Expression` instance is passed, it will be used as-is.
3181            using: optionally specify the join "using" criteria as a SQL string.
3182                If an `Expression` instance is passed, it will be used as-is.
3183            append: if `True`, add to any existing expressions.
3184                Otherwise, this resets the expressions.
3185            join_type: if set, alter the parsed join type.
3186            join_alias: an optional alias for the joined source.
3187            dialect: the dialect used to parse the input expressions.
3188            copy: if `False`, modify this expression instance in-place.
3189            opts: other options to use to parse the input expressions.
3190
3191        Returns:
3192            Select: the modified expression.
3193        """
3194        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3195
3196        try:
3197            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3198        except ParseError:
3199            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3200
3201        join = expression if isinstance(expression, Join) else Join(this=expression)
3202
3203        if isinstance(join.this, Select):
3204            join.this.replace(join.this.subquery())
3205
3206        if join_type:
3207            method: t.Optional[Token]
3208            side: t.Optional[Token]
3209            kind: t.Optional[Token]
3210
3211            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3212
3213            if method:
3214                join.set("method", method.text)
3215            if side:
3216                join.set("side", side.text)
3217            if kind:
3218                join.set("kind", kind.text)
3219
3220        if on:
3221            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3222            join.set("on", on)
3223
3224        if using:
3225            join = _apply_list_builder(
3226                *ensure_list(using),
3227                instance=join,
3228                arg="using",
3229                append=append,
3230                copy=copy,
3231                into=Identifier,
3232                **opts,
3233            )
3234
3235        if join_alias:
3236            join.set("this", alias_(join.this, join_alias, table=True))
3237
3238        return _apply_list_builder(
3239            join,
3240            instance=self,
3241            arg="joins",
3242            append=append,
3243            copy=copy,
3244            **opts,
3245        )
3246
3247    def where(
3248        self,
3249        *expressions: t.Optional[ExpOrStr],
3250        append: bool = True,
3251        dialect: DialectType = None,
3252        copy: bool = True,
3253        **opts,
3254    ) -> Select:
3255        """
3256        Append to or set the WHERE expressions.
3257
3258        Example:
3259            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3260            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3261
3262        Args:
3263            *expressions: the SQL code strings to parse.
3264                If an `Expression` instance is passed, it will be used as-is.
3265                Multiple expressions are combined with an AND operator.
3266            append: if `True`, AND the new expressions to any existing expression.
3267                Otherwise, this resets the expression.
3268            dialect: the dialect used to parse the input expressions.
3269            copy: if `False`, modify this expression instance in-place.
3270            opts: other options to use to parse the input expressions.
3271
3272        Returns:
3273            Select: the modified expression.
3274        """
3275        return _apply_conjunction_builder(
3276            *expressions,
3277            instance=self,
3278            arg="where",
3279            append=append,
3280            into=Where,
3281            dialect=dialect,
3282            copy=copy,
3283            **opts,
3284        )
3285
3286    def having(
3287        self,
3288        *expressions: t.Optional[ExpOrStr],
3289        append: bool = True,
3290        dialect: DialectType = None,
3291        copy: bool = True,
3292        **opts,
3293    ) -> Select:
3294        """
3295        Append to or set the HAVING expressions.
3296
3297        Example:
3298            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3299            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3300
3301        Args:
3302            *expressions: the SQL code strings to parse.
3303                If an `Expression` instance is passed, it will be used as-is.
3304                Multiple expressions are combined with an AND operator.
3305            append: if `True`, AND the new expressions to any existing expression.
3306                Otherwise, this resets the expression.
3307            dialect: the dialect used to parse the input expressions.
3308            copy: if `False`, modify this expression instance in-place.
3309            opts: other options to use to parse the input expressions.
3310
3311        Returns:
3312            The modified Select expression.
3313        """
3314        return _apply_conjunction_builder(
3315            *expressions,
3316            instance=self,
3317            arg="having",
3318            append=append,
3319            into=Having,
3320            dialect=dialect,
3321            copy=copy,
3322            **opts,
3323        )
3324
3325    def window(
3326        self,
3327        *expressions: t.Optional[ExpOrStr],
3328        append: bool = True,
3329        dialect: DialectType = None,
3330        copy: bool = True,
3331        **opts,
3332    ) -> Select:
3333        return _apply_list_builder(
3334            *expressions,
3335            instance=self,
3336            arg="windows",
3337            append=append,
3338            into=Window,
3339            dialect=dialect,
3340            copy=copy,
3341            **opts,
3342        )
3343
3344    def qualify(
3345        self,
3346        *expressions: t.Optional[ExpOrStr],
3347        append: bool = True,
3348        dialect: DialectType = None,
3349        copy: bool = True,
3350        **opts,
3351    ) -> Select:
3352        return _apply_conjunction_builder(
3353            *expressions,
3354            instance=self,
3355            arg="qualify",
3356            append=append,
3357            into=Qualify,
3358            dialect=dialect,
3359            copy=copy,
3360            **opts,
3361        )
3362
3363    def distinct(
3364        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3365    ) -> Select:
3366        """
3367        Set the OFFSET expression.
3368
3369        Example:
3370            >>> Select().from_("tbl").select("x").distinct().sql()
3371            'SELECT DISTINCT x FROM tbl'
3372
3373        Args:
3374            ons: the expressions to distinct on
3375            distinct: whether the Select should be distinct
3376            copy: if `False`, modify this expression instance in-place.
3377
3378        Returns:
3379            Select: the modified expression.
3380        """
3381        instance = maybe_copy(self, copy)
3382        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3383        instance.set("distinct", Distinct(on=on) if distinct else None)
3384        return instance
3385
3386    def ctas(
3387        self,
3388        table: ExpOrStr,
3389        properties: t.Optional[t.Dict] = None,
3390        dialect: DialectType = None,
3391        copy: bool = True,
3392        **opts,
3393    ) -> Create:
3394        """
3395        Convert this expression to a CREATE TABLE AS statement.
3396
3397        Example:
3398            >>> Select().select("*").from_("tbl").ctas("x").sql()
3399            'CREATE TABLE x AS SELECT * FROM tbl'
3400
3401        Args:
3402            table: the SQL code string to parse as the table name.
3403                If another `Expression` instance is passed, it will be used as-is.
3404            properties: an optional mapping of table properties
3405            dialect: the dialect used to parse the input table.
3406            copy: if `False`, modify this expression instance in-place.
3407            opts: other options to use to parse the input table.
3408
3409        Returns:
3410            The new Create expression.
3411        """
3412        instance = maybe_copy(self, copy)
3413        table_expression = maybe_parse(
3414            table,
3415            into=Table,
3416            dialect=dialect,
3417            **opts,
3418        )
3419        properties_expression = None
3420        if properties:
3421            properties_expression = Properties.from_dict(properties)
3422
3423        return Create(
3424            this=table_expression,
3425            kind="TABLE",
3426            expression=instance,
3427            properties=properties_expression,
3428        )
3429
3430    def lock(self, update: bool = True, copy: bool = True) -> Select:
3431        """
3432        Set the locking read mode for this expression.
3433
3434        Examples:
3435            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3436            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3437
3438            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3439            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3440
3441        Args:
3442            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3443            copy: if `False`, modify this expression instance in-place.
3444
3445        Returns:
3446            The modified expression.
3447        """
3448        inst = maybe_copy(self, copy)
3449        inst.set("locks", [Lock(update=update)])
3450
3451        return inst
3452
3453    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3454        """
3455        Set hints for this expression.
3456
3457        Examples:
3458            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3459            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3460
3461        Args:
3462            hints: The SQL code strings to parse as the hints.
3463                If an `Expression` instance is passed, it will be used as-is.
3464            dialect: The dialect used to parse the hints.
3465            copy: If `False`, modify this expression instance in-place.
3466
3467        Returns:
3468            The modified expression.
3469        """
3470        inst = maybe_copy(self, copy)
3471        inst.set(
3472            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3473        )
3474
3475        return inst
3476
3477    @property
3478    def named_selects(self) -> t.List[str]:
3479        return [e.output_name for e in self.expressions if e.alias_or_name]
3480
3481    @property
3482    def is_star(self) -> bool:
3483        return any(expression.is_star for expression in self.expressions)
3484
3485    @property
3486    def selects(self) -> t.List[Expression]:
3487        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, '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}
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:
2809    def from_(
2810        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2811    ) -> Select:
2812        """
2813        Set the FROM expression.
2814
2815        Example:
2816            >>> Select().from_("tbl").select("x").sql()
2817            'SELECT x FROM tbl'
2818
2819        Args:
2820            expression : the SQL code strings to parse.
2821                If a `From` instance is passed, this is used as-is.
2822                If another `Expression` instance is passed, it will be wrapped in a `From`.
2823            dialect: the dialect used to parse the input expression.
2824            copy: if `False`, modify this expression instance in-place.
2825            opts: other options to use to parse the input expressions.
2826
2827        Returns:
2828            The modified Select expression.
2829        """
2830        return _apply_builder(
2831            expression=expression,
2832            instance=self,
2833            arg="from",
2834            into=From,
2835            prefix="FROM",
2836            dialect=dialect,
2837            copy=copy,
2838            **opts,
2839        )

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:
2841    def group_by(
2842        self,
2843        *expressions: t.Optional[ExpOrStr],
2844        append: bool = True,
2845        dialect: DialectType = None,
2846        copy: bool = True,
2847        **opts,
2848    ) -> Select:
2849        """
2850        Set the GROUP BY expression.
2851
2852        Example:
2853            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2854            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2855
2856        Args:
2857            *expressions: the SQL code strings to parse.
2858                If a `Group` instance is passed, this is used as-is.
2859                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2860                If nothing is passed in then a group by is not applied to the expression
2861            append: if `True`, add to any existing expressions.
2862                Otherwise, this flattens all the `Group` expression into a single expression.
2863            dialect: the dialect used to parse the input expression.
2864            copy: if `False`, modify this expression instance in-place.
2865            opts: other options to use to parse the input expressions.
2866
2867        Returns:
2868            The modified Select expression.
2869        """
2870        if not expressions:
2871            return self if not copy else self.copy()
2872
2873        return _apply_child_list_builder(
2874            *expressions,
2875            instance=self,
2876            arg="group",
2877            append=append,
2878            copy=copy,
2879            prefix="GROUP BY",
2880            into=Group,
2881            dialect=dialect,
2882            **opts,
2883        )

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 order_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:
2885    def order_by(
2886        self,
2887        *expressions: t.Optional[ExpOrStr],
2888        append: bool = True,
2889        dialect: DialectType = None,
2890        copy: bool = True,
2891        **opts,
2892    ) -> Select:
2893        """
2894        Set the ORDER BY expression.
2895
2896        Example:
2897            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2898            'SELECT x FROM tbl ORDER BY x DESC'
2899
2900        Args:
2901            *expressions: the SQL code strings to parse.
2902                If a `Group` instance is passed, this is used as-is.
2903                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2904            append: if `True`, add to any existing expressions.
2905                Otherwise, this flattens all the `Order` expression into a single expression.
2906            dialect: the dialect used to parse the input expression.
2907            copy: if `False`, modify this expression instance in-place.
2908            opts: other options to use to parse the input expressions.
2909
2910        Returns:
2911            The modified Select expression.
2912        """
2913        return _apply_child_list_builder(
2914            *expressions,
2915            instance=self,
2916            arg="order",
2917            append=append,
2918            copy=copy,
2919            prefix="ORDER BY",
2920            into=Order,
2921            dialect=dialect,
2922            **opts,
2923        )

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.

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:
2925    def sort_by(
2926        self,
2927        *expressions: t.Optional[ExpOrStr],
2928        append: bool = True,
2929        dialect: DialectType = None,
2930        copy: bool = True,
2931        **opts,
2932    ) -> Select:
2933        """
2934        Set the SORT BY expression.
2935
2936        Example:
2937            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2938            'SELECT x FROM tbl SORT BY x DESC'
2939
2940        Args:
2941            *expressions: the SQL code strings to parse.
2942                If a `Group` instance is passed, this is used as-is.
2943                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2944            append: if `True`, add to any existing expressions.
2945                Otherwise, this flattens all the `Order` expression into a single expression.
2946            dialect: the dialect used to parse the input expression.
2947            copy: if `False`, modify this expression instance in-place.
2948            opts: other options to use to parse the input expressions.
2949
2950        Returns:
2951            The modified Select expression.
2952        """
2953        return _apply_child_list_builder(
2954            *expressions,
2955            instance=self,
2956            arg="sort",
2957            append=append,
2958            copy=copy,
2959            prefix="SORT BY",
2960            into=Sort,
2961            dialect=dialect,
2962            **opts,
2963        )

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:
2965    def cluster_by(
2966        self,
2967        *expressions: t.Optional[ExpOrStr],
2968        append: bool = True,
2969        dialect: DialectType = None,
2970        copy: bool = True,
2971        **opts,
2972    ) -> Select:
2973        """
2974        Set the CLUSTER BY expression.
2975
2976        Example:
2977            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2978            'SELECT x FROM tbl CLUSTER BY x DESC'
2979
2980        Args:
2981            *expressions: the SQL code strings to parse.
2982                If a `Group` instance is passed, this is used as-is.
2983                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2984            append: if `True`, add to any existing expressions.
2985                Otherwise, this flattens all the `Order` expression into a single expression.
2986            dialect: the dialect used to parse the input expression.
2987            copy: if `False`, modify this expression instance in-place.
2988            opts: other options to use to parse the input expressions.
2989
2990        Returns:
2991            The modified Select expression.
2992        """
2993        return _apply_child_list_builder(
2994            *expressions,
2995            instance=self,
2996            arg="cluster",
2997            append=append,
2998            copy=copy,
2999            prefix="CLUSTER BY",
3000            into=Cluster,
3001            dialect=dialect,
3002            **opts,
3003        )

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 limit( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3005    def limit(
3006        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3007    ) -> Select:
3008        """
3009        Set the LIMIT expression.
3010
3011        Example:
3012            >>> Select().from_("tbl").select("x").limit(10).sql()
3013            'SELECT x FROM tbl LIMIT 10'
3014
3015        Args:
3016            expression: the SQL code string to parse.
3017                This can also be an integer.
3018                If a `Limit` instance is passed, this is used as-is.
3019                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
3020            dialect: the dialect used to parse the input expression.
3021            copy: if `False`, modify this expression instance in-place.
3022            opts: other options to use to parse the input expressions.
3023
3024        Returns:
3025            Select: the modified expression.
3026        """
3027        return _apply_builder(
3028            expression=expression,
3029            instance=self,
3030            arg="limit",
3031            into=Limit,
3032            prefix="LIMIT",
3033            dialect=dialect,
3034            copy=copy,
3035            into_arg="expression",
3036            **opts,
3037        )

Set the LIMIT expression.

Example:
>>> Select().from_("tbl").select("x").limit(10).sql()
'SELECT x FROM tbl LIMIT 10'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, this is 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:

Select: the modified expression.

def offset( self, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3039    def offset(
3040        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3041    ) -> Select:
3042        """
3043        Set the OFFSET expression.
3044
3045        Example:
3046            >>> Select().from_("tbl").select("x").offset(10).sql()
3047            'SELECT x FROM tbl OFFSET 10'
3048
3049        Args:
3050            expression: the SQL code string to parse.
3051                This can also be an integer.
3052                If a `Offset` instance is passed, this is used as-is.
3053                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3054            dialect: the dialect used to parse the input expression.
3055            copy: if `False`, modify this expression instance in-place.
3056            opts: other options to use to parse the input expressions.
3057
3058        Returns:
3059            The modified Select expression.
3060        """
3061        return _apply_builder(
3062            expression=expression,
3063            instance=self,
3064            arg="offset",
3065            into=Offset,
3066            prefix="OFFSET",
3067            dialect=dialect,
3068            copy=copy,
3069            into_arg="expression",
3070            **opts,
3071        )

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 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:
3073    def select(
3074        self,
3075        *expressions: t.Optional[ExpOrStr],
3076        append: bool = True,
3077        dialect: DialectType = None,
3078        copy: bool = True,
3079        **opts,
3080    ) -> Select:
3081        """
3082        Append to or set the SELECT expressions.
3083
3084        Example:
3085            >>> Select().select("x", "y").sql()
3086            'SELECT x, y'
3087
3088        Args:
3089            *expressions: the SQL code strings to parse.
3090                If an `Expression` instance is passed, it will be used as-is.
3091            append: if `True`, add to any existing expressions.
3092                Otherwise, this resets the expressions.
3093            dialect: the dialect used to parse the input expressions.
3094            copy: if `False`, modify this expression instance in-place.
3095            opts: other options to use to parse the input expressions.
3096
3097        Returns:
3098            The modified Select expression.
3099        """
3100        return _apply_list_builder(
3101            *expressions,
3102            instance=self,
3103            arg="expressions",
3104            append=append,
3105            dialect=dialect,
3106            copy=copy,
3107            **opts,
3108        )

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 Select 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:
3110    def lateral(
3111        self,
3112        *expressions: t.Optional[ExpOrStr],
3113        append: bool = True,
3114        dialect: DialectType = None,
3115        copy: bool = True,
3116        **opts,
3117    ) -> Select:
3118        """
3119        Append to or set the LATERAL expressions.
3120
3121        Example:
3122            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3123            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3124
3125        Args:
3126            *expressions: the SQL code strings to parse.
3127                If an `Expression` instance is passed, it will be used as-is.
3128            append: if `True`, add to any existing expressions.
3129                Otherwise, this resets the expressions.
3130            dialect: the dialect used to parse the input expressions.
3131            copy: if `False`, modify this expression instance in-place.
3132            opts: other options to use to parse the input expressions.
3133
3134        Returns:
3135            The modified Select expression.
3136        """
3137        return _apply_list_builder(
3138            *expressions,
3139            instance=self,
3140            arg="laterals",
3141            append=append,
3142            into=Lateral,
3143            prefix="LATERAL VIEW",
3144            dialect=dialect,
3145            copy=copy,
3146            **opts,
3147        )

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:
3149    def join(
3150        self,
3151        expression: ExpOrStr,
3152        on: t.Optional[ExpOrStr] = None,
3153        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3154        append: bool = True,
3155        join_type: t.Optional[str] = None,
3156        join_alias: t.Optional[Identifier | str] = None,
3157        dialect: DialectType = None,
3158        copy: bool = True,
3159        **opts,
3160    ) -> Select:
3161        """
3162        Append to or set the JOIN expressions.
3163
3164        Example:
3165            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3166            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3167
3168            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3169            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3170
3171            Use `join_type` to change the type of join:
3172
3173            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3174            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3175
3176        Args:
3177            expression: the SQL code string to parse.
3178                If an `Expression` instance is passed, it will be used as-is.
3179            on: optionally specify the join "on" criteria as a SQL string.
3180                If an `Expression` instance is passed, it will be used as-is.
3181            using: optionally specify the join "using" criteria as a SQL string.
3182                If an `Expression` instance is passed, it will be used as-is.
3183            append: if `True`, add to any existing expressions.
3184                Otherwise, this resets the expressions.
3185            join_type: if set, alter the parsed join type.
3186            join_alias: an optional alias for the joined source.
3187            dialect: the dialect used to parse the input expressions.
3188            copy: if `False`, modify this expression instance in-place.
3189            opts: other options to use to parse the input expressions.
3190
3191        Returns:
3192            Select: the modified expression.
3193        """
3194        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3195
3196        try:
3197            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3198        except ParseError:
3199            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3200
3201        join = expression if isinstance(expression, Join) else Join(this=expression)
3202
3203        if isinstance(join.this, Select):
3204            join.this.replace(join.this.subquery())
3205
3206        if join_type:
3207            method: t.Optional[Token]
3208            side: t.Optional[Token]
3209            kind: t.Optional[Token]
3210
3211            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3212
3213            if method:
3214                join.set("method", method.text)
3215            if side:
3216                join.set("side", side.text)
3217            if kind:
3218                join.set("kind", kind.text)
3219
3220        if on:
3221            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3222            join.set("on", on)
3223
3224        if using:
3225            join = _apply_list_builder(
3226                *ensure_list(using),
3227                instance=join,
3228                arg="using",
3229                append=append,
3230                copy=copy,
3231                into=Identifier,
3232                **opts,
3233            )
3234
3235        if join_alias:
3236            join.set("this", alias_(join.this, join_alias, table=True))
3237
3238        return _apply_list_builder(
3239            join,
3240            instance=self,
3241            arg="joins",
3242            append=append,
3243            copy=copy,
3244            **opts,
3245        )

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:
3247    def where(
3248        self,
3249        *expressions: t.Optional[ExpOrStr],
3250        append: bool = True,
3251        dialect: DialectType = None,
3252        copy: bool = True,
3253        **opts,
3254    ) -> Select:
3255        """
3256        Append to or set the WHERE expressions.
3257
3258        Example:
3259            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3260            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3261
3262        Args:
3263            *expressions: the SQL code strings to parse.
3264                If an `Expression` instance is passed, it will be used as-is.
3265                Multiple expressions are combined with an AND operator.
3266            append: if `True`, AND the new expressions to any existing expression.
3267                Otherwise, this resets the expression.
3268            dialect: the dialect used to parse the input expressions.
3269            copy: if `False`, modify this expression instance in-place.
3270            opts: other options to use to parse the input expressions.
3271
3272        Returns:
3273            Select: the modified expression.
3274        """
3275        return _apply_conjunction_builder(
3276            *expressions,
3277            instance=self,
3278            arg="where",
3279            append=append,
3280            into=Where,
3281            dialect=dialect,
3282            copy=copy,
3283            **opts,
3284        )

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:
3286    def having(
3287        self,
3288        *expressions: t.Optional[ExpOrStr],
3289        append: bool = True,
3290        dialect: DialectType = None,
3291        copy: bool = True,
3292        **opts,
3293    ) -> Select:
3294        """
3295        Append to or set the HAVING expressions.
3296
3297        Example:
3298            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3299            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3300
3301        Args:
3302            *expressions: the SQL code strings to parse.
3303                If an `Expression` instance is passed, it will be used as-is.
3304                Multiple expressions are combined with an AND operator.
3305            append: if `True`, AND the new expressions to any existing expression.
3306                Otherwise, this resets the expression.
3307            dialect: the dialect used to parse the input expressions.
3308            copy: if `False`, modify this expression instance in-place.
3309            opts: other options to use to parse the input expressions.
3310
3311        Returns:
3312            The modified Select expression.
3313        """
3314        return _apply_conjunction_builder(
3315            *expressions,
3316            instance=self,
3317            arg="having",
3318            append=append,
3319            into=Having,
3320            dialect=dialect,
3321            copy=copy,
3322            **opts,
3323        )

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:
3325    def window(
3326        self,
3327        *expressions: t.Optional[ExpOrStr],
3328        append: bool = True,
3329        dialect: DialectType = None,
3330        copy: bool = True,
3331        **opts,
3332    ) -> Select:
3333        return _apply_list_builder(
3334            *expressions,
3335            instance=self,
3336            arg="windows",
3337            append=append,
3338            into=Window,
3339            dialect=dialect,
3340            copy=copy,
3341            **opts,
3342        )
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:
3344    def qualify(
3345        self,
3346        *expressions: t.Optional[ExpOrStr],
3347        append: bool = True,
3348        dialect: DialectType = None,
3349        copy: bool = True,
3350        **opts,
3351    ) -> Select:
3352        return _apply_conjunction_builder(
3353            *expressions,
3354            instance=self,
3355            arg="qualify",
3356            append=append,
3357            into=Qualify,
3358            dialect=dialect,
3359            copy=copy,
3360            **opts,
3361        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3363    def distinct(
3364        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3365    ) -> Select:
3366        """
3367        Set the OFFSET expression.
3368
3369        Example:
3370            >>> Select().from_("tbl").select("x").distinct().sql()
3371            'SELECT DISTINCT x FROM tbl'
3372
3373        Args:
3374            ons: the expressions to distinct on
3375            distinct: whether the Select should be distinct
3376            copy: if `False`, modify this expression instance in-place.
3377
3378        Returns:
3379            Select: the modified expression.
3380        """
3381        instance = maybe_copy(self, copy)
3382        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3383        instance.set("distinct", Distinct(on=on) if distinct else None)
3384        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:
3386    def ctas(
3387        self,
3388        table: ExpOrStr,
3389        properties: t.Optional[t.Dict] = None,
3390        dialect: DialectType = None,
3391        copy: bool = True,
3392        **opts,
3393    ) -> Create:
3394        """
3395        Convert this expression to a CREATE TABLE AS statement.
3396
3397        Example:
3398            >>> Select().select("*").from_("tbl").ctas("x").sql()
3399            'CREATE TABLE x AS SELECT * FROM tbl'
3400
3401        Args:
3402            table: the SQL code string to parse as the table name.
3403                If another `Expression` instance is passed, it will be used as-is.
3404            properties: an optional mapping of table properties
3405            dialect: the dialect used to parse the input table.
3406            copy: if `False`, modify this expression instance in-place.
3407            opts: other options to use to parse the input table.
3408
3409        Returns:
3410            The new Create expression.
3411        """
3412        instance = maybe_copy(self, copy)
3413        table_expression = maybe_parse(
3414            table,
3415            into=Table,
3416            dialect=dialect,
3417            **opts,
3418        )
3419        properties_expression = None
3420        if properties:
3421            properties_expression = Properties.from_dict(properties)
3422
3423        return Create(
3424            this=table_expression,
3425            kind="TABLE",
3426            expression=instance,
3427            properties=properties_expression,
3428        )

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:
3430    def lock(self, update: bool = True, copy: bool = True) -> Select:
3431        """
3432        Set the locking read mode for this expression.
3433
3434        Examples:
3435            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3436            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3437
3438            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3439            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3440
3441        Args:
3442            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3443            copy: if `False`, modify this expression instance in-place.
3444
3445        Returns:
3446            The modified expression.
3447        """
3448        inst = maybe_copy(self, copy)
3449        inst.set("locks", [Lock(update=update)])
3450
3451        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:
3453    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3454        """
3455        Set hints for this expression.
3456
3457        Examples:
3458            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3459            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3460
3461        Args:
3462            hints: The SQL code strings to parse as the hints.
3463                If an `Expression` instance is passed, it will be used as-is.
3464            dialect: The dialect used to parse the hints.
3465            copy: If `False`, modify this expression instance in-place.
3466
3467        Returns:
3468            The modified expression.
3469        """
3470        inst = maybe_copy(self, copy)
3471        inst.set(
3472            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3473        )
3474
3475        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]
3477    @property
3478    def named_selects(self) -> t.List[str]:
3479        return [e.output_name for e in self.expressions if e.alias_or_name]
is_star: bool
3481    @property
3482    def is_star(self) -> bool:
3483        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3485    @property
3486    def selects(self) -> t.List[Expression]:
3487        return self.expressions
key = 'select'
class Subquery(DerivedTable, Unionable):
3490class Subquery(DerivedTable, Unionable):
3491    arg_types = {
3492        "this": True,
3493        "alias": False,
3494        "with": False,
3495        **QUERY_MODIFIERS,
3496    }
3497
3498    def unnest(self):
3499        """
3500        Returns the first non subquery.
3501        """
3502        expression = self
3503        while isinstance(expression, Subquery):
3504            expression = expression.this
3505        return expression
3506
3507    def unwrap(self) -> Subquery:
3508        expression = self
3509        while expression.same_parent and expression.is_wrapper:
3510            expression = t.cast(Subquery, expression.parent)
3511        return expression
3512
3513    @property
3514    def is_wrapper(self) -> bool:
3515        """
3516        Whether this Subquery acts as a simple wrapper around another expression.
3517
3518        SELECT * FROM (((SELECT * FROM t)))
3519                      ^
3520                      This corresponds to a "wrapper" Subquery node
3521        """
3522        return all(v is None for k, v in self.args.items() if k != "this")
3523
3524    @property
3525    def is_star(self) -> bool:
3526        return self.this.is_star
3527
3528    @property
3529    def output_name(self) -> str:
3530        return self.alias
arg_types = {'this': True, 'alias': False, 'with': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': 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}
def unnest(self):
3498    def unnest(self):
3499        """
3500        Returns the first non subquery.
3501        """
3502        expression = self
3503        while isinstance(expression, Subquery):
3504            expression = expression.this
3505        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3507    def unwrap(self) -> Subquery:
3508        expression = self
3509        while expression.same_parent and expression.is_wrapper:
3510            expression = t.cast(Subquery, expression.parent)
3511        return expression
is_wrapper: bool
3513    @property
3514    def is_wrapper(self) -> bool:
3515        """
3516        Whether this Subquery acts as a simple wrapper around another expression.
3517
3518        SELECT * FROM (((SELECT * FROM t)))
3519                      ^
3520                      This corresponds to a "wrapper" Subquery node
3521        """
3522        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
3524    @property
3525    def is_star(self) -> bool:
3526        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3528    @property
3529    def output_name(self) -> str:
3530        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):
3533class TableSample(Expression):
3534    arg_types = {
3535        "this": False,
3536        "expressions": False,
3537        "method": False,
3538        "bucket_numerator": False,
3539        "bucket_denominator": False,
3540        "bucket_field": False,
3541        "percent": False,
3542        "rows": False,
3543        "size": False,
3544        "seed": False,
3545    }
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):
3548class Tag(Expression):
3549    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3550
3551    arg_types = {
3552        "this": False,
3553        "prefix": False,
3554        "postfix": False,
3555    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3560class Pivot(Expression):
3561    arg_types = {
3562        "this": False,
3563        "alias": False,
3564        "expressions": False,
3565        "field": False,
3566        "unpivot": False,
3567        "using": False,
3568        "group": False,
3569        "columns": False,
3570        "include_nulls": False,
3571    }
3572
3573    @property
3574    def unpivot(self) -> bool:
3575        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
3573    @property
3574    def unpivot(self) -> bool:
3575        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3578class Window(Condition):
3579    arg_types = {
3580        "this": True,
3581        "partition_by": False,
3582        "order": False,
3583        "spec": False,
3584        "alias": False,
3585        "over": False,
3586        "first": False,
3587    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3590class WindowSpec(Expression):
3591    arg_types = {
3592        "kind": False,
3593        "start": False,
3594        "start_side": False,
3595        "end": False,
3596        "end_side": False,
3597    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3600class Where(Expression):
3601    pass
key = 'where'
class Star(Expression):
3604class Star(Expression):
3605    arg_types = {"except": False, "replace": False}
3606
3607    @property
3608    def name(self) -> str:
3609        return "*"
3610
3611    @property
3612    def output_name(self) -> str:
3613        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3607    @property
3608    def name(self) -> str:
3609        return "*"
output_name: str
3611    @property
3612    def output_name(self) -> str:
3613        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):
3616class Parameter(Condition):
3617    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3620class SessionParameter(Condition):
3621    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3624class Placeholder(Condition):
3625    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3628class Null(Condition):
3629    arg_types: t.Dict[str, t.Any] = {}
3630
3631    @property
3632    def name(self) -> str:
3633        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3631    @property
3632    def name(self) -> str:
3633        return "NULL"
key = 'null'
class Boolean(Condition):
3636class Boolean(Condition):
3637    pass
key = 'boolean'
class DataTypeParam(Expression):
3640class DataTypeParam(Expression):
3641    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3644class DataType(Expression):
3645    arg_types = {
3646        "this": True,
3647        "expressions": False,
3648        "nested": False,
3649        "values": False,
3650        "prefix": False,
3651        "kind": False,
3652    }
3653
3654    class Type(AutoName):
3655        ARRAY = auto()
3656        AGGREGATEFUNCTION = auto()
3657        SIMPLEAGGREGATEFUNCTION = auto()
3658        BIGDECIMAL = auto()
3659        BIGINT = auto()
3660        BIGSERIAL = auto()
3661        BINARY = auto()
3662        BIT = auto()
3663        BOOLEAN = auto()
3664        CHAR = auto()
3665        DATE = auto()
3666        DATE32 = auto()
3667        DATEMULTIRANGE = auto()
3668        DATERANGE = auto()
3669        DATETIME = auto()
3670        DATETIME64 = auto()
3671        DECIMAL = auto()
3672        DOUBLE = auto()
3673        ENUM = auto()
3674        ENUM8 = auto()
3675        ENUM16 = auto()
3676        FIXEDSTRING = auto()
3677        FLOAT = auto()
3678        GEOGRAPHY = auto()
3679        GEOMETRY = auto()
3680        HLLSKETCH = auto()
3681        HSTORE = auto()
3682        IMAGE = auto()
3683        INET = auto()
3684        INT = auto()
3685        INT128 = auto()
3686        INT256 = auto()
3687        INT4MULTIRANGE = auto()
3688        INT4RANGE = auto()
3689        INT8MULTIRANGE = auto()
3690        INT8RANGE = auto()
3691        INTERVAL = auto()
3692        IPADDRESS = auto()
3693        IPPREFIX = auto()
3694        IPV4 = auto()
3695        IPV6 = auto()
3696        JSON = auto()
3697        JSONB = auto()
3698        LONGBLOB = auto()
3699        LONGTEXT = auto()
3700        LOWCARDINALITY = auto()
3701        MAP = auto()
3702        MEDIUMBLOB = auto()
3703        MEDIUMINT = auto()
3704        MEDIUMTEXT = auto()
3705        MONEY = auto()
3706        NCHAR = auto()
3707        NESTED = auto()
3708        NULL = auto()
3709        NULLABLE = auto()
3710        NUMMULTIRANGE = auto()
3711        NUMRANGE = auto()
3712        NVARCHAR = auto()
3713        OBJECT = auto()
3714        ROWVERSION = auto()
3715        SERIAL = auto()
3716        SET = auto()
3717        SMALLINT = auto()
3718        SMALLMONEY = auto()
3719        SMALLSERIAL = auto()
3720        STRUCT = auto()
3721        SUPER = auto()
3722        TEXT = auto()
3723        TINYBLOB = auto()
3724        TINYTEXT = auto()
3725        TIME = auto()
3726        TIMETZ = auto()
3727        TIMESTAMP = auto()
3728        TIMESTAMPLTZ = auto()
3729        TIMESTAMPTZ = auto()
3730        TIMESTAMP_S = auto()
3731        TIMESTAMP_MS = auto()
3732        TIMESTAMP_NS = auto()
3733        TINYINT = auto()
3734        TSMULTIRANGE = auto()
3735        TSRANGE = auto()
3736        TSTZMULTIRANGE = auto()
3737        TSTZRANGE = auto()
3738        UBIGINT = auto()
3739        UINT = auto()
3740        UINT128 = auto()
3741        UINT256 = auto()
3742        UMEDIUMINT = auto()
3743        UDECIMAL = auto()
3744        UNIQUEIDENTIFIER = auto()
3745        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3746        USERDEFINED = "USER-DEFINED"
3747        USMALLINT = auto()
3748        UTINYINT = auto()
3749        UUID = auto()
3750        VARBINARY = auto()
3751        VARCHAR = auto()
3752        VARIANT = auto()
3753        XML = auto()
3754        YEAR = auto()
3755
3756    TEXT_TYPES = {
3757        Type.CHAR,
3758        Type.NCHAR,
3759        Type.VARCHAR,
3760        Type.NVARCHAR,
3761        Type.TEXT,
3762    }
3763
3764    INTEGER_TYPES = {
3765        Type.INT,
3766        Type.TINYINT,
3767        Type.SMALLINT,
3768        Type.BIGINT,
3769        Type.INT128,
3770        Type.INT256,
3771        Type.BIT,
3772    }
3773
3774    FLOAT_TYPES = {
3775        Type.FLOAT,
3776        Type.DOUBLE,
3777    }
3778
3779    NUMERIC_TYPES = {
3780        *INTEGER_TYPES,
3781        *FLOAT_TYPES,
3782    }
3783
3784    TEMPORAL_TYPES = {
3785        Type.TIME,
3786        Type.TIMETZ,
3787        Type.TIMESTAMP,
3788        Type.TIMESTAMPTZ,
3789        Type.TIMESTAMPLTZ,
3790        Type.TIMESTAMP_S,
3791        Type.TIMESTAMP_MS,
3792        Type.TIMESTAMP_NS,
3793        Type.DATE,
3794        Type.DATE32,
3795        Type.DATETIME,
3796        Type.DATETIME64,
3797    }
3798
3799    @classmethod
3800    def build(
3801        cls,
3802        dtype: DATA_TYPE,
3803        dialect: DialectType = None,
3804        udt: bool = False,
3805        **kwargs,
3806    ) -> DataType:
3807        """
3808        Constructs a DataType object.
3809
3810        Args:
3811            dtype: the data type of interest.
3812            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3813            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3814                DataType, thus creating a user-defined type.
3815            kawrgs: additional arguments to pass in the constructor of DataType.
3816
3817        Returns:
3818            The constructed DataType object.
3819        """
3820        from sqlglot import parse_one
3821
3822        if isinstance(dtype, str):
3823            if dtype.upper() == "UNKNOWN":
3824                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3825
3826            try:
3827                data_type_exp = parse_one(
3828                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3829                )
3830            except ParseError:
3831                if udt:
3832                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3833                raise
3834        elif isinstance(dtype, DataType.Type):
3835            data_type_exp = DataType(this=dtype)
3836        elif isinstance(dtype, DataType):
3837            return dtype
3838        else:
3839            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3840
3841        return DataType(**{**data_type_exp.args, **kwargs})
3842
3843    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3844        """
3845        Checks whether this DataType matches one of the provided data types. Nested types or precision
3846        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3847
3848        Args:
3849            dtypes: the data types to compare this DataType to.
3850
3851        Returns:
3852            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3853        """
3854        for dtype in dtypes:
3855            other = DataType.build(dtype, udt=True)
3856
3857            if (
3858                other.expressions
3859                or self.this == DataType.Type.USERDEFINED
3860                or other.this == DataType.Type.USERDEFINED
3861            ):
3862                matches = self == other
3863            else:
3864                matches = self.this == other.this
3865
3866            if matches:
3867                return True
3868        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>}
INTEGER_TYPES = {<Type.INT256: 'INT256'>, <Type.BIT: 'BIT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.INT256: 'INT256'>, <Type.BIT: 'BIT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.FLOAT: 'FLOAT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATE32: 'DATE32'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, **kwargs) -> DataType:
3799    @classmethod
3800    def build(
3801        cls,
3802        dtype: DATA_TYPE,
3803        dialect: DialectType = None,
3804        udt: bool = False,
3805        **kwargs,
3806    ) -> DataType:
3807        """
3808        Constructs a DataType object.
3809
3810        Args:
3811            dtype: the data type of interest.
3812            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3813            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3814                DataType, thus creating a user-defined type.
3815            kawrgs: additional arguments to pass in the constructor of DataType.
3816
3817        Returns:
3818            The constructed DataType object.
3819        """
3820        from sqlglot import parse_one
3821
3822        if isinstance(dtype, str):
3823            if dtype.upper() == "UNKNOWN":
3824                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3825
3826            try:
3827                data_type_exp = parse_one(
3828                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3829                )
3830            except ParseError:
3831                if udt:
3832                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3833                raise
3834        elif isinstance(dtype, DataType.Type):
3835            data_type_exp = DataType(this=dtype)
3836        elif isinstance(dtype, DataType):
3837            return dtype
3838        else:
3839            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3840
3841        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.
  • kawrgs: 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:
3843    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3844        """
3845        Checks whether this DataType matches one of the provided data types. Nested types or precision
3846        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3847
3848        Args:
3849            dtypes: the data types to compare this DataType to.
3850
3851        Returns:
3852            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3853        """
3854        for dtype in dtypes:
3855            other = DataType.build(dtype, udt=True)
3856
3857            if (
3858                other.expressions
3859                or self.this == DataType.Type.USERDEFINED
3860                or other.this == DataType.Type.USERDEFINED
3861            ):
3862                matches = self == other
3863            else:
3864                matches = self.this == other.this
3865
3866            if matches:
3867                return True
3868        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):
3654    class Type(AutoName):
3655        ARRAY = auto()
3656        AGGREGATEFUNCTION = auto()
3657        SIMPLEAGGREGATEFUNCTION = auto()
3658        BIGDECIMAL = auto()
3659        BIGINT = auto()
3660        BIGSERIAL = auto()
3661        BINARY = auto()
3662        BIT = auto()
3663        BOOLEAN = auto()
3664        CHAR = auto()
3665        DATE = auto()
3666        DATE32 = auto()
3667        DATEMULTIRANGE = auto()
3668        DATERANGE = auto()
3669        DATETIME = auto()
3670        DATETIME64 = auto()
3671        DECIMAL = auto()
3672        DOUBLE = auto()
3673        ENUM = auto()
3674        ENUM8 = auto()
3675        ENUM16 = auto()
3676        FIXEDSTRING = auto()
3677        FLOAT = auto()
3678        GEOGRAPHY = auto()
3679        GEOMETRY = auto()
3680        HLLSKETCH = auto()
3681        HSTORE = auto()
3682        IMAGE = auto()
3683        INET = auto()
3684        INT = auto()
3685        INT128 = auto()
3686        INT256 = auto()
3687        INT4MULTIRANGE = auto()
3688        INT4RANGE = auto()
3689        INT8MULTIRANGE = auto()
3690        INT8RANGE = auto()
3691        INTERVAL = auto()
3692        IPADDRESS = auto()
3693        IPPREFIX = auto()
3694        IPV4 = auto()
3695        IPV6 = auto()
3696        JSON = auto()
3697        JSONB = auto()
3698        LONGBLOB = auto()
3699        LONGTEXT = auto()
3700        LOWCARDINALITY = auto()
3701        MAP = auto()
3702        MEDIUMBLOB = auto()
3703        MEDIUMINT = auto()
3704        MEDIUMTEXT = auto()
3705        MONEY = auto()
3706        NCHAR = auto()
3707        NESTED = auto()
3708        NULL = auto()
3709        NULLABLE = auto()
3710        NUMMULTIRANGE = auto()
3711        NUMRANGE = auto()
3712        NVARCHAR = auto()
3713        OBJECT = auto()
3714        ROWVERSION = auto()
3715        SERIAL = auto()
3716        SET = auto()
3717        SMALLINT = auto()
3718        SMALLMONEY = auto()
3719        SMALLSERIAL = auto()
3720        STRUCT = auto()
3721        SUPER = auto()
3722        TEXT = auto()
3723        TINYBLOB = auto()
3724        TINYTEXT = auto()
3725        TIME = auto()
3726        TIMETZ = auto()
3727        TIMESTAMP = auto()
3728        TIMESTAMPLTZ = auto()
3729        TIMESTAMPTZ = auto()
3730        TIMESTAMP_S = auto()
3731        TIMESTAMP_MS = auto()
3732        TIMESTAMP_NS = auto()
3733        TINYINT = auto()
3734        TSMULTIRANGE = auto()
3735        TSRANGE = auto()
3736        TSTZMULTIRANGE = auto()
3737        TSTZRANGE = auto()
3738        UBIGINT = auto()
3739        UINT = auto()
3740        UINT128 = auto()
3741        UINT256 = auto()
3742        UMEDIUMINT = auto()
3743        UDECIMAL = auto()
3744        UNIQUEIDENTIFIER = auto()
3745        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3746        USERDEFINED = "USER-DEFINED"
3747        USMALLINT = auto()
3748        UTINYINT = auto()
3749        UUID = auto()
3750        VARBINARY = auto()
3751        VARCHAR = auto()
3752        VARIANT = auto()
3753        XML = auto()
3754        YEAR = 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'>
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'>
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'>
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'>
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'>
Inherited Members
enum.Enum
name
value
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
3875class PseudoType(DataType):
3876    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3880class ObjectIdentifier(DataType):
3881    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3885class SubqueryPredicate(Predicate):
3886    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3889class All(SubqueryPredicate):
3890    pass
key = 'all'
class Any(SubqueryPredicate):
3893class Any(SubqueryPredicate):
3894    pass
key = 'any'
class Exists(SubqueryPredicate):
3897class Exists(SubqueryPredicate):
3898    pass
key = 'exists'
class Command(Expression):
3903class Command(Expression):
3904    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3907class Transaction(Expression):
3908    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3911class Commit(Expression):
3912    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3915class Rollback(Expression):
3916    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3919class AlterTable(Expression):
3920    arg_types = {"this": True, "actions": True, "exists": False, "only": False}
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False}
key = 'altertable'
class AddConstraint(Expression):
3923class AddConstraint(Expression):
3924    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3927class DropPartition(Expression):
3928    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3932class Binary(Condition):
3933    arg_types = {"this": True, "expression": True}
3934
3935    @property
3936    def left(self) -> Expression:
3937        return self.this
3938
3939    @property
3940    def right(self) -> Expression:
3941        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
3935    @property
3936    def left(self) -> Expression:
3937        return self.this
right: Expression
3939    @property
3940    def right(self) -> Expression:
3941        return self.expression
key = 'binary'
class Add(Binary):
3944class Add(Binary):
3945    pass
key = 'add'
class Connector(Binary):
3948class Connector(Binary):
3949    pass
key = 'connector'
class And(Connector):
3952class And(Connector):
3953    pass
key = 'and'
class Or(Connector):
3956class Or(Connector):
3957    pass
key = 'or'
class BitwiseAnd(Binary):
3960class BitwiseAnd(Binary):
3961    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3964class BitwiseLeftShift(Binary):
3965    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3968class BitwiseOr(Binary):
3969    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3972class BitwiseRightShift(Binary):
3973    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3976class BitwiseXor(Binary):
3977    pass
key = 'bitwisexor'
class Div(Binary):
3980class Div(Binary):
3981    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):
3984class Overlaps(Binary):
3985    pass
key = 'overlaps'
class Dot(Binary):
3988class Dot(Binary):
3989    @property
3990    def name(self) -> str:
3991        return self.expression.name
3992
3993    @property
3994    def output_name(self) -> str:
3995        return self.name
3996
3997    @classmethod
3998    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3999        """Build a Dot object with a sequence of expressions."""
4000        if len(expressions) < 2:
4001            raise ValueError(f"Dot requires >= 2 expressions.")
4002
4003        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4004
4005    @property
4006    def parts(self) -> t.List[Expression]:
4007        """Return the parts of a table / column in order catalog, db, table."""
4008        this, *parts = self.flatten()
4009
4010        parts.reverse()
4011
4012        for arg in ("this", "table", "db", "catalog"):
4013            part = this.args.get(arg)
4014
4015            if isinstance(part, Expression):
4016                parts.append(part)
4017
4018        parts.reverse()
4019        return parts
name: str
3989    @property
3990    def name(self) -> str:
3991        return self.expression.name
output_name: str
3993    @property
3994    def output_name(self) -> str:
3995        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:
3997    @classmethod
3998    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3999        """Build a Dot object with a sequence of expressions."""
4000        if len(expressions) < 2:
4001            raise ValueError(f"Dot requires >= 2 expressions.")
4002
4003        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]
4005    @property
4006    def parts(self) -> t.List[Expression]:
4007        """Return the parts of a table / column in order catalog, db, table."""
4008        this, *parts = self.flatten()
4009
4010        parts.reverse()
4011
4012        for arg in ("this", "table", "db", "catalog"):
4013            part = this.args.get(arg)
4014
4015            if isinstance(part, Expression):
4016                parts.append(part)
4017
4018        parts.reverse()
4019        return parts

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

key = 'dot'
class DPipe(Binary):
4022class DPipe(Binary):
4023    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4026class EQ(Binary, Predicate):
4027    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4030class NullSafeEQ(Binary, Predicate):
4031    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4034class NullSafeNEQ(Binary, Predicate):
4035    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4039class PropertyEQ(Binary):
4040    pass
key = 'propertyeq'
class Distance(Binary):
4043class Distance(Binary):
4044    pass
key = 'distance'
class Escape(Binary):
4047class Escape(Binary):
4048    pass
key = 'escape'
class Glob(Binary, Predicate):
4051class Glob(Binary, Predicate):
4052    pass
key = 'glob'
class GT(Binary, Predicate):
4055class GT(Binary, Predicate):
4056    pass
key = 'gt'
class GTE(Binary, Predicate):
4059class GTE(Binary, Predicate):
4060    pass
key = 'gte'
class ILike(Binary, Predicate):
4063class ILike(Binary, Predicate):
4064    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4067class ILikeAny(Binary, Predicate):
4068    pass
key = 'ilikeany'
class IntDiv(Binary):
4071class IntDiv(Binary):
4072    pass
key = 'intdiv'
class Is(Binary, Predicate):
4075class Is(Binary, Predicate):
4076    pass
key = 'is'
class Kwarg(Binary):
4079class Kwarg(Binary):
4080    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4083class Like(Binary, Predicate):
4084    pass
key = 'like'
class LikeAny(Binary, Predicate):
4087class LikeAny(Binary, Predicate):
4088    pass
key = 'likeany'
class LT(Binary, Predicate):
4091class LT(Binary, Predicate):
4092    pass
key = 'lt'
class LTE(Binary, Predicate):
4095class LTE(Binary, Predicate):
4096    pass
key = 'lte'
class Mod(Binary):
4099class Mod(Binary):
4100    pass
key = 'mod'
class Mul(Binary):
4103class Mul(Binary):
4104    pass
key = 'mul'
class NEQ(Binary, Predicate):
4107class NEQ(Binary, Predicate):
4108    pass
key = 'neq'
class Operator(Binary):
4112class Operator(Binary):
4113    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4116class SimilarTo(Binary, Predicate):
4117    pass
key = 'similarto'
class Slice(Binary):
4120class Slice(Binary):
4121    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4124class Sub(Binary):
4125    pass
key = 'sub'
class ArrayOverlaps(Binary):
4128class ArrayOverlaps(Binary):
4129    pass
key = 'arrayoverlaps'
class Unary(Condition):
4134class Unary(Condition):
4135    pass
key = 'unary'
class BitwiseNot(Unary):
4138class BitwiseNot(Unary):
4139    pass
key = 'bitwisenot'
class Not(Unary):
4142class Not(Unary):
4143    pass
key = 'not'
class Paren(Unary):
4146class Paren(Unary):
4147    arg_types = {"this": True, "with": False}
4148
4149    @property
4150    def output_name(self) -> str:
4151        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4149    @property
4150    def output_name(self) -> str:
4151        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):
4154class Neg(Unary):
4155    pass
key = 'neg'
class Alias(Expression):
4158class Alias(Expression):
4159    arg_types = {"this": True, "alias": False}
4160
4161    @property
4162    def output_name(self) -> str:
4163        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4161    @property
4162    def output_name(self) -> str:
4163        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):
4168class PivotAlias(Alias):
4169    pass
key = 'pivotalias'
class Aliases(Expression):
4172class Aliases(Expression):
4173    arg_types = {"this": True, "expressions": True}
4174
4175    @property
4176    def aliases(self):
4177        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4175    @property
4176    def aliases(self):
4177        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4181class AtIndex(Expression):
4182    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4185class AtTimeZone(Expression):
4186    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4189class FromTimeZone(Expression):
4190    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4193class Between(Predicate):
4194    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4197class Bracket(Condition):
4198    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4199    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4200
4201    @property
4202    def output_name(self) -> str:
4203        if len(self.expressions) == 1:
4204            return self.expressions[0].output_name
4205
4206        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4201    @property
4202    def output_name(self) -> str:
4203        if len(self.expressions) == 1:
4204            return self.expressions[0].output_name
4205
4206        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):
4209class Distinct(Expression):
4210    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4213class In(Predicate):
4214    arg_types = {
4215        "this": True,
4216        "expressions": False,
4217        "query": False,
4218        "unnest": False,
4219        "field": False,
4220        "is_global": False,
4221    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4225class ForIn(Expression):
4226    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4229class TimeUnit(Expression):
4230    """Automatically converts unit arg into a var."""
4231
4232    arg_types = {"unit": False}
4233
4234    UNABBREVIATED_UNIT_NAME = {
4235        "D": "DAY",
4236        "H": "HOUR",
4237        "M": "MINUTE",
4238        "MS": "MILLISECOND",
4239        "NS": "NANOSECOND",
4240        "Q": "QUARTER",
4241        "S": "SECOND",
4242        "US": "MICROSECOND",
4243        "W": "WEEK",
4244        "Y": "YEAR",
4245    }
4246
4247    VAR_LIKE = (Column, Literal, Var)
4248
4249    def __init__(self, **args):
4250        unit = args.get("unit")
4251        if isinstance(unit, self.VAR_LIKE):
4252            args["unit"] = Var(
4253                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4254            )
4255        elif isinstance(unit, Week):
4256            unit.set("this", Var(this=unit.this.name.upper()))
4257
4258        super().__init__(**args)
4259
4260    @property
4261    def unit(self) -> t.Optional[Var]:
4262        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4249    def __init__(self, **args):
4250        unit = args.get("unit")
4251        if isinstance(unit, self.VAR_LIKE):
4252            args["unit"] = Var(
4253                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4254            )
4255        elif isinstance(unit, Week):
4256            unit.set("this", Var(this=unit.this.name.upper()))
4257
4258        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: Optional[Var]
4260    @property
4261    def unit(self) -> t.Optional[Var]:
4262        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4265class IntervalOp(TimeUnit):
4266    arg_types = {"unit": True, "expression": True}
4267
4268    def interval(self):
4269        return Interval(
4270            this=self.expression.copy(),
4271            unit=self.unit.copy(),
4272        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4268    def interval(self):
4269        return Interval(
4270            this=self.expression.copy(),
4271            unit=self.unit.copy(),
4272        )
key = 'intervalop'
class IntervalSpan(DataType):
4278class IntervalSpan(DataType):
4279    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4282class Interval(TimeUnit):
4283    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4286class IgnoreNulls(Expression):
4287    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4290class RespectNulls(Expression):
4291    pass
key = 'respectnulls'
class Func(Condition):
4295class Func(Condition):
4296    """
4297    The base class for all function expressions.
4298
4299    Attributes:
4300        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4301            treated as a variable length argument and the argument's value will be stored as a list.
4302        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4303            for this function expression. These values are used to map this node to a name during parsing
4304            as well as to provide the function's name during SQL string generation. By default the SQL
4305            name is set to the expression's class name transformed to snake case.
4306    """
4307
4308    is_var_len_args = False
4309
4310    @classmethod
4311    def from_arg_list(cls, args):
4312        if cls.is_var_len_args:
4313            all_arg_keys = list(cls.arg_types)
4314            # If this function supports variable length argument treat the last argument as such.
4315            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4316            num_non_var = len(non_var_len_arg_keys)
4317
4318            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4319            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4320        else:
4321            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4322
4323        return cls(**args_dict)
4324
4325    @classmethod
4326    def sql_names(cls):
4327        if cls is Func:
4328            raise NotImplementedError(
4329                "SQL name is only supported by concrete function implementations"
4330            )
4331        if "_sql_names" not in cls.__dict__:
4332            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4333        return cls._sql_names
4334
4335    @classmethod
4336    def sql_name(cls):
4337        return cls.sql_names()[0]
4338
4339    @classmethod
4340    def default_parser_mappings(cls):
4341        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): determines 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):
4310    @classmethod
4311    def from_arg_list(cls, args):
4312        if cls.is_var_len_args:
4313            all_arg_keys = list(cls.arg_types)
4314            # If this function supports variable length argument treat the last argument as such.
4315            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4316            num_non_var = len(non_var_len_arg_keys)
4317
4318            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4319            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4320        else:
4321            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4322
4323        return cls(**args_dict)
@classmethod
def sql_names(cls):
4325    @classmethod
4326    def sql_names(cls):
4327        if cls is Func:
4328            raise NotImplementedError(
4329                "SQL name is only supported by concrete function implementations"
4330            )
4331        if "_sql_names" not in cls.__dict__:
4332            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4333        return cls._sql_names
@classmethod
def sql_name(cls):
4335    @classmethod
4336    def sql_name(cls):
4337        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4339    @classmethod
4340    def default_parser_mappings(cls):
4341        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4344class AggFunc(Func):
4345    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4348class ParameterizedAgg(AggFunc):
4349    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4352class Abs(Func):
4353    pass
key = 'abs'
class ArgMax(AggFunc):
4356class ArgMax(AggFunc):
4357    arg_types = {"this": True, "expression": True, "count": False}
4358    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4361class ArgMin(AggFunc):
4362    arg_types = {"this": True, "expression": True, "count": False}
4363    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4366class ApproxTopK(AggFunc):
4367    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4370class Flatten(Func):
4371    pass
key = 'flatten'
class Transform(Func):
4375class Transform(Func):
4376    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4379class Anonymous(Func):
4380    arg_types = {"this": True, "expressions": False}
4381    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4384class AnonymousAggFunc(AggFunc):
4385    arg_types = {"this": True, "expressions": False}
4386    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4390class CombinedAggFunc(AnonymousAggFunc):
4391    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4394class CombinedParameterizedAgg(ParameterizedAgg):
4395    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):
4400class Hll(AggFunc):
4401    arg_types = {"this": True, "expressions": False}
4402    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4405class ApproxDistinct(AggFunc):
4406    arg_types = {"this": True, "accuracy": False}
4407    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4410class Array(Func):
4411    arg_types = {"expressions": False}
4412    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4416class ToArray(Func):
4417    pass
key = 'toarray'
class ToChar(Func):
4422class ToChar(Func):
4423    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4426class GenerateSeries(Func):
4427    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4430class ArrayAgg(AggFunc):
4431    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4434class ArrayUniqueAgg(AggFunc):
4435    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4438class ArrayAll(Func):
4439    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4442class ArrayAny(Func):
4443    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4446class ArrayConcat(Func):
4447    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4448    arg_types = {"this": True, "expressions": False}
4449    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4452class ArrayContains(Binary, Func):
4453    pass
key = 'arraycontains'
class ArrayContained(Binary):
4456class ArrayContained(Binary):
4457    pass
key = 'arraycontained'
class ArrayFilter(Func):
4460class ArrayFilter(Func):
4461    arg_types = {"this": True, "expression": True}
4462    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4465class ArrayJoin(Func):
4466    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4469class ArraySize(Func):
4470    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4473class ArraySort(Func):
4474    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4477class ArraySum(Func):
4478    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4481class ArrayUnionAgg(AggFunc):
4482    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4485class Avg(AggFunc):
4486    pass
key = 'avg'
class AnyValue(AggFunc):
4489class AnyValue(AggFunc):
4490    arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False}
arg_types = {'this': True, 'having': False, 'max': False, 'ignore_nulls': False}
key = 'anyvalue'
class First(Func):
4493class First(Func):
4494    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4497class Last(Func):
4498    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4501class Case(Func):
4502    arg_types = {"this": False, "ifs": True, "default": False}
4503
4504    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4505        instance = maybe_copy(self, copy)
4506        instance.append(
4507            "ifs",
4508            If(
4509                this=maybe_parse(condition, copy=copy, **opts),
4510                true=maybe_parse(then, copy=copy, **opts),
4511            ),
4512        )
4513        return instance
4514
4515    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4516        instance = maybe_copy(self, copy)
4517        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4518        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:
4504    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4505        instance = maybe_copy(self, copy)
4506        instance.append(
4507            "ifs",
4508            If(
4509                this=maybe_parse(condition, copy=copy, **opts),
4510                true=maybe_parse(then, copy=copy, **opts),
4511            ),
4512        )
4513        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4515    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4516        instance = maybe_copy(self, copy)
4517        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4518        return instance
key = 'case'
class Cast(Func):
4521class Cast(Func):
4522    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4523
4524    @property
4525    def name(self) -> str:
4526        return self.this.name
4527
4528    @property
4529    def to(self) -> DataType:
4530        return self.args["to"]
4531
4532    @property
4533    def output_name(self) -> str:
4534        return self.name
4535
4536    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4537        """
4538        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4539        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4540        array<int> != array<float>.
4541
4542        Args:
4543            dtypes: the data types to compare this Cast's DataType to.
4544
4545        Returns:
4546            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4547        """
4548        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4524    @property
4525    def name(self) -> str:
4526        return self.this.name
to: DataType
4528    @property
4529    def to(self) -> DataType:
4530        return self.args["to"]
output_name: str
4532    @property
4533    def output_name(self) -> str:
4534        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:
4536    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4537        """
4538        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4539        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4540        array<int> != array<float>.
4541
4542        Args:
4543            dtypes: the data types to compare this Cast's DataType to.
4544
4545        Returns:
4546            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4547        """
4548        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):
4551class TryCast(Cast):
4552    pass
key = 'trycast'
class CastToStrType(Func):
4555class CastToStrType(Func):
4556    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4559class Collate(Binary, Func):
4560    pass
key = 'collate'
class Ceil(Func):
4563class Ceil(Func):
4564    arg_types = {"this": True, "decimals": False}
4565    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4568class Coalesce(Func):
4569    arg_types = {"this": True, "expressions": False}
4570    is_var_len_args = True
4571    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4574class Chr(Func):
4575    arg_types = {"this": True, "charset": False, "expressions": False}
4576    is_var_len_args = True
4577    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4580class Concat(Func):
4581    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4582    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4585class ConcatWs(Concat):
4586    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4589class Count(AggFunc):
4590    arg_types = {"this": False, "expressions": False}
4591    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4594class CountIf(AggFunc):
4595    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class CurrentDate(Func):
4598class CurrentDate(Func):
4599    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4602class CurrentDatetime(Func):
4603    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4606class CurrentTime(Func):
4607    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4610class CurrentTimestamp(Func):
4611    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4614class CurrentUser(Func):
4615    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4618class DateAdd(Func, IntervalOp):
4619    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4622class DateSub(Func, IntervalOp):
4623    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4626class DateDiff(Func, TimeUnit):
4627    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4628    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4631class DateTrunc(Func):
4632    arg_types = {"unit": True, "this": True, "zone": False}
4633
4634    def __init__(self, **args):
4635        unit = args.get("unit")
4636        if isinstance(unit, TimeUnit.VAR_LIKE):
4637            args["unit"] = Literal.string(
4638                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4639            )
4640        elif isinstance(unit, Week):
4641            unit.set("this", Literal.string(unit.this.name.upper()))
4642
4643        super().__init__(**args)
4644
4645    @property
4646    def unit(self) -> Expression:
4647        return self.args["unit"]
DateTrunc(**args)
4634    def __init__(self, **args):
4635        unit = args.get("unit")
4636        if isinstance(unit, TimeUnit.VAR_LIKE):
4637            args["unit"] = Literal.string(
4638                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4639            )
4640        elif isinstance(unit, Week):
4641            unit.set("this", Literal.string(unit.this.name.upper()))
4642
4643        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4645    @property
4646    def unit(self) -> Expression:
4647        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4650class DatetimeAdd(Func, IntervalOp):
4651    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4654class DatetimeSub(Func, IntervalOp):
4655    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4658class DatetimeDiff(Func, TimeUnit):
4659    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4662class DatetimeTrunc(Func, TimeUnit):
4663    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4666class DayOfWeek(Func):
4667    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4670class DayOfMonth(Func):
4671    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4674class DayOfYear(Func):
4675    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4678class ToDays(Func):
4679    pass
key = 'todays'
class WeekOfYear(Func):
4682class WeekOfYear(Func):
4683    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4686class MonthsBetween(Func):
4687    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4690class LastDay(Func, TimeUnit):
4691    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4692    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4695class Extract(Func):
4696    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4699class Timestamp(Func):
4700    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4703class TimestampAdd(Func, TimeUnit):
4704    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4707class TimestampSub(Func, TimeUnit):
4708    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4711class TimestampDiff(Func, TimeUnit):
4712    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4715class TimestampTrunc(Func, TimeUnit):
4716    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4719class TimeAdd(Func, TimeUnit):
4720    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4723class TimeSub(Func, TimeUnit):
4724    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4727class TimeDiff(Func, TimeUnit):
4728    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4731class TimeTrunc(Func, TimeUnit):
4732    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4735class DateFromParts(Func):
4736    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4737    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4740class TimeFromParts(Func):
4741    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4742    arg_types = {
4743        "hour": True,
4744        "min": True,
4745        "sec": True,
4746        "nano": False,
4747        "fractions": False,
4748        "precision": False,
4749    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4752class DateStrToDate(Func):
4753    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4756class DateToDateStr(Func):
4757    pass
key = 'datetodatestr'
class DateToDi(Func):
4760class DateToDi(Func):
4761    pass
key = 'datetodi'
class Date(Func):
4765class Date(Func):
4766    arg_types = {"this": False, "zone": False, "expressions": False}
4767    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4770class Day(Func):
4771    pass
key = 'day'
class Decode(Func):
4774class Decode(Func):
4775    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4778class DiToDate(Func):
4779    pass
key = 'ditodate'
class Encode(Func):
4782class Encode(Func):
4783    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4786class Exp(Func):
4787    pass
key = 'exp'
class Explode(Func):
4791class Explode(Func):
4792    arg_types = {"this": True, "expressions": False}
4793    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4796class ExplodeOuter(Explode):
4797    pass
key = 'explodeouter'
class Posexplode(Explode):
4800class Posexplode(Explode):
4801    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4804class PosexplodeOuter(Posexplode):
4805    pass
key = 'posexplodeouter'
class Floor(Func):
4808class Floor(Func):
4809    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4812class FromBase64(Func):
4813    pass
key = 'frombase64'
class ToBase64(Func):
4816class ToBase64(Func):
4817    pass
key = 'tobase64'
class Greatest(Func):
4820class Greatest(Func):
4821    arg_types = {"this": True, "expressions": False}
4822    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4825class GroupConcat(AggFunc):
4826    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4829class Hex(Func):
4830    pass
key = 'hex'
class Xor(Connector, Func):
4833class Xor(Connector, Func):
4834    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4837class If(Func):
4838    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4841class Nullif(Func):
4842    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4845class Initcap(Func):
4846    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4849class IsNan(Func):
4850    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4853class IsInf(Func):
4854    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class FormatJson(Expression):
4857class FormatJson(Expression):
4858    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4861class JSONKeyValue(Expression):
4862    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4865class JSONObject(Func):
4866    arg_types = {
4867        "expressions": False,
4868        "null_handling": False,
4869        "unique_keys": False,
4870        "return_type": False,
4871        "encoding": False,
4872    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
4875class JSONObjectAgg(AggFunc):
4876    arg_types = {
4877        "expressions": False,
4878        "null_handling": False,
4879        "unique_keys": False,
4880        "return_type": False,
4881        "encoding": False,
4882    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
4886class JSONArray(Func):
4887    arg_types = {
4888        "expressions": True,
4889        "null_handling": False,
4890        "return_type": False,
4891        "strict": False,
4892    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4896class JSONArrayAgg(Func):
4897    arg_types = {
4898        "this": True,
4899        "order": False,
4900        "null_handling": False,
4901        "return_type": False,
4902        "strict": False,
4903    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4908class JSONColumnDef(Expression):
4909    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):
4912class JSONSchema(Expression):
4913    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4917class JSONTable(Func):
4918    arg_types = {
4919        "this": True,
4920        "schema": True,
4921        "path": False,
4922        "error_handling": False,
4923        "empty_handling": False,
4924    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4927class OpenJSONColumnDef(Expression):
4928    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):
4931class OpenJSON(Func):
4932    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4935class JSONBContains(Binary):
4936    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4939class JSONExtract(Binary, Func):
4940    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4943class JSONExtractScalar(JSONExtract):
4944    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4947class JSONBExtract(JSONExtract):
4948    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4951class JSONBExtractScalar(JSONExtract):
4952    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4955class JSONFormat(Func):
4956    arg_types = {"this": False, "options": False}
4957    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4961class JSONArrayContains(Binary, Predicate, Func):
4962    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4965class ParseJSON(Func):
4966    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4967    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4968    arg_types = {"this": True, "expressions": False}
4969    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class GetPath(Func):
4973class GetPath(Func):
4974    arg_types = {"this": True, "expression": True}
4975
4976    @property
4977    def output_name(self) -> str:
4978        return self.expression.output_name
arg_types = {'this': True, 'expression': True}
output_name: str
4976    @property
4977    def output_name(self) -> str:
4978        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 = 'getpath'
class Least(Func):
4981class Least(Func):
4982    arg_types = {"this": True, "expressions": False}
4983    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4986class Left(Func):
4987    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4994class Length(Func):
4995    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4998class Levenshtein(Func):
4999    arg_types = {
5000        "this": True,
5001        "expression": False,
5002        "ins_cost": False,
5003        "del_cost": False,
5004        "sub_cost": False,
5005    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5008class Ln(Func):
5009    pass
key = 'ln'
class Log(Func):
5012class Log(Func):
5013    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
5016class Log2(Func):
5017    pass
key = 'log2'
class Log10(Func):
5020class Log10(Func):
5021    pass
key = 'log10'
class LogicalOr(AggFunc):
5024class LogicalOr(AggFunc):
5025    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5028class LogicalAnd(AggFunc):
5029    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5032class Lower(Func):
5033    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5036class Map(Func):
5037    arg_types = {"keys": False, "values": False}
5038
5039    @property
5040    def keys(self) -> t.List[Expression]:
5041        keys = self.args.get("keys")
5042        return keys.expressions if keys else []
5043
5044    @property
5045    def values(self) -> t.List[Expression]:
5046        values = self.args.get("values")
5047        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5039    @property
5040    def keys(self) -> t.List[Expression]:
5041        keys = self.args.get("keys")
5042        return keys.expressions if keys else []
values: List[Expression]
5044    @property
5045    def values(self) -> t.List[Expression]:
5046        values = self.args.get("values")
5047        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5050class MapFromEntries(Func):
5051    pass
key = 'mapfromentries'
class StarMap(Func):
5054class StarMap(Func):
5055    pass
key = 'starmap'
class VarMap(Func):
5058class VarMap(Func):
5059    arg_types = {"keys": True, "values": True}
5060    is_var_len_args = True
5061
5062    @property
5063    def keys(self) -> t.List[Expression]:
5064        return self.args["keys"].expressions
5065
5066    @property
5067    def values(self) -> t.List[Expression]:
5068        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5062    @property
5063    def keys(self) -> t.List[Expression]:
5064        return self.args["keys"].expressions
values: List[Expression]
5066    @property
5067    def values(self) -> t.List[Expression]:
5068        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5072class MatchAgainst(Func):
5073    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5076class Max(AggFunc):
5077    arg_types = {"this": True, "expressions": False}
5078    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5081class MD5(Func):
5082    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5086class MD5Digest(Func):
5087    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5090class Min(AggFunc):
5091    arg_types = {"this": True, "expressions": False}
5092    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5095class Month(Func):
5096    pass
key = 'month'
class Nvl2(Func):
5099class Nvl2(Func):
5100    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5104class Predict(Func):
5105    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5108class Pow(Binary, Func):
5109    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5112class PercentileCont(AggFunc):
5113    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5116class PercentileDisc(AggFunc):
5117    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5120class Quantile(AggFunc):
5121    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5124class ApproxQuantile(Quantile):
5125    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Rand(Func):
5128class Rand(Func):
5129    _sql_names = ["RAND", "RANDOM"]
5130    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5133class Randn(Func):
5134    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5137class RangeN(Func):
5138    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5141class ReadCSV(Func):
5142    _sql_names = ["READ_CSV"]
5143    is_var_len_args = True
5144    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5147class Reduce(Func):
5148    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):
5151class RegexpExtract(Func):
5152    arg_types = {
5153        "this": True,
5154        "expression": True,
5155        "position": False,
5156        "occurrence": False,
5157        "parameters": False,
5158        "group": False,
5159    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5162class RegexpReplace(Func):
5163    arg_types = {
5164        "this": True,
5165        "expression": True,
5166        "replacement": False,
5167        "position": False,
5168        "occurrence": False,
5169        "parameters": False,
5170        "modifiers": False,
5171    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5174class RegexpLike(Binary, Func):
5175    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5178class RegexpILike(Binary, Func):
5179    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5184class RegexpSplit(Func):
5185    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5188class Repeat(Func):
5189    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5194class Round(Func):
5195    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5198class RowNumber(Func):
5199    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5202class SafeDivide(Func):
5203    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5206class SHA(Func):
5207    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5210class SHA2(Func):
5211    _sql_names = ["SHA2"]
5212    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5215class SortArray(Func):
5216    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5219class Split(Func):
5220    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5225class Substring(Func):
5226    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5229class StandardHash(Func):
5230    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5233class StartsWith(Func):
5234    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5235    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5238class StrPosition(Func):
5239    arg_types = {
5240        "this": True,
5241        "substr": True,
5242        "position": False,
5243        "instance": False,
5244    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5247class StrToDate(Func):
5248    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5251class StrToTime(Func):
5252    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5257class StrToUnix(Func):
5258    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5263class StrToMap(Func):
5264    arg_types = {
5265        "this": True,
5266        "pair_delim": False,
5267        "key_value_delim": False,
5268        "duplicate_resolution_callback": False,
5269    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5272class NumberToStr(Func):
5273    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5276class FromBase(Func):
5277    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5280class Struct(Func):
5281    arg_types = {"expressions": False}
5282    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5285class StructExtract(Func):
5286    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5291class Stuff(Func):
5292    _sql_names = ["STUFF", "INSERT"]
5293    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):
5296class Sum(AggFunc):
5297    pass
key = 'sum'
class Sqrt(Func):
5300class Sqrt(Func):
5301    pass
key = 'sqrt'
class Stddev(AggFunc):
5304class Stddev(AggFunc):
5305    pass
key = 'stddev'
class StddevPop(AggFunc):
5308class StddevPop(AggFunc):
5309    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5312class StddevSamp(AggFunc):
5313    pass
key = 'stddevsamp'
class TimeToStr(Func):
5316class TimeToStr(Func):
5317    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5320class TimeToTimeStr(Func):
5321    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5324class TimeToUnix(Func):
5325    pass
key = 'timetounix'
class TimeStrToDate(Func):
5328class TimeStrToDate(Func):
5329    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5332class TimeStrToTime(Func):
5333    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5336class TimeStrToUnix(Func):
5337    pass
key = 'timestrtounix'
class Trim(Func):
5340class Trim(Func):
5341    arg_types = {
5342        "this": True,
5343        "expression": False,
5344        "position": False,
5345        "collation": False,
5346    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5349class TsOrDsAdd(Func, TimeUnit):
5350    # return_type is used to correctly cast the arguments of this expression when transpiling it
5351    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5352
5353    @property
5354    def return_type(self) -> DataType:
5355        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
5353    @property
5354    def return_type(self) -> DataType:
5355        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5358class TsOrDsDiff(Func, TimeUnit):
5359    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5362class TsOrDsToDateStr(Func):
5363    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5366class TsOrDsToDate(Func):
5367    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5370class TsOrDsToTime(Func):
5371    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5374class TsOrDiToDi(Func):
5375    pass
key = 'tsorditodi'
class Unhex(Func):
5378class Unhex(Func):
5379    pass
key = 'unhex'
class UnixDate(Func):
5383class UnixDate(Func):
5384    pass
key = 'unixdate'
class UnixToStr(Func):
5387class UnixToStr(Func):
5388    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5393class UnixToTime(Func):
5394    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5395
5396    SECONDS = Literal.number(0)
5397    DECIS = Literal.number(1)
5398    CENTIS = Literal.number(2)
5399    MILLIS = Literal.number(3)
5400    DECIMILLIS = Literal.number(4)
5401    CENTIMILLIS = Literal.number(5)
5402    MICROS = Literal.number(6)
5403    DECIMICROS = Literal.number(7)
5404    CENTIMICROS = Literal.number(8)
5405    NANOS = Literal.number(9)
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': 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):
5408class UnixToTimeStr(Func):
5409    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5412class TimestampFromParts(Func):
5413    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5414    arg_types = {
5415        "year": True,
5416        "month": True,
5417        "day": True,
5418        "hour": True,
5419        "min": True,
5420        "sec": True,
5421        "nano": False,
5422        "zone": False,
5423        "milli": False,
5424    }
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):
5427class Upper(Func):
5428    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5431class Variance(AggFunc):
5432    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5435class VariancePop(AggFunc):
5436    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5439class Week(Func):
5440    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5443class XMLTable(Func):
5444    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):
5447class Year(Func):
5448    pass
key = 'year'
class Use(Expression):
5451class Use(Expression):
5452    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5455class Merge(Expression):
5456    arg_types = {"this": True, "using": True, "on": True, "expressions": True, "with": False}
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5459class When(Func):
5460    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):
5465class NextValueFor(Func):
5466    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <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 'ArrayContains'>, <class 'ArrayFilter'>, <class 'ArrayJoin'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'Count'>, <class 'CountIf'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'GetPath'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Last'>, <class 'LastDay'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'Log10'>, <class 'Log2'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <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 '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 '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 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <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'>, '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_CONTAINS': <class 'ArrayContains'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_JOIN': <class 'ArrayJoin'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, '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'>, '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'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GET_PATH': <class 'GetPath'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOG10': <class 'Log10'>, 'LOG2': <class 'Log2'>, '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'>, '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'>, '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'>, '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'>, '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'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, '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'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, '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'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, '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'>}
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:
5504def maybe_parse(
5505    sql_or_expression: ExpOrStr,
5506    *,
5507    into: t.Optional[IntoType] = None,
5508    dialect: DialectType = None,
5509    prefix: t.Optional[str] = None,
5510    copy: bool = False,
5511    **opts,
5512) -> Expression:
5513    """Gracefully handle a possible string or expression.
5514
5515    Example:
5516        >>> maybe_parse("1")
5517        Literal(this=1, is_string=False)
5518        >>> maybe_parse(to_identifier("x"))
5519        Identifier(this=x, quoted=False)
5520
5521    Args:
5522        sql_or_expression: the SQL code string or an expression
5523        into: the SQLGlot Expression to parse into
5524        dialect: the dialect used to parse the input expressions (in the case that an
5525            input expression is a SQL string).
5526        prefix: a string to prefix the sql with before it gets parsed
5527            (automatically includes a space)
5528        copy: whether or not to copy the expression.
5529        **opts: other options to use to parse the input expressions (again, in the case
5530            that an input expression is a SQL string).
5531
5532    Returns:
5533        Expression: the parsed or given expression.
5534    """
5535    if isinstance(sql_or_expression, Expression):
5536        if copy:
5537            return sql_or_expression.copy()
5538        return sql_or_expression
5539
5540    if sql_or_expression is None:
5541        raise ParseError(f"SQL cannot be None")
5542
5543    import sqlglot
5544
5545    sql = str(sql_or_expression)
5546    if prefix:
5547        sql = f"{prefix} {sql}"
5548
5549    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 or not 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):
5562def maybe_copy(instance, copy=True):
5563    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:
5777def union(
5778    left: ExpOrStr,
5779    right: ExpOrStr,
5780    distinct: bool = True,
5781    dialect: DialectType = None,
5782    copy: bool = True,
5783    **opts,
5784) -> Union:
5785    """
5786    Initializes a syntax tree from one UNION expression.
5787
5788    Example:
5789        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5790        'SELECT * FROM foo UNION SELECT * FROM bla'
5791
5792    Args:
5793        left: the SQL code string corresponding to the left-hand side.
5794            If an `Expression` instance is passed, it will be used as-is.
5795        right: the SQL code string corresponding to the right-hand side.
5796            If an `Expression` instance is passed, it will be used as-is.
5797        distinct: set the DISTINCT flag if and only if this is true.
5798        dialect: the dialect used to parse the input expression.
5799        copy: whether or not to copy the expression.
5800        opts: other options to use to parse the input expressions.
5801
5802    Returns:
5803        The new Union instance.
5804    """
5805    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5806    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5807
5808    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 or not 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:
5811def intersect(
5812    left: ExpOrStr,
5813    right: ExpOrStr,
5814    distinct: bool = True,
5815    dialect: DialectType = None,
5816    copy: bool = True,
5817    **opts,
5818) -> Intersect:
5819    """
5820    Initializes a syntax tree from one INTERSECT expression.
5821
5822    Example:
5823        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5824        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5825
5826    Args:
5827        left: the SQL code string corresponding to the left-hand side.
5828            If an `Expression` instance is passed, it will be used as-is.
5829        right: the SQL code string corresponding to the right-hand side.
5830            If an `Expression` instance is passed, it will be used as-is.
5831        distinct: set the DISTINCT flag if and only if this is true.
5832        dialect: the dialect used to parse the input expression.
5833        copy: whether or not to copy the expression.
5834        opts: other options to use to parse the input expressions.
5835
5836    Returns:
5837        The new Intersect instance.
5838    """
5839    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5840    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5841
5842    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 or not 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:
5845def except_(
5846    left: ExpOrStr,
5847    right: ExpOrStr,
5848    distinct: bool = True,
5849    dialect: DialectType = None,
5850    copy: bool = True,
5851    **opts,
5852) -> Except:
5853    """
5854    Initializes a syntax tree from one EXCEPT expression.
5855
5856    Example:
5857        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5858        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5859
5860    Args:
5861        left: the SQL code string corresponding to the left-hand side.
5862            If an `Expression` instance is passed, it will be used as-is.
5863        right: the SQL code string corresponding to the right-hand side.
5864            If an `Expression` instance is passed, it will be used as-is.
5865        distinct: set the DISTINCT flag if and only if this is true.
5866        dialect: the dialect used to parse the input expression.
5867        copy: whether or not to copy the expression.
5868        opts: other options to use to parse the input expressions.
5869
5870    Returns:
5871        The new Except instance.
5872    """
5873    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5874    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5875
5876    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 or not 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:
5879def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5880    """
5881    Initializes a syntax tree from one or multiple SELECT expressions.
5882
5883    Example:
5884        >>> select("col1", "col2").from_("tbl").sql()
5885        'SELECT col1, col2 FROM tbl'
5886
5887    Args:
5888        *expressions: the SQL code string to parse as the expressions of a
5889            SELECT statement. If an Expression instance is passed, this is used as-is.
5890        dialect: the dialect used to parse the input expressions (in the case that an
5891            input expression is a SQL string).
5892        **opts: other options to use to parse the input expressions (again, in the case
5893            that an input expression is a SQL string).
5894
5895    Returns:
5896        Select: the syntax tree for the SELECT statement.
5897    """
5898    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:
5901def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5902    """
5903    Initializes a syntax tree from a FROM expression.
5904
5905    Example:
5906        >>> from_("tbl").select("col1", "col2").sql()
5907        'SELECT col1, col2 FROM tbl'
5908
5909    Args:
5910        *expression: the SQL code string to parse as the FROM expressions of a
5911            SELECT statement. If an Expression instance is passed, this is used as-is.
5912        dialect: the dialect used to parse the input expression (in the case that the
5913            input expression is a SQL string).
5914        **opts: other options to use to parse the input expressions (again, in the case
5915            that the input expression is a SQL string).
5916
5917    Returns:
5918        Select: the syntax tree for the SELECT statement.
5919    """
5920    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:
5923def update(
5924    table: str | Table,
5925    properties: dict,
5926    where: t.Optional[ExpOrStr] = None,
5927    from_: t.Optional[ExpOrStr] = None,
5928    dialect: DialectType = None,
5929    **opts,
5930) -> Update:
5931    """
5932    Creates an update statement.
5933
5934    Example:
5935        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5936        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5937
5938    Args:
5939        *properties: dictionary of properties to set which are
5940            auto converted to sql objects eg None -> NULL
5941        where: sql conditional parsed into a WHERE statement
5942        from_: sql statement parsed into a FROM statement
5943        dialect: the dialect used to parse the input expressions.
5944        **opts: other options to use to parse the input expressions.
5945
5946    Returns:
5947        Update: the syntax tree for the UPDATE statement.
5948    """
5949    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5950    update_expr.set(
5951        "expressions",
5952        [
5953            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5954            for k, v in properties.items()
5955        ],
5956    )
5957    if from_:
5958        update_expr.set(
5959            "from",
5960            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5961        )
5962    if isinstance(where, Condition):
5963        where = Where(this=where)
5964    if where:
5965        update_expr.set(
5966            "where",
5967            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5968        )
5969    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:
5972def delete(
5973    table: ExpOrStr,
5974    where: t.Optional[ExpOrStr] = None,
5975    returning: t.Optional[ExpOrStr] = None,
5976    dialect: DialectType = None,
5977    **opts,
5978) -> Delete:
5979    """
5980    Builds a delete statement.
5981
5982    Example:
5983        >>> delete("my_table", where="id > 1").sql()
5984        'DELETE FROM my_table WHERE id > 1'
5985
5986    Args:
5987        where: sql conditional parsed into a WHERE statement
5988        returning: sql conditional parsed into a RETURNING statement
5989        dialect: the dialect used to parse the input expressions.
5990        **opts: other options to use to parse the input expressions.
5991
5992    Returns:
5993        Delete: the syntax tree for the DELETE statement.
5994    """
5995    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5996    if where:
5997        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5998    if returning:
5999        delete_expr = t.cast(
6000            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6001        )
6002    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:
6005def insert(
6006    expression: ExpOrStr,
6007    into: ExpOrStr,
6008    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6009    overwrite: t.Optional[bool] = None,
6010    returning: t.Optional[ExpOrStr] = None,
6011    dialect: DialectType = None,
6012    copy: bool = True,
6013    **opts,
6014) -> Insert:
6015    """
6016    Builds an INSERT statement.
6017
6018    Example:
6019        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6020        'INSERT INTO tbl VALUES (1, 2, 3)'
6021
6022    Args:
6023        expression: the sql string or expression of the INSERT statement
6024        into: the tbl to insert data to.
6025        columns: optionally the table's column names.
6026        overwrite: whether to INSERT OVERWRITE or not.
6027        returning: sql conditional parsed into a RETURNING statement
6028        dialect: the dialect used to parse the input expressions.
6029        copy: whether or not to copy the expression.
6030        **opts: other options to use to parse the input expressions.
6031
6032    Returns:
6033        Insert: the syntax tree for the INSERT statement.
6034    """
6035    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6036    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6037
6038    if columns:
6039        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6040
6041    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6042
6043    if returning:
6044        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6045
6046    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 or not 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:
6049def condition(
6050    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6051) -> Condition:
6052    """
6053    Initialize a logical condition expression.
6054
6055    Example:
6056        >>> condition("x=1").sql()
6057        'x = 1'
6058
6059        This is helpful for composing larger logical syntax trees:
6060        >>> where = condition("x=1")
6061        >>> where = where.and_("y=1")
6062        >>> Select().from_("tbl").select("*").where(where).sql()
6063        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6064
6065    Args:
6066        *expression: the SQL code string to parse.
6067            If an Expression instance is passed, this is used as-is.
6068        dialect: the dialect used to parse the input expression (in the case that the
6069            input expression is a SQL string).
6070        copy: Whether or not to copy `expression` (only applies to expressions).
6071        **opts: other options to use to parse the input expressions (again, in the case
6072            that the input expression is a SQL string).
6073
6074    Returns:
6075        The new Condition instance
6076    """
6077    return maybe_parse(
6078        expression,
6079        into=Condition,
6080        dialect=dialect,
6081        copy=copy,
6082        **opts,
6083    )

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 or not 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:
6086def and_(
6087    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6088) -> Condition:
6089    """
6090    Combine multiple conditions with an AND logical operator.
6091
6092    Example:
6093        >>> and_("x=1", and_("y=1", "z=1")).sql()
6094        'x = 1 AND (y = 1 AND z = 1)'
6095
6096    Args:
6097        *expressions: the SQL code strings to parse.
6098            If an Expression instance is passed, this is used as-is.
6099        dialect: the dialect used to parse the input expression.
6100        copy: whether or not to copy `expressions` (only applies to Expressions).
6101        **opts: other options to use to parse the input expressions.
6102
6103    Returns:
6104        And: the new condition
6105    """
6106    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 or not to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

And: 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:
6109def or_(
6110    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6111) -> Condition:
6112    """
6113    Combine multiple conditions with an OR logical operator.
6114
6115    Example:
6116        >>> or_("x=1", or_("y=1", "z=1")).sql()
6117        'x = 1 OR (y = 1 OR z = 1)'
6118
6119    Args:
6120        *expressions: the SQL code strings to parse.
6121            If an Expression instance is passed, this is used as-is.
6122        dialect: the dialect used to parse the input expression.
6123        copy: whether or not to copy `expressions` (only applies to Expressions).
6124        **opts: other options to use to parse the input expressions.
6125
6126    Returns:
6127        Or: the new condition
6128    """
6129    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 or not to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

Or: 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:
6132def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6133    """
6134    Wrap a condition with a NOT operator.
6135
6136    Example:
6137        >>> not_("this_suit='black'").sql()
6138        "NOT this_suit = 'black'"
6139
6140    Args:
6141        expression: the SQL code string to parse.
6142            If an Expression instance is passed, this is used as-is.
6143        dialect: the dialect used to parse the input expression.
6144        copy: whether to copy the expression or not.
6145        **opts: other options to use to parse the input expressions.
6146
6147    Returns:
6148        The new condition.
6149    """
6150    this = condition(
6151        expression,
6152        dialect=dialect,
6153        copy=copy,
6154        **opts,
6155    )
6156    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:
6159def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6160    """
6161    Wrap an expression in parentheses.
6162
6163    Example:
6164        >>> paren("5 + 3").sql()
6165        '(5 + 3)'
6166
6167    Args:
6168        expression: the SQL code string to parse.
6169            If an Expression instance is passed, this is used as-is.
6170        copy: whether to copy the expression or not.
6171
6172    Returns:
6173        The wrapped expression.
6174    """
6175    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 = re.compile('^[_a-zA-Z][\\w]*$')
def to_identifier(name, quoted=None, copy=True):
6193def to_identifier(name, quoted=None, copy=True):
6194    """Builds an identifier.
6195
6196    Args:
6197        name: The name to turn into an identifier.
6198        quoted: Whether or not force quote the identifier.
6199        copy: Whether or not to copy name if it's an Identifier.
6200
6201    Returns:
6202        The identifier ast node.
6203    """
6204
6205    if name is None:
6206        return None
6207
6208    if isinstance(name, Identifier):
6209        identifier = maybe_copy(name, copy)
6210    elif isinstance(name, str):
6211        identifier = Identifier(
6212            this=name,
6213            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6214        )
6215    else:
6216        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6217    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether or not force quote the identifier.
  • copy: Whether or not 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:
6220def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6221    """
6222    Parses a given string into an identifier.
6223
6224    Args:
6225        name: The name to parse into an identifier.
6226        dialect: The dialect to parse against.
6227
6228    Returns:
6229        The identifier ast node.
6230    """
6231    try:
6232        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6233    except ParseError:
6234        expression = to_identifier(name)
6235
6236    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:
6242def to_interval(interval: str | Literal) -> Interval:
6243    """Builds an interval expression from a string like '1 day' or '5 months'."""
6244    if isinstance(interval, Literal):
6245        if not interval.is_string:
6246            raise ValueError("Invalid interval string.")
6247
6248        interval = interval.this
6249
6250    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6251
6252    if not interval_parts:
6253        raise ValueError("Invalid interval string.")
6254
6255    return Interval(
6256        this=Literal.string(interval_parts.group(1)),
6257        unit=Var(this=interval_parts.group(2).upper()),
6258    )

Builds an interval expression from a string like '1 day' or '5 months'.

def to_table( sql_path: Union[str, Table, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Optional[Table]:
6271def to_table(
6272    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6273) -> t.Optional[Table]:
6274    """
6275    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6276    If a table is passed in then that table is returned.
6277
6278    Args:
6279        sql_path: a `[catalog].[schema].[table]` string.
6280        dialect: the source dialect according to which the table name will be parsed.
6281        copy: Whether or not to copy a table if it is passed in.
6282        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6283
6284    Returns:
6285        A table expression.
6286    """
6287    if sql_path is None or isinstance(sql_path, Table):
6288        return maybe_copy(sql_path, copy=copy)
6289    if not isinstance(sql_path, str):
6290        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6291
6292    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6293    if table:
6294        for k, v in kwargs.items():
6295            table.set(k, v)
6296
6297    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 or not 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, **kwargs) -> Column:
6300def to_column(sql_path: str | Column, **kwargs) -> Column:
6301    """
6302    Create a column from a `[table].[column]` sql path. Schema is optional.
6303
6304    If a column is passed in then that column is returned.
6305
6306    Args:
6307        sql_path: `[table].[column]` string
6308    Returns:
6309        Table: A column expression
6310    """
6311    if sql_path is None or isinstance(sql_path, Column):
6312        return sql_path
6313    if not isinstance(sql_path, str):
6314        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6315    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore

Create a column from a [table].[column] sql path. Schema is optional.

If a column is passed in then that column is returned.

Arguments:
  • sql_path: [table].[column] string
Returns:

Table: A column expression

def alias_( expression: Union[str, Expression], alias: str | Identifier, 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):
6318def alias_(
6319    expression: ExpOrStr,
6320    alias: str | Identifier,
6321    table: bool | t.Sequence[str | Identifier] = False,
6322    quoted: t.Optional[bool] = None,
6323    dialect: DialectType = None,
6324    copy: bool = True,
6325    **opts,
6326):
6327    """Create an Alias expression.
6328
6329    Example:
6330        >>> alias_('foo', 'bar').sql()
6331        'foo AS bar'
6332
6333        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6334        '(SELECT 1, 2) AS bar(a, b)'
6335
6336    Args:
6337        expression: the SQL code strings to parse.
6338            If an Expression instance is passed, this is used as-is.
6339        alias: the alias name to use. If the name has
6340            special characters it is quoted.
6341        table: Whether or not to create a table alias, can also be a list of columns.
6342        quoted: whether or not to quote the alias
6343        dialect: the dialect used to parse the input expression.
6344        copy: Whether or not to copy the expression.
6345        **opts: other options to use to parse the input expressions.
6346
6347    Returns:
6348        Alias: the aliased expression
6349    """
6350    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6351    alias = to_identifier(alias, quoted=quoted)
6352
6353    if table:
6354        table_alias = TableAlias(this=alias)
6355        exp.set("alias", table_alias)
6356
6357        if not isinstance(table, bool):
6358            for column in table:
6359                table_alias.append("columns", to_identifier(column, quoted=quoted))
6360
6361        return exp
6362
6363    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6364    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6365    # for the complete Window expression.
6366    #
6367    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6368
6369    if "alias" in exp.arg_types and not isinstance(exp, Window):
6370        exp.set("alias", alias)
6371        return exp
6372    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 or not to create a table alias, can also be a list of columns.
  • quoted: whether or not to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether or not 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:
6375def subquery(
6376    expression: ExpOrStr,
6377    alias: t.Optional[Identifier | str] = None,
6378    dialect: DialectType = None,
6379    **opts,
6380) -> Select:
6381    """
6382    Build a subquery expression.
6383
6384    Example:
6385        >>> subquery('select x from tbl', 'bar').select('x').sql()
6386        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6387
6388    Args:
6389        expression: the SQL code strings to parse.
6390            If an Expression instance is passed, this is used as-is.
6391        alias: the alias name to use.
6392        dialect: the dialect used to parse the input expression.
6393        **opts: other options to use to parse the input expressions.
6394
6395    Returns:
6396        A new Select instance with the subquery expression included.
6397    """
6398
6399    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6400    return Select().from_(expression, dialect=dialect, **opts)

Build a subquery expression.

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):
6431def column(
6432    col,
6433    table=None,
6434    db=None,
6435    catalog=None,
6436    *,
6437    fields=None,
6438    quoted=None,
6439    copy=True,
6440):
6441    """
6442    Build a Column.
6443
6444    Args:
6445        col: Column name.
6446        table: Table name.
6447        db: Database name.
6448        catalog: Catalog name.
6449        fields: Additional fields using dots.
6450        quoted: Whether to force quotes on the column's identifiers.
6451        copy: Whether or not to copy identifiers if passed in.
6452
6453    Returns:
6454        The new Column instance.
6455    """
6456    this = Column(
6457        this=to_identifier(col, quoted=quoted, copy=copy),
6458        table=to_identifier(table, quoted=quoted, copy=copy),
6459        db=to_identifier(db, quoted=quoted, copy=copy),
6460        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6461    )
6462
6463    if fields:
6464        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6465    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 or not to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], **opts) -> Cast:
6468def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6469    """Cast an expression to a data type.
6470
6471    Example:
6472        >>> cast('x + 1', 'int').sql()
6473        'CAST(x + 1 AS INT)'
6474
6475    Args:
6476        expression: The expression to cast.
6477        to: The datatype to cast to.
6478
6479    Returns:
6480        The new Cast instance.
6481    """
6482    expression = maybe_parse(expression, **opts)
6483    data_type = DataType.build(to, **opts)
6484    expression = Cast(this=expression, to=data_type)
6485    expression.type = data_type
6486    return expression

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.
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:
6489def table_(
6490    table: Identifier | str,
6491    db: t.Optional[Identifier | str] = None,
6492    catalog: t.Optional[Identifier | str] = None,
6493    quoted: t.Optional[bool] = None,
6494    alias: t.Optional[Identifier | str] = None,
6495) -> Table:
6496    """Build a Table.
6497
6498    Args:
6499        table: Table name.
6500        db: Database name.
6501        catalog: Catalog name.
6502        quote: Whether to force quotes on the table's identifiers.
6503        alias: Table's alias.
6504
6505    Returns:
6506        The new Table instance.
6507    """
6508    return Table(
6509        this=to_identifier(table, quoted=quoted) if table else None,
6510        db=to_identifier(db, quoted=quoted) if db else None,
6511        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6512        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6513    )

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:
6516def values(
6517    values: t.Iterable[t.Tuple[t.Any, ...]],
6518    alias: t.Optional[str] = None,
6519    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6520) -> Values:
6521    """Build VALUES statement.
6522
6523    Example:
6524        >>> values([(1, '2')]).sql()
6525        "VALUES (1, '2')"
6526
6527    Args:
6528        values: values statements that will be converted to SQL
6529        alias: optional alias
6530        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6531         If either are provided then an alias is also required.
6532
6533    Returns:
6534        Values: the Values expression object
6535    """
6536    if columns and not alias:
6537        raise ValueError("Alias is required when providing columns")
6538
6539    return Values(
6540        expressions=[convert(tup) for tup in values],
6541        alias=(
6542            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6543            if columns
6544            else (TableAlias(this=to_identifier(alias)) if alias else None)
6545        ),
6546    )

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:
6549def var(name: t.Optional[ExpOrStr]) -> Var:
6550    """Build a SQL variable.
6551
6552    Example:
6553        >>> repr(var('x'))
6554        'Var(this=x)'
6555
6556        >>> repr(var(column('x', table='y')))
6557        'Var(this=x)'
6558
6559    Args:
6560        name: The name of the var or an expression who's name will become the var.
6561
6562    Returns:
6563        The new variable node.
6564    """
6565    if not name:
6566        raise ValueError("Cannot convert empty name into var.")
6567
6568    if isinstance(name, Expression):
6569        name = name.name
6570    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) -> AlterTable:
6573def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6574    """Build ALTER TABLE... RENAME... expression
6575
6576    Args:
6577        old_name: The old name of the table
6578        new_name: The new name of the table
6579
6580    Returns:
6581        Alter table expression
6582    """
6583    old_table = to_table(old_name)
6584    new_table = to_table(new_name)
6585    return AlterTable(
6586        this=old_table,
6587        actions=[
6588            RenameTable(this=new_table),
6589        ],
6590    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of 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) -> AlterTable:
6593def rename_column(
6594    table_name: str | Table,
6595    old_column_name: str | Column,
6596    new_column_name: str | Column,
6597    exists: t.Optional[bool] = None,
6598) -> AlterTable:
6599    """Build ALTER TABLE... RENAME COLUMN... expression
6600
6601    Args:
6602        table_name: Name of the table
6603        old_column: The old name of the column
6604        new_column: The new name of the column
6605        exists: Whether or not to add the `IF EXISTS` clause
6606
6607    Returns:
6608        Alter table expression
6609    """
6610    table = to_table(table_name)
6611    old_column = to_column(old_column_name)
6612    new_column = to_column(new_column_name)
6613    return AlterTable(
6614        this=table,
6615        actions=[
6616            RenameColumn(this=old_column, to=new_column, exists=exists),
6617        ],
6618    )

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 or not to add the IF EXISTS clause
Returns:

Alter table expression

def convert(value: Any, copy: bool = False) -> Expression:
6621def convert(value: t.Any, copy: bool = False) -> Expression:
6622    """Convert a python value into an expression object.
6623
6624    Raises an error if a conversion is not possible.
6625
6626    Args:
6627        value: A python object.
6628        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6629
6630    Returns:
6631        Expression: the equivalent expression object.
6632    """
6633    if isinstance(value, Expression):
6634        return maybe_copy(value, copy)
6635    if isinstance(value, str):
6636        return Literal.string(value)
6637    if isinstance(value, bool):
6638        return Boolean(this=value)
6639    if value is None or (isinstance(value, float) and math.isnan(value)):
6640        return NULL
6641    if isinstance(value, numbers.Number):
6642        return Literal.number(value)
6643    if isinstance(value, datetime.datetime):
6644        datetime_literal = Literal.string(
6645            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6646        )
6647        return TimeStrToTime(this=datetime_literal)
6648    if isinstance(value, datetime.date):
6649        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6650        return DateStrToDate(this=date_literal)
6651    if isinstance(value, tuple):
6652        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6653    if isinstance(value, list):
6654        return Array(expressions=[convert(v, copy=copy) for v in value])
6655    if isinstance(value, dict):
6656        return Map(
6657            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6658            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6659        )
6660    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 or not to copy value (only applies to Expressions and collections).
Returns:

Expression: the equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
6663def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6664    """
6665    Replace children of an expression with the result of a lambda fun(child) -> exp.
6666    """
6667    for k, v in expression.args.items():
6668        is_list_arg = type(v) is list
6669
6670        child_nodes = v if is_list_arg else [v]
6671        new_child_nodes = []
6672
6673        for cn in child_nodes:
6674            if isinstance(cn, Expression):
6675                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6676                    new_child_nodes.append(child_node)
6677                    child_node.parent = expression
6678                    child_node.arg_key = k
6679            else:
6680                new_child_nodes.append(cn)
6681
6682        expression.args[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 column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
6685def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6686    """
6687    Return all table names referenced through columns in an expression.
6688
6689    Example:
6690        >>> import sqlglot
6691        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6692        ['a', 'c']
6693
6694    Args:
6695        expression: expression to find table names.
6696        exclude: a table name to exclude
6697
6698    Returns:
6699        A list of unique names.
6700    """
6701    return {
6702        table
6703        for table in (column.table for column in expression.find_all(Column))
6704        if table and table != exclude
6705    }

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:
6708def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6709    """Get the full name of a table as a string.
6710
6711    Args:
6712        table: Table expression node or string.
6713        dialect: The dialect to generate the table name for.
6714        identify: Determines when an identifier should be quoted. Possible values are:
6715            False (default): Never quote, except in cases where it's mandatory by the dialect.
6716            True: Always quote.
6717
6718    Examples:
6719        >>> from sqlglot import exp, parse_one
6720        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6721        'a.b.c'
6722
6723    Returns:
6724        The table name.
6725    """
6726
6727    table = maybe_parse(table, into=Table, dialect=dialect)
6728
6729    if not table:
6730        raise ValueError(f"Cannot parse {table}")
6731
6732    return ".".join(
6733        part.sql(dialect=dialect, identify=True, copy=False)
6734        if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6735        else part.name
6736        for part in table.parts
6737    )

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:
6740def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6741    """Returns a case normalized table name without quotes.
6742
6743    Args:
6744        table: the table to normalize
6745        dialect: the dialect to use for normalization rules
6746        copy: whether or not to copy the expression.
6747
6748    Examples:
6749        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6750        'A-B.c'
6751    """
6752    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6753
6754    return ".".join(
6755        p.name
6756        for p in normalize_identifiers(
6757            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6758        ).parts
6759    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether or not 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:
6762def replace_tables(
6763    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6764) -> E:
6765    """Replace all tables in expression according to the mapping.
6766
6767    Args:
6768        expression: expression node to be transformed and replaced.
6769        mapping: mapping of table names.
6770        dialect: the dialect of the mapping table
6771        copy: whether or not to copy the expression.
6772
6773    Examples:
6774        >>> from sqlglot import exp, parse_one
6775        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6776        'SELECT * FROM c /* a.b */'
6777
6778    Returns:
6779        The mapped expression.
6780    """
6781
6782    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6783
6784    def _replace_tables(node: Expression) -> Expression:
6785        if isinstance(node, Table):
6786            original = normalize_table_name(node, dialect=dialect)
6787            new_name = mapping.get(original)
6788
6789            if new_name:
6790                table = to_table(
6791                    new_name,
6792                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6793                )
6794                table.add_comments([original])
6795                return table
6796        return node
6797
6798    return expression.transform(_replace_tables, copy=copy)

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 or not 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:
6801def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6802    """Replace placeholders in an expression.
6803
6804    Args:
6805        expression: expression node to be transformed and replaced.
6806        args: positional names that will substitute unnamed placeholders in the given order.
6807        kwargs: keyword arguments that will substitute named placeholders.
6808
6809    Examples:
6810        >>> from sqlglot import exp, parse_one
6811        >>> replace_placeholders(
6812        ...     parse_one("select * from :tbl where ? = ?"),
6813        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6814        ... ).sql()
6815        "SELECT * FROM foo WHERE str_col = 'b'"
6816
6817    Returns:
6818        The mapped expression.
6819    """
6820
6821    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6822        if isinstance(node, Placeholder):
6823            if node.name:
6824                new_name = kwargs.get(node.name)
6825                if new_name:
6826                    return convert(new_name)
6827            else:
6828                try:
6829                    return convert(next(args))
6830                except StopIteration:
6831                    pass
6832        return node
6833
6834    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, Subqueryable], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
6837def expand(
6838    expression: Expression,
6839    sources: t.Dict[str, Subqueryable],
6840    dialect: DialectType = None,
6841    copy: bool = True,
6842) -> Expression:
6843    """Transforms an expression by expanding all referenced sources into subqueries.
6844
6845    Examples:
6846        >>> from sqlglot import parse_one
6847        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6848        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6849
6850        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6851        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6852
6853    Args:
6854        expression: The expression to expand.
6855        sources: A dictionary of name to Subqueryables.
6856        dialect: The dialect of the sources dict.
6857        copy: Whether or not to copy the expression during transformation. Defaults to True.
6858
6859    Returns:
6860        The transformed expression.
6861    """
6862    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6863
6864    def _expand(node: Expression):
6865        if isinstance(node, Table):
6866            name = normalize_table_name(node, dialect=dialect)
6867            source = sources.get(name)
6868            if source:
6869                subquery = source.subquery(node.alias or name)
6870                subquery.comments = [f"source: {name}"]
6871                return subquery.transform(_expand, copy=False)
6872        return node
6873
6874    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 Subqueryables.
  • dialect: The dialect of the sources dict.
  • copy: Whether or not 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:
6877def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
6878    """
6879    Returns a Func expression.
6880
6881    Examples:
6882        >>> func("abs", 5).sql()
6883        'ABS(5)'
6884
6885        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6886        'CAST(5 AS DOUBLE)'
6887
6888    Args:
6889        name: the name of the function to build.
6890        args: the args used to instantiate the function of interest.
6891        copy: whether or not to copy the argument expressions.
6892        dialect: the source dialect.
6893        kwargs: the kwargs used to instantiate the function of interest.
6894
6895    Note:
6896        The arguments `args` and `kwargs` are mutually exclusive.
6897
6898    Returns:
6899        An instance of the function of interest, or an anonymous function, if `name` doesn't
6900        correspond to an existing `sqlglot.expressions.Func` class.
6901    """
6902    if args and kwargs:
6903        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6904
6905    from sqlglot.dialects.dialect import Dialect
6906
6907    dialect = Dialect.get_or_raise(dialect)
6908
6909    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
6910    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
6911
6912    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
6913    if constructor:
6914        if converted:
6915            if "dialect" in constructor.__code__.co_varnames:
6916                function = constructor(converted, dialect=dialect)
6917            else:
6918                function = constructor(converted)
6919        elif constructor.__name__ == "from_arg_list":
6920            function = constructor.__self__(**kwargs)  # type: ignore
6921        else:
6922            constructor = FUNCTION_BY_NAME.get(name.upper())
6923            if constructor:
6924                function = constructor(**kwargs)
6925            else:
6926                raise ValueError(
6927                    f"Unable to convert '{name}' into a Func. Either manually construct "
6928                    "the Func expression of interest or parse the function call."
6929                )
6930    else:
6931        kwargs = kwargs or {"expressions": converted}
6932        function = Anonymous(this=name, **kwargs)
6933
6934    for error_message in function.error_messages(converted):
6935        raise ValueError(error_message)
6936
6937    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 or not 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:
6940def case(
6941    expression: t.Optional[ExpOrStr] = None,
6942    **opts,
6943) -> Case:
6944    """
6945    Initialize a CASE statement.
6946
6947    Example:
6948        case().when("a = 1", "foo").else_("bar")
6949
6950    Args:
6951        expression: Optionally, the input expression (not all dialects support this)
6952        **opts: Extra keyword arguments for parsing `expression`
6953    """
6954    if expression is not None:
6955        this = maybe_parse(expression, **opts)
6956    else:
6957        this = None
6958    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 cast_unless( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], *types: Union[str, DataType, DataType.Type], **opts: Any) -> Expression | Cast:
6961def cast_unless(
6962    expression: ExpOrStr,
6963    to: DATA_TYPE,
6964    *types: DATA_TYPE,
6965    **opts: t.Any,
6966) -> Expression | Cast:
6967    """
6968    Cast an expression to a data type unless it is a specified type.
6969
6970    Args:
6971        expression: The expression to cast.
6972        to: The data type to cast to.
6973        **types: The types to exclude from casting.
6974        **opts: Extra keyword arguments for parsing `expression`
6975    """
6976    expr = maybe_parse(expression, **opts)
6977    if expr.is_type(*types):
6978        return expr
6979    return cast(expr, to, **opts)

Cast an expression to a data type unless it is a specified type.

Arguments:
  • expression: The expression to cast.
  • to: The data type to cast to.
  • **types: The types to exclude from casting.
  • **opts: Extra keyword arguments for parsing expression
def true() -> Boolean:
6982def true() -> Boolean:
6983    """
6984    Returns a true Boolean expression.
6985    """
6986    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
6989def false() -> Boolean:
6990    """
6991    Returns a false Boolean expression.
6992    """
6993    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6996def null() -> Null:
6997    """
6998    Returns a Null expression.
6999    """
7000    return Null()

Returns a Null expression.

TRUE = Boolean(this=True)
FALSE = Boolean(this=False)
NULL = Null()