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

Retrieves the argument with key "this".

expression

Retrieves the argument with key "expression".

expressions

Retrieves the argument with key "expressions".

def text(self, key) -> str:
141    def text(self, key) -> str:
142        """
143        Returns a textual representation of the argument corresponding to "key". This can only be used
144        for args that are strings or leaf Expression instances, such as identifiers and literals.
145        """
146        field = self.args.get(key)
147        if isinstance(field, str):
148            return field
149        if isinstance(field, (Identifier, Literal, Var)):
150            return field.this
151        if isinstance(field, (Star, Null)):
152            return field.name
153        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

Checks whether a Literal expression is a string.

is_number: bool

Checks whether a Literal expression is a number.

is_int: bool

Checks whether a Literal expression is an integer.

is_star: bool

Checks whether an expression is a star.

alias: str

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

alias_column_names: List[str]
name: str
alias_or_name: str
output_name: str

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]
meta: Dict[str, Any]
def copy(self):
258    def copy(self):
259        """
260        Returns a deep copy of the expression.
261        """
262        new = deepcopy(self)
263        new.parent = self.parent
264        return new

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
266    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
267        if self.comments is None:
268            self.comments = []
269        if comments:
270            self.comments.extend(comments)
def append(self, arg_key: str, value: Any) -> None:
272    def append(self, arg_key: str, value: t.Any) -> None:
273        """
274        Appends value to arg_key if it's a list or sets it as a new list.
275
276        Args:
277            arg_key (str): name of the list expression arg
278            value (Any): value to append to the list
279        """
280        if not isinstance(self.args.get(arg_key), list):
281            self.args[arg_key] = []
282        self.args[arg_key].append(value)
283        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:
285    def set(self, arg_key: str, value: t.Any) -> None:
286        """
287        Sets arg_key to value.
288
289        Args:
290            arg_key: name of the expression arg.
291            value: value to set the arg to.
292        """
293        if value is None:
294            self.args.pop(arg_key, None)
295            return
296
297        self.args[arg_key] = value
298        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

Returns the depth of this tree.

def iter_expressions(self) -> Iterator[Tuple[str, Expression]]:
319    def iter_expressions(self) -> t.Iterator[t.Tuple[str, Expression]]:
320        """Yields the key and expression for all arguments, exploding list args."""
321        for k, vs in self.args.items():
322            if type(vs) is list:
323                for v in vs:
324                    if hasattr(v, "parent"):
325                        yield k, v
326            else:
327                if hasattr(vs, "parent"):
328                    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]:
330    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
331        """
332        Returns the first node in this tree which matches at least one of
333        the specified types.
334
335        Args:
336            expression_types: the expression type(s) to match.
337            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
338
339        Returns:
340            The node which matches the criteria or None if no such node was found.
341        """
342        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]:
344    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
345        """
346        Returns a generator object which visits all nodes in this tree and only
347        yields those that match at least one of the specified expression types.
348
349        Args:
350            expression_types: the expression type(s) to match.
351            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
352
353        Returns:
354            The generator object.
355        """
356        for expression, *_ in self.walk(bfs=bfs):
357            if isinstance(expression, expression_types):
358                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]:
360    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
361        """
362        Returns a nearest parent matching expression_types.
363
364        Args:
365            expression_types: the expression type(s) to match.
366
367        Returns:
368            The parent node.
369        """
370        ancestor = self.parent
371        while ancestor and not isinstance(ancestor, expression_types):
372            ancestor = ancestor.parent
373        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]

Returns the parent select statement.

same_parent: bool

Returns if the parent is the same class as itself.

def root(self) -> Expression:
387    def root(self) -> Expression:
388        """
389        Returns the root expression of this tree.
390        """
391        expression = self
392        while expression.parent:
393            expression = expression.parent
394        return expression

Returns the root expression of this tree.

def walk(self, bfs=True, prune=None):
396    def walk(self, bfs=True, prune=None):
397        """
398        Returns a generator object which visits all nodes in this tree.
399
400        Args:
401            bfs (bool): if set to True the BFS traversal order will be applied,
402                otherwise the DFS traversal will be used instead.
403            prune ((node, parent, arg_key) -> bool): callable that returns True if
404                the generator should stop traversing this branch of the tree.
405
406        Returns:
407            the generator object.
408        """
409        if bfs:
410            yield from self.bfs(prune=prune)
411        else:
412            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):
414    def dfs(self, parent=None, key=None, prune=None):
415        """
416        Returns a generator object which visits all nodes in this tree in
417        the DFS (Depth-first) order.
418
419        Returns:
420            The generator object.
421        """
422        parent = parent or self.parent
423        yield self, parent, key
424        if prune and prune(self, parent, key):
425            return
426
427        for k, v in self.iter_expressions():
428            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):
430    def bfs(self, prune=None):
431        """
432        Returns a generator object which visits all nodes in this tree in
433        the BFS (Breadth-first) order.
434
435        Returns:
436            The generator object.
437        """
438        queue = deque([(self, self.parent, None)])
439
440        while queue:
441            item, parent, key = queue.popleft()
442
443            yield item, parent, key
444            if prune and prune(item, parent, key):
445                continue
446
447            for k, v in item.iter_expressions():
448                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):
450    def unnest(self):
451        """
452        Returns the first non parenthesis child or self.
453        """
454        expression = self
455        while type(expression) is Paren:
456            expression = expression.this
457        return expression

Returns the first non parenthesis child or self.

def unalias(self):
459    def unalias(self):
460        """
461        Returns the inner expression if this is an Alias.
462        """
463        if isinstance(self, Alias):
464            return self.this
465        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
467    def unnest_operands(self):
468        """
469        Returns unnested operands as a tuple.
470        """
471        return tuple(arg.unnest() for _, arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
473    def flatten(self, unnest=True):
474        """
475        Returns a generator which yields child nodes who's parents are the same class.
476
477        A AND B AND C -> [A, B, C]
478        """
479        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and not type(n) is self.__class__):
480            if not type(node) is self.__class__:
481                yield node.unnest() if unnest else node

Returns a generator which yields child nodes who's parents are the same class.

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

def sql( self, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> str:
489    def sql(self, dialect: DialectType = None, **opts) -> str:
490        """
491        Returns SQL string representation of this tree.
492
493        Args:
494            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
495            opts: other `sqlglot.generator.Generator` options.
496
497        Returns:
498            The SQL string.
499        """
500        from sqlglot.dialects import Dialect
501
502        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):
528    def transform(self, fun, *args, copy=True, **kwargs):
529        """
530        Recursively visits all tree nodes (excluding already transformed ones)
531        and applies the given transformation function to each node.
532
533        Args:
534            fun (function): a function which takes a node as an argument and returns a
535                new transformed node or the same node without modifications. If the function
536                returns None, then the corresponding node will be removed from the syntax tree.
537            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
538                modified in place.
539
540        Returns:
541            The transformed tree.
542        """
543        node = self.copy() if copy else self
544        new_node = fun(node, *args, **kwargs)
545
546        if new_node is None or not isinstance(new_node, Expression):
547            return new_node
548        if new_node is not node:
549            new_node.parent = node.parent
550            return new_node
551
552        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
553        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):
563    def replace(self, expression):
564        """
565        Swap out this expression with a new expression.
566
567        For example::
568
569            >>> tree = Select().select("x").from_("tbl")
570            >>> tree.find(Column).replace(Column(this="y"))
571            (COLUMN this: y)
572            >>> tree.sql()
573            'SELECT y FROM tbl'
574
575        Args:
576            expression: new node
577
578        Returns:
579            The new expression or expressions.
580        """
581        if not self.parent:
582            return expression
583
584        parent = self.parent
585        self.parent = None
586
587        replace_children(parent, lambda child: expression if child is self else child)
588        return expression

Swap out this expression with a new expression.

For example::

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

The new expression or expressions.

def pop(self: ~E) -> ~E:
590    def pop(self: E) -> E:
591        """
592        Remove this expression from its AST.
593
594        Returns:
595            The popped expression.
596        """
597        self.replace(None)
598        return self

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
659    @classmethod
660    def load(cls, obj):
661        """
662        Load a dict (as returned by `Expression.dump`) into an Expression instance.
663        """
664        from sqlglot.serde import load
665
666        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:
668    def and_(
669        self,
670        *expressions: t.Optional[ExpOrStr],
671        dialect: DialectType = None,
672        copy: bool = True,
673        **opts,
674    ) -> Condition:
675        """
676        AND this condition with one or multiple expressions.
677
678        Example:
679            >>> condition("x=1").and_("y=1").sql()
680            'x = 1 AND y = 1'
681
682        Args:
683            *expressions: the SQL code strings to parse.
684                If an `Expression` instance is passed, it will be used as-is.
685            dialect: the dialect used to parse the input expression.
686            copy: whether or not to copy the involved expressions (only applies to Expressions).
687            opts: other options to use to parse the input expressions.
688
689        Returns:
690            The new And condition.
691        """
692        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:
694    def or_(
695        self,
696        *expressions: t.Optional[ExpOrStr],
697        dialect: DialectType = None,
698        copy: bool = True,
699        **opts,
700    ) -> Condition:
701        """
702        OR this condition with one or multiple expressions.
703
704        Example:
705            >>> condition("x=1").or_("y=1").sql()
706            'x = 1 OR y = 1'
707
708        Args:
709            *expressions: the SQL code strings to parse.
710                If an `Expression` instance is passed, it will be used as-is.
711            dialect: the dialect used to parse the input expression.
712            copy: whether or not to copy the involved expressions (only applies to Expressions).
713            opts: other options to use to parse the input expressions.
714
715        Returns:
716            The new Or condition.
717        """
718        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):
720    def not_(self, copy: bool = True):
721        """
722        Wrap this condition with NOT.
723
724        Example:
725            >>> condition("x=1").not_().sql()
726            'NOT x = 1'
727
728        Args:
729            copy: whether or not to copy this object.
730
731        Returns:
732            The new Not instance.
733        """
734        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:
736    def as_(
737        self,
738        alias: str | Identifier,
739        quoted: t.Optional[bool] = None,
740        dialect: DialectType = None,
741        copy: bool = True,
742        **opts,
743    ) -> Alias:
744        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:
769    def isin(
770        self,
771        *expressions: t.Any,
772        query: t.Optional[ExpOrStr] = None,
773        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
774        copy: bool = True,
775        **opts,
776    ) -> In:
777        return In(
778            this=maybe_copy(self, copy),
779            expressions=[convert(e, copy=copy) for e in expressions],
780            query=maybe_parse(query, copy=copy, **opts) if query else None,
781            unnest=Unnest(
782                expressions=[
783                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
784                ]
785            )
786            if unnest
787            else None,
788        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
790    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
791        return Between(
792            this=maybe_copy(self, copy),
793            low=convert(low, copy=copy, **opts),
794            high=convert(high, copy=copy, **opts),
795        )
def is_( self, other: Union[str, Expression]) -> Is:
797    def is_(self, other: ExpOrStr) -> Is:
798        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
800    def like(self, other: ExpOrStr) -> Like:
801        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
803    def ilike(self, other: ExpOrStr) -> ILike:
804        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
806    def eq(self, other: t.Any) -> EQ:
807        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
809    def neq(self, other: t.Any) -> NEQ:
810        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
812    def rlike(self, other: ExpOrStr) -> RegexpLike:
813        return self._binop(RegexpLike, other)
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
896class Condition(Expression):
897    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
904class DerivedTable(Expression):
905    @property
906    def selects(self) -> t.List[Expression]:
907        return self.this.selects if isinstance(self.this, Subqueryable) else []
908
909    @property
910    def named_selects(self) -> t.List[str]:
911        return [select.output_name for select in self.selects]
selects: List[Expression]
named_selects: List[str]
key = 'derivedtable'
class Unionable(Expression):
914class Unionable(Expression):
915    def union(
916        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
917    ) -> Unionable:
918        """
919        Builds a UNION expression.
920
921        Example:
922            >>> import sqlglot
923            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
924            'SELECT * FROM foo UNION SELECT * FROM bla'
925
926        Args:
927            expression: the SQL code string.
928                If an `Expression` instance is passed, it will be used as-is.
929            distinct: set the DISTINCT flag if and only if this is true.
930            dialect: the dialect used to parse the input expression.
931            opts: other options to use to parse the input expressions.
932
933        Returns:
934            The new Union expression.
935        """
936        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
937
938    def intersect(
939        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
940    ) -> Unionable:
941        """
942        Builds an INTERSECT expression.
943
944        Example:
945            >>> import sqlglot
946            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
947            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
948
949        Args:
950            expression: the SQL code string.
951                If an `Expression` instance is passed, it will be used as-is.
952            distinct: set the DISTINCT flag if and only if this is true.
953            dialect: the dialect used to parse the input expression.
954            opts: other options to use to parse the input expressions.
955
956        Returns:
957            The new Intersect expression.
958        """
959        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
960
961    def except_(
962        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
963    ) -> Unionable:
964        """
965        Builds an EXCEPT expression.
966
967        Example:
968            >>> import sqlglot
969            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
970            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
971
972        Args:
973            expression: the SQL code string.
974                If an `Expression` instance is passed, it will be used as-is.
975            distinct: set the DISTINCT flag if and only if this is true.
976            dialect: the dialect used to parse the input expression.
977            opts: other options to use to parse the input expressions.
978
979        Returns:
980            The new Except expression.
981        """
982        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:
915    def union(
916        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
917    ) -> Unionable:
918        """
919        Builds a UNION expression.
920
921        Example:
922            >>> import sqlglot
923            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
924            'SELECT * FROM foo UNION SELECT * FROM bla'
925
926        Args:
927            expression: the SQL code string.
928                If an `Expression` instance is passed, it will be used as-is.
929            distinct: set the DISTINCT flag if and only if this is true.
930            dialect: the dialect used to parse the input expression.
931            opts: other options to use to parse the input expressions.
932
933        Returns:
934            The new Union expression.
935        """
936        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:
938    def intersect(
939        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
940    ) -> Unionable:
941        """
942        Builds an INTERSECT expression.
943
944        Example:
945            >>> import sqlglot
946            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
947            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
948
949        Args:
950            expression: the SQL code string.
951                If an `Expression` instance is passed, it will be used as-is.
952            distinct: set the DISTINCT flag if and only if this is true.
953            dialect: the dialect used to parse the input expression.
954            opts: other options to use to parse the input expressions.
955
956        Returns:
957            The new Intersect expression.
958        """
959        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:
961    def except_(
962        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
963    ) -> Unionable:
964        """
965        Builds an EXCEPT expression.
966
967        Example:
968            >>> import sqlglot
969            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
970            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
971
972        Args:
973            expression: the SQL code string.
974                If an `Expression` instance is passed, it will be used as-is.
975            distinct: set the DISTINCT flag if and only if this is true.
976            dialect: the dialect used to parse the input expression.
977            opts: other options to use to parse the input expressions.
978
979        Returns:
980            The new Except expression.
981        """
982        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):
985class UDTF(DerivedTable, Unionable):
986    @property
987    def selects(self) -> t.List[Expression]:
988        alias = self.args.get("alias")
989        return alias.columns if alias else []
selects: List[Expression]
key = 'udtf'
class Cache(Expression):
992class Cache(Expression):
993    arg_types = {
994        "with": False,
995        "this": True,
996        "lazy": False,
997        "options": False,
998        "expression": False,
999    }
arg_types = {'with': False, 'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1002class Uncache(Expression):
1003    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class DDL(Expression):
1006class DDL(Expression):
1007    @property
1008    def ctes(self):
1009        with_ = self.args.get("with")
1010        if not with_:
1011            return []
1012        return with_.expressions
1013
1014    @property
1015    def named_selects(self) -> t.List[str]:
1016        if isinstance(self.expression, Subqueryable):
1017            return self.expression.named_selects
1018        return []
1019
1020    @property
1021    def selects(self) -> t.List[Expression]:
1022        if isinstance(self.expression, Subqueryable):
1023            return self.expression.selects
1024        return []
ctes
named_selects: List[str]
selects: List[Expression]
key = 'ddl'
class Create(DDL):
1027class Create(DDL):
1028    arg_types = {
1029        "with": False,
1030        "this": True,
1031        "kind": True,
1032        "expression": False,
1033        "exists": False,
1034        "properties": False,
1035        "replace": False,
1036        "unique": False,
1037        "indexes": False,
1038        "no_schema_binding": False,
1039        "begin": False,
1040        "clone": False,
1041    }
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, 'clone': False}
key = 'create'
class Clone(Expression):
1045class Clone(Expression):
1046    arg_types = {
1047        "this": True,
1048        "when": False,
1049        "kind": False,
1050        "shallow": False,
1051        "expression": False,
1052    }
arg_types = {'this': True, 'when': False, 'kind': False, 'shallow': False, 'expression': False}
key = 'clone'
class Describe(Expression):
1055class Describe(Expression):
1056    arg_types = {"this": True, "kind": False, "expressions": False}
arg_types = {'this': True, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1059class Kill(Expression):
1060    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1063class Pragma(Expression):
1064    pass
key = 'pragma'
class Set(Expression):
1067class Set(Expression):
1068    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class SetItem(Expression):
1071class SetItem(Expression):
1072    arg_types = {
1073        "this": False,
1074        "expressions": False,
1075        "kind": False,
1076        "collate": False,  # MySQL SET NAMES statement
1077        "global": False,
1078    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1081class Show(Expression):
1082    arg_types = {
1083        "this": True,
1084        "target": False,
1085        "offset": False,
1086        "limit": False,
1087        "like": False,
1088        "where": False,
1089        "db": False,
1090        "scope": False,
1091        "scope_kind": False,
1092        "full": False,
1093        "mutex": False,
1094        "query": False,
1095        "channel": False,
1096        "global": False,
1097        "log": False,
1098        "position": False,
1099        "types": False,
1100    }
arg_types = {'this': True, 'target': False, 'offset': False, 'limit': 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):
1103class UserDefinedFunction(Expression):
1104    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1107class CharacterSet(Expression):
1108    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1111class With(Expression):
1112    arg_types = {"expressions": True, "recursive": False}
1113
1114    @property
1115    def recursive(self) -> bool:
1116        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
key = 'with'
class WithinGroup(Expression):
1119class WithinGroup(Expression):
1120    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1123class CTE(DerivedTable):
1124    arg_types = {"this": True, "alias": True}
arg_types = {'this': True, 'alias': True}
key = 'cte'
class TableAlias(Expression):
1127class TableAlias(Expression):
1128    arg_types = {"this": False, "columns": False}
1129
1130    @property
1131    def columns(self):
1132        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
key = 'tablealias'
class BitString(Condition):
1135class BitString(Condition):
1136    pass
key = 'bitstring'
class HexString(Condition):
1139class HexString(Condition):
1140    pass
key = 'hexstring'
class ByteString(Condition):
1143class ByteString(Condition):
1144    pass
key = 'bytestring'
class RawString(Condition):
1147class RawString(Condition):
1148    pass
key = 'rawstring'
class Column(Condition):
1151class Column(Condition):
1152    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1153
1154    @property
1155    def table(self) -> str:
1156        return self.text("table")
1157
1158    @property
1159    def db(self) -> str:
1160        return self.text("db")
1161
1162    @property
1163    def catalog(self) -> str:
1164        return self.text("catalog")
1165
1166    @property
1167    def output_name(self) -> str:
1168        return self.name
1169
1170    @property
1171    def parts(self) -> t.List[Identifier]:
1172        """Return the parts of a column in order catalog, db, table, name."""
1173        return [
1174            t.cast(Identifier, self.args[part])
1175            for part in ("catalog", "db", "table", "this")
1176            if self.args.get(part)
1177        ]
1178
1179    def to_dot(self) -> Dot | Identifier:
1180        """Converts the column into a dot expression."""
1181        parts = self.parts
1182        parent = self.parent
1183
1184        while parent:
1185            if isinstance(parent, Dot):
1186                parts.append(parent.expression)
1187            parent = parent.parent
1188
1189        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
db: str
catalog: str
output_name: str

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]

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

def to_dot(self) -> Dot | Identifier:
1179    def to_dot(self) -> Dot | Identifier:
1180        """Converts the column into a dot expression."""
1181        parts = self.parts
1182        parent = self.parent
1183
1184        while parent:
1185            if isinstance(parent, Dot):
1186                parts.append(parent.expression)
1187            parent = parent.parent
1188
1189        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1192class ColumnPosition(Expression):
1193    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1196class ColumnDef(Expression):
1197    arg_types = {
1198        "this": True,
1199        "kind": False,
1200        "constraints": False,
1201        "exists": False,
1202        "position": False,
1203    }
1204
1205    @property
1206    def constraints(self) -> t.List[ColumnConstraint]:
1207        return self.args.get("constraints") or []
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
key = 'columndef'
class AlterColumn(Expression):
1210class AlterColumn(Expression):
1211    arg_types = {
1212        "this": True,
1213        "dtype": False,
1214        "collate": False,
1215        "using": False,
1216        "default": False,
1217        "drop": False,
1218    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False}
key = 'altercolumn'
class RenameTable(Expression):
1221class RenameTable(Expression):
1222    pass
key = 'renametable'
class Comment(Expression):
1225class Comment(Expression):
1226    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):
1229class Comprehension(Expression):
1230    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):
1234class MergeTreeTTLAction(Expression):
1235    arg_types = {
1236        "this": True,
1237        "delete": False,
1238        "recompress": False,
1239        "to_disk": False,
1240        "to_volume": False,
1241    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1245class MergeTreeTTL(Expression):
1246    arg_types = {
1247        "expressions": True,
1248        "where": False,
1249        "group": False,
1250        "aggregates": False,
1251    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1255class IndexConstraintOption(Expression):
1256    arg_types = {
1257        "key_block_size": False,
1258        "using": False,
1259        "parser": False,
1260        "comment": False,
1261        "visible": False,
1262        "engine_attr": False,
1263        "secondary_engine_attr": False,
1264    }
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):
1267class ColumnConstraint(Expression):
1268    arg_types = {"this": False, "kind": True}
1269
1270    @property
1271    def kind(self) -> ColumnConstraintKind:
1272        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1275class ColumnConstraintKind(Expression):
1276    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1279class AutoIncrementColumnConstraint(ColumnConstraintKind):
1280    pass
key = 'autoincrementcolumnconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1283class CaseSpecificColumnConstraint(ColumnConstraintKind):
1284    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1287class CharacterSetColumnConstraint(ColumnConstraintKind):
1288    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1291class CheckColumnConstraint(ColumnConstraintKind):
1292    pass
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1295class ClusteredColumnConstraint(ColumnConstraintKind):
1296    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1299class CollateColumnConstraint(ColumnConstraintKind):
1300    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1303class CommentColumnConstraint(ColumnConstraintKind):
1304    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1307class CompressColumnConstraint(ColumnConstraintKind):
1308    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1311class DateFormatColumnConstraint(ColumnConstraintKind):
1312    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1315class DefaultColumnConstraint(ColumnConstraintKind):
1316    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1319class EncodeColumnConstraint(ColumnConstraintKind):
1320    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1323class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1324    # this: True -> ALWAYS, this: False -> BY DEFAULT
1325    arg_types = {
1326        "this": False,
1327        "expression": False,
1328        "on_null": False,
1329        "start": False,
1330        "increment": False,
1331        "minvalue": False,
1332        "maxvalue": False,
1333        "cycle": False,
1334    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1338class IndexColumnConstraint(ColumnConstraintKind):
1339    arg_types = {
1340        "this": False,
1341        "schema": True,
1342        "kind": False,
1343        "index_type": False,
1344        "options": False,
1345    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1348class InlineLengthColumnConstraint(ColumnConstraintKind):
1349    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1352class NonClusteredColumnConstraint(ColumnConstraintKind):
1353    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1356class NotForReplicationColumnConstraint(ColumnConstraintKind):
1357    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1360class NotNullColumnConstraint(ColumnConstraintKind):
1361    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1365class OnUpdateColumnConstraint(ColumnConstraintKind):
1366    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1369class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1370    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1373class TitleColumnConstraint(ColumnConstraintKind):
1374    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1377class UniqueColumnConstraint(ColumnConstraintKind):
1378    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1381class UppercaseColumnConstraint(ColumnConstraintKind):
1382    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1385class PathColumnConstraint(ColumnConstraintKind):
1386    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1391class ComputedColumnConstraint(ColumnConstraintKind):
1392    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1395class Constraint(Expression):
1396    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(Expression):
1399class Delete(Expression):
1400    arg_types = {
1401        "with": False,
1402        "this": False,
1403        "using": False,
1404        "where": False,
1405        "returning": False,
1406        "limit": False,
1407        "tables": False,  # Multiple-Table Syntax (MySQL)
1408    }
1409
1410    def delete(
1411        self,
1412        table: ExpOrStr,
1413        dialect: DialectType = None,
1414        copy: bool = True,
1415        **opts,
1416    ) -> Delete:
1417        """
1418        Create a DELETE expression or replace the table on an existing DELETE expression.
1419
1420        Example:
1421            >>> delete("tbl").sql()
1422            'DELETE FROM tbl'
1423
1424        Args:
1425            table: the table from which to delete.
1426            dialect: the dialect used to parse the input expression.
1427            copy: if `False`, modify this expression instance in-place.
1428            opts: other options to use to parse the input expressions.
1429
1430        Returns:
1431            Delete: the modified expression.
1432        """
1433        return _apply_builder(
1434            expression=table,
1435            instance=self,
1436            arg="this",
1437            dialect=dialect,
1438            into=Table,
1439            copy=copy,
1440            **opts,
1441        )
1442
1443    def where(
1444        self,
1445        *expressions: t.Optional[ExpOrStr],
1446        append: bool = True,
1447        dialect: DialectType = None,
1448        copy: bool = True,
1449        **opts,
1450    ) -> Delete:
1451        """
1452        Append to or set the WHERE expressions.
1453
1454        Example:
1455            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1456            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1457
1458        Args:
1459            *expressions: the SQL code strings to parse.
1460                If an `Expression` instance is passed, it will be used as-is.
1461                Multiple expressions are combined with an AND operator.
1462            append: if `True`, AND the new expressions to any existing expression.
1463                Otherwise, this resets the expression.
1464            dialect: the dialect used to parse the input expressions.
1465            copy: if `False`, modify this expression instance in-place.
1466            opts: other options to use to parse the input expressions.
1467
1468        Returns:
1469            Delete: the modified expression.
1470        """
1471        return _apply_conjunction_builder(
1472            *expressions,
1473            instance=self,
1474            arg="where",
1475            append=append,
1476            into=Where,
1477            dialect=dialect,
1478            copy=copy,
1479            **opts,
1480        )
1481
1482    def returning(
1483        self,
1484        expression: ExpOrStr,
1485        dialect: DialectType = None,
1486        copy: bool = True,
1487        **opts,
1488    ) -> Delete:
1489        """
1490        Set the RETURNING expression. Not supported by all dialects.
1491
1492        Example:
1493            >>> delete("tbl").returning("*", dialect="postgres").sql()
1494            'DELETE FROM tbl RETURNING *'
1495
1496        Args:
1497            expression: the SQL code strings to parse.
1498                If an `Expression` instance is passed, it will be used as-is.
1499            dialect: the dialect used to parse the input expressions.
1500            copy: if `False`, modify this expression instance in-place.
1501            opts: other options to use to parse the input expressions.
1502
1503        Returns:
1504            Delete: the modified expression.
1505        """
1506        return _apply_builder(
1507            expression=expression,
1508            instance=self,
1509            arg="returning",
1510            prefix="RETURNING",
1511            dialect=dialect,
1512            copy=copy,
1513            into=Returning,
1514            **opts,
1515        )
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:
1410    def delete(
1411        self,
1412        table: ExpOrStr,
1413        dialect: DialectType = None,
1414        copy: bool = True,
1415        **opts,
1416    ) -> Delete:
1417        """
1418        Create a DELETE expression or replace the table on an existing DELETE expression.
1419
1420        Example:
1421            >>> delete("tbl").sql()
1422            'DELETE FROM tbl'
1423
1424        Args:
1425            table: the table from which to delete.
1426            dialect: the dialect used to parse the input expression.
1427            copy: if `False`, modify this expression instance in-place.
1428            opts: other options to use to parse the input expressions.
1429
1430        Returns:
1431            Delete: the modified expression.
1432        """
1433        return _apply_builder(
1434            expression=table,
1435            instance=self,
1436            arg="this",
1437            dialect=dialect,
1438            into=Table,
1439            copy=copy,
1440            **opts,
1441        )

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:
1443    def where(
1444        self,
1445        *expressions: t.Optional[ExpOrStr],
1446        append: bool = True,
1447        dialect: DialectType = None,
1448        copy: bool = True,
1449        **opts,
1450    ) -> Delete:
1451        """
1452        Append to or set the WHERE expressions.
1453
1454        Example:
1455            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1456            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1457
1458        Args:
1459            *expressions: the SQL code strings to parse.
1460                If an `Expression` instance is passed, it will be used as-is.
1461                Multiple expressions are combined with an AND operator.
1462            append: if `True`, AND the new expressions to any existing expression.
1463                Otherwise, this resets the expression.
1464            dialect: the dialect used to parse the input expressions.
1465            copy: if `False`, modify this expression instance in-place.
1466            opts: other options to use to parse the input expressions.
1467
1468        Returns:
1469            Delete: the modified expression.
1470        """
1471        return _apply_conjunction_builder(
1472            *expressions,
1473            instance=self,
1474            arg="where",
1475            append=append,
1476            into=Where,
1477            dialect=dialect,
1478            copy=copy,
1479            **opts,
1480        )

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.

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) -> Delete:
1482    def returning(
1483        self,
1484        expression: ExpOrStr,
1485        dialect: DialectType = None,
1486        copy: bool = True,
1487        **opts,
1488    ) -> Delete:
1489        """
1490        Set the RETURNING expression. Not supported by all dialects.
1491
1492        Example:
1493            >>> delete("tbl").returning("*", dialect="postgres").sql()
1494            'DELETE FROM tbl RETURNING *'
1495
1496        Args:
1497            expression: the SQL code strings to parse.
1498                If an `Expression` instance is passed, it will be used as-is.
1499            dialect: the dialect used to parse the input expressions.
1500            copy: if `False`, modify this expression instance in-place.
1501            opts: other options to use to parse the input expressions.
1502
1503        Returns:
1504            Delete: the modified expression.
1505        """
1506        return _apply_builder(
1507            expression=expression,
1508            instance=self,
1509            arg="returning",
1510            prefix="RETURNING",
1511            dialect=dialect,
1512            copy=copy,
1513            into=Returning,
1514            **opts,
1515        )

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 = 'delete'
class Drop(Expression):
1518class Drop(Expression):
1519    arg_types = {
1520        "this": False,
1521        "kind": False,
1522        "exists": False,
1523        "temporary": False,
1524        "materialized": False,
1525        "cascade": False,
1526        "constraints": False,
1527        "purge": False,
1528    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1531class Filter(Expression):
1532    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1535class Check(Expression):
1536    pass
key = 'check'
class Connect(Expression):
1540class Connect(Expression):
1541    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1544class Prior(Expression):
1545    pass
key = 'prior'
class Directory(Expression):
1548class Directory(Expression):
1549    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1550    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1553class ForeignKey(Expression):
1554    arg_types = {
1555        "expressions": True,
1556        "reference": False,
1557        "delete": False,
1558        "update": False,
1559    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1562class ColumnPrefix(Expression):
1563    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1566class PrimaryKey(Expression):
1567    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1572class Into(Expression):
1573    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1576class From(Expression):
1577    @property
1578    def name(self) -> str:
1579        return self.this.name
1580
1581    @property
1582    def alias_or_name(self) -> str:
1583        return self.this.alias_or_name
name: str
alias_or_name: str
key = 'from'
class Having(Expression):
1586class Having(Expression):
1587    pass
key = 'having'
class Hint(Expression):
1590class Hint(Expression):
1591    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1594class JoinHint(Expression):
1595    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1598class Identifier(Expression):
1599    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1600
1601    @property
1602    def quoted(self) -> bool:
1603        return bool(self.args.get("quoted"))
1604
1605    @property
1606    def hashable_args(self) -> t.Any:
1607        return (self.this, self.quoted)
1608
1609    @property
1610    def output_name(self) -> str:
1611        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
hashable_args: Any
output_name: str

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 Index(Expression):
1614class Index(Expression):
1615    arg_types = {
1616        "this": False,
1617        "table": False,
1618        "using": False,
1619        "where": False,
1620        "columns": False,
1621        "unique": False,
1622        "primary": False,
1623        "amp": False,  # teradata
1624        "partition_by": False,  # teradata
1625        "where": False,  # postgres partial indexes
1626    }
arg_types = {'this': False, 'table': False, 'using': False, 'where': False, 'columns': False, 'unique': False, 'primary': False, 'amp': False, 'partition_by': False}
key = 'index'
class Insert(DDL):
1629class Insert(DDL):
1630    arg_types = {
1631        "with": False,
1632        "this": True,
1633        "expression": False,
1634        "conflict": False,
1635        "returning": False,
1636        "overwrite": False,
1637        "exists": False,
1638        "partition": False,
1639        "alternative": False,
1640        "where": False,
1641        "ignore": False,
1642        "by_name": False,
1643    }
1644
1645    def with_(
1646        self,
1647        alias: ExpOrStr,
1648        as_: ExpOrStr,
1649        recursive: t.Optional[bool] = None,
1650        append: bool = True,
1651        dialect: DialectType = None,
1652        copy: bool = True,
1653        **opts,
1654    ) -> Insert:
1655        """
1656        Append to or set the common table expressions.
1657
1658        Example:
1659            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1660            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1661
1662        Args:
1663            alias: the SQL code string to parse as the table name.
1664                If an `Expression` instance is passed, this is used as-is.
1665            as_: the SQL code string to parse as the table expression.
1666                If an `Expression` instance is passed, it will be used as-is.
1667            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1668            append: if `True`, add to any existing expressions.
1669                Otherwise, this resets the expressions.
1670            dialect: the dialect used to parse the input expression.
1671            copy: if `False`, modify this expression instance in-place.
1672            opts: other options to use to parse the input expressions.
1673
1674        Returns:
1675            The modified expression.
1676        """
1677        return _apply_cte_builder(
1678            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1679        )
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:
1645    def with_(
1646        self,
1647        alias: ExpOrStr,
1648        as_: ExpOrStr,
1649        recursive: t.Optional[bool] = None,
1650        append: bool = True,
1651        dialect: DialectType = None,
1652        copy: bool = True,
1653        **opts,
1654    ) -> Insert:
1655        """
1656        Append to or set the common table expressions.
1657
1658        Example:
1659            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1660            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1661
1662        Args:
1663            alias: the SQL code string to parse as the table name.
1664                If an `Expression` instance is passed, this is used as-is.
1665            as_: the SQL code string to parse as the table expression.
1666                If an `Expression` instance is passed, it will be used as-is.
1667            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1668            append: if `True`, add to any existing expressions.
1669                Otherwise, this resets the expressions.
1670            dialect: the dialect used to parse the input expression.
1671            copy: if `False`, modify this expression instance in-place.
1672            opts: other options to use to parse the input expressions.
1673
1674        Returns:
1675            The modified expression.
1676        """
1677        return _apply_cte_builder(
1678            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1679        )

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):
1682class OnConflict(Expression):
1683    arg_types = {
1684        "duplicate": False,
1685        "expressions": False,
1686        "nothing": False,
1687        "key": False,
1688        "constraint": False,
1689    }
arg_types = {'duplicate': False, 'expressions': False, 'nothing': False, 'key': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1692class Returning(Expression):
1693    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1697class Introducer(Expression):
1698    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1702class National(Expression):
1703    pass
key = 'national'
class LoadData(Expression):
1706class LoadData(Expression):
1707    arg_types = {
1708        "this": True,
1709        "local": False,
1710        "overwrite": False,
1711        "inpath": True,
1712        "partition": False,
1713        "input_format": False,
1714        "serde": False,
1715    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1718class Partition(Expression):
1719    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class Fetch(Expression):
1722class Fetch(Expression):
1723    arg_types = {
1724        "direction": False,
1725        "count": False,
1726        "percent": False,
1727        "with_ties": False,
1728    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1731class Group(Expression):
1732    arg_types = {
1733        "expressions": False,
1734        "grouping_sets": False,
1735        "cube": False,
1736        "rollup": False,
1737        "totals": False,
1738        "all": False,
1739    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1742class Lambda(Expression):
1743    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1746class Limit(Expression):
1747    arg_types = {"this": False, "expression": True, "offset": False}
arg_types = {'this': False, 'expression': True, 'offset': False}
key = 'limit'
class Literal(Condition):
1750class Literal(Condition):
1751    arg_types = {"this": True, "is_string": True}
1752
1753    @property
1754    def hashable_args(self) -> t.Any:
1755        return (self.this, self.args.get("is_string"))
1756
1757    @classmethod
1758    def number(cls, number) -> Literal:
1759        return cls(this=str(number), is_string=False)
1760
1761    @classmethod
1762    def string(cls, string) -> Literal:
1763        return cls(this=str(string), is_string=True)
1764
1765    @property
1766    def output_name(self) -> str:
1767        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
@classmethod
def number(cls, number) -> Literal:
1757    @classmethod
1758    def number(cls, number) -> Literal:
1759        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
1761    @classmethod
1762    def string(cls, string) -> Literal:
1763        return cls(this=str(string), is_string=True)
output_name: str

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):
1770class Join(Expression):
1771    arg_types = {
1772        "this": True,
1773        "on": False,
1774        "side": False,
1775        "kind": False,
1776        "using": False,
1777        "method": False,
1778        "global": False,
1779        "hint": False,
1780    }
1781
1782    @property
1783    def method(self) -> str:
1784        return self.text("method").upper()
1785
1786    @property
1787    def kind(self) -> str:
1788        return self.text("kind").upper()
1789
1790    @property
1791    def side(self) -> str:
1792        return self.text("side").upper()
1793
1794    @property
1795    def hint(self) -> str:
1796        return self.text("hint").upper()
1797
1798    @property
1799    def alias_or_name(self) -> str:
1800        return self.this.alias_or_name
1801
1802    def on(
1803        self,
1804        *expressions: t.Optional[ExpOrStr],
1805        append: bool = True,
1806        dialect: DialectType = None,
1807        copy: bool = True,
1808        **opts,
1809    ) -> Join:
1810        """
1811        Append to or set the ON expressions.
1812
1813        Example:
1814            >>> import sqlglot
1815            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1816            'JOIN x ON y = 1'
1817
1818        Args:
1819            *expressions: the SQL code strings to parse.
1820                If an `Expression` instance is passed, it will be used as-is.
1821                Multiple expressions are combined with an AND operator.
1822            append: if `True`, AND the new expressions to any existing expression.
1823                Otherwise, this resets the expression.
1824            dialect: the dialect used to parse the input expressions.
1825            copy: if `False`, modify this expression instance in-place.
1826            opts: other options to use to parse the input expressions.
1827
1828        Returns:
1829            The modified Join expression.
1830        """
1831        join = _apply_conjunction_builder(
1832            *expressions,
1833            instance=self,
1834            arg="on",
1835            append=append,
1836            dialect=dialect,
1837            copy=copy,
1838            **opts,
1839        )
1840
1841        if join.kind == "CROSS":
1842            join.set("kind", None)
1843
1844        return join
1845
1846    def using(
1847        self,
1848        *expressions: t.Optional[ExpOrStr],
1849        append: bool = True,
1850        dialect: DialectType = None,
1851        copy: bool = True,
1852        **opts,
1853    ) -> Join:
1854        """
1855        Append to or set the USING expressions.
1856
1857        Example:
1858            >>> import sqlglot
1859            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1860            'JOIN x USING (foo, bla)'
1861
1862        Args:
1863            *expressions: the SQL code strings to parse.
1864                If an `Expression` instance is passed, it will be used as-is.
1865            append: if `True`, concatenate the new expressions to the existing "using" list.
1866                Otherwise, this resets the expression.
1867            dialect: the dialect used to parse the input expressions.
1868            copy: if `False`, modify this expression instance in-place.
1869            opts: other options to use to parse the input expressions.
1870
1871        Returns:
1872            The modified Join expression.
1873        """
1874        join = _apply_list_builder(
1875            *expressions,
1876            instance=self,
1877            arg="using",
1878            append=append,
1879            dialect=dialect,
1880            copy=copy,
1881            **opts,
1882        )
1883
1884        if join.kind == "CROSS":
1885            join.set("kind", None)
1886
1887        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
kind: str
side: str
hint: str
alias_or_name: str
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:
1802    def on(
1803        self,
1804        *expressions: t.Optional[ExpOrStr],
1805        append: bool = True,
1806        dialect: DialectType = None,
1807        copy: bool = True,
1808        **opts,
1809    ) -> Join:
1810        """
1811        Append to or set the ON expressions.
1812
1813        Example:
1814            >>> import sqlglot
1815            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1816            'JOIN x ON y = 1'
1817
1818        Args:
1819            *expressions: the SQL code strings to parse.
1820                If an `Expression` instance is passed, it will be used as-is.
1821                Multiple expressions are combined with an AND operator.
1822            append: if `True`, AND the new expressions to any existing expression.
1823                Otherwise, this resets the expression.
1824            dialect: the dialect used to parse the input expressions.
1825            copy: if `False`, modify this expression instance in-place.
1826            opts: other options to use to parse the input expressions.
1827
1828        Returns:
1829            The modified Join expression.
1830        """
1831        join = _apply_conjunction_builder(
1832            *expressions,
1833            instance=self,
1834            arg="on",
1835            append=append,
1836            dialect=dialect,
1837            copy=copy,
1838            **opts,
1839        )
1840
1841        if join.kind == "CROSS":
1842            join.set("kind", None)
1843
1844        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:
1846    def using(
1847        self,
1848        *expressions: t.Optional[ExpOrStr],
1849        append: bool = True,
1850        dialect: DialectType = None,
1851        copy: bool = True,
1852        **opts,
1853    ) -> Join:
1854        """
1855        Append to or set the USING expressions.
1856
1857        Example:
1858            >>> import sqlglot
1859            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1860            'JOIN x USING (foo, bla)'
1861
1862        Args:
1863            *expressions: the SQL code strings to parse.
1864                If an `Expression` instance is passed, it will be used as-is.
1865            append: if `True`, concatenate the new expressions to the existing "using" list.
1866                Otherwise, this resets the expression.
1867            dialect: the dialect used to parse the input expressions.
1868            copy: if `False`, modify this expression instance in-place.
1869            opts: other options to use to parse the input expressions.
1870
1871        Returns:
1872            The modified Join expression.
1873        """
1874        join = _apply_list_builder(
1875            *expressions,
1876            instance=self,
1877            arg="using",
1878            append=append,
1879            dialect=dialect,
1880            copy=copy,
1881            **opts,
1882        )
1883
1884        if join.kind == "CROSS":
1885            join.set("kind", None)
1886
1887        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):
1890class Lateral(UDTF):
1891    arg_types = {"this": True, "view": False, "outer": False, "alias": False}
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False}
key = 'lateral'
class MatchRecognize(Expression):
1894class MatchRecognize(Expression):
1895    arg_types = {
1896        "partition_by": False,
1897        "order": False,
1898        "measures": False,
1899        "rows": False,
1900        "after": False,
1901        "pattern": False,
1902        "define": False,
1903        "alias": False,
1904    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
1909class Final(Expression):
1910    pass
key = 'final'
class Offset(Expression):
1913class Offset(Expression):
1914    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'offset'
class Order(Expression):
1917class Order(Expression):
1918    arg_types = {"this": False, "expressions": True}
arg_types = {'this': False, 'expressions': True}
key = 'order'
class Cluster(Order):
1923class Cluster(Order):
1924    pass
key = 'cluster'
class Distribute(Order):
1927class Distribute(Order):
1928    pass
key = 'distribute'
class Sort(Order):
1931class Sort(Order):
1932    pass
key = 'sort'
class Ordered(Expression):
1935class Ordered(Expression):
1936    arg_types = {"this": True, "desc": False, "nulls_first": True}
arg_types = {'this': True, 'desc': False, 'nulls_first': True}
key = 'ordered'
class Property(Expression):
1939class Property(Expression):
1940    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
1943class AlgorithmProperty(Property):
1944    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
1947class AutoIncrementProperty(Property):
1948    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class BlockCompressionProperty(Property):
1951class BlockCompressionProperty(Property):
1952    arg_types = {"autotemp": False, "always": False, "default": True, "manual": True, "never": True}
arg_types = {'autotemp': False, 'always': False, 'default': True, 'manual': True, 'never': True}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
1955class CharacterSetProperty(Property):
1956    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
1959class ChecksumProperty(Property):
1960    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
1963class CollateProperty(Property):
1964    arg_types = {"this": True}
arg_types = {'this': True}
key = 'collateproperty'
class CopyGrantsProperty(Property):
1967class CopyGrantsProperty(Property):
1968    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
1971class DataBlocksizeProperty(Property):
1972    arg_types = {
1973        "size": False,
1974        "units": False,
1975        "minimum": False,
1976        "maximum": False,
1977        "default": False,
1978    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
1981class DefinerProperty(Property):
1982    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
1985class DistKeyProperty(Property):
1986    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
1989class DistStyleProperty(Property):
1990    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
1993class EngineProperty(Property):
1994    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
1997class HeapProperty(Property):
1998    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2001class ToTableProperty(Property):
2002    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2005class ExecuteAsProperty(Property):
2006    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2009class ExternalProperty(Property):
2010    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2013class FallbackProperty(Property):
2014    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2017class FileFormatProperty(Property):
2018    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2021class FreespaceProperty(Property):
2022    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InputOutputFormat(Expression):
2025class InputOutputFormat(Expression):
2026    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class IsolatedLoadingProperty(Property):
2029class IsolatedLoadingProperty(Property):
2030    arg_types = {
2031        "no": True,
2032        "concurrent": True,
2033        "for_all": True,
2034        "for_insert": True,
2035        "for_none": True,
2036    }
arg_types = {'no': True, 'concurrent': True, 'for_all': True, 'for_insert': True, 'for_none': True}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2039class JournalProperty(Property):
2040    arg_types = {
2041        "no": False,
2042        "dual": False,
2043        "before": False,
2044        "local": False,
2045        "after": False,
2046    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2049class LanguageProperty(Property):
2050    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2054class ClusteredByProperty(Property):
2055    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2058class DictProperty(Property):
2059    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2062class DictSubProperty(Property):
2063    pass
key = 'dictsubproperty'
class DictRange(Property):
2066class DictRange(Property):
2067    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2072class OnCluster(Property):
2073    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2076class LikeProperty(Property):
2077    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2080class LocationProperty(Property):
2081    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockingProperty(Property):
2084class LockingProperty(Property):
2085    arg_types = {
2086        "this": False,
2087        "kind": True,
2088        "for_or_in": True,
2089        "lock_type": True,
2090        "override": False,
2091    }
arg_types = {'this': False, 'kind': True, 'for_or_in': True, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2094class LogProperty(Property):
2095    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2098class MaterializedProperty(Property):
2099    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2102class MergeBlockRatioProperty(Property):
2103    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):
2106class NoPrimaryIndexProperty(Property):
2107    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2110class OnProperty(Property):
2111    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2114class OnCommitProperty(Property):
2115    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2118class PartitionedByProperty(Property):
2119    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class ReturnsProperty(Property):
2122class ReturnsProperty(Property):
2123    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2126class RowFormatProperty(Property):
2127    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2130class RowFormatDelimitedProperty(Property):
2131    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2132    arg_types = {
2133        "fields": False,
2134        "escaped": False,
2135        "collection_items": False,
2136        "map_keys": False,
2137        "lines": False,
2138        "null": False,
2139        "serde": False,
2140    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2143class RowFormatSerdeProperty(Property):
2144    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2148class QueryTransform(Expression):
2149    arg_types = {
2150        "expressions": True,
2151        "command_script": True,
2152        "schema": False,
2153        "row_format_before": False,
2154        "record_writer": False,
2155        "row_format_after": False,
2156        "record_reader": False,
2157    }
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 SchemaCommentProperty(Property):
2160class SchemaCommentProperty(Property):
2161    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2164class SerdeProperties(Property):
2165    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2168class SetProperty(Property):
2169    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SettingsProperty(Property):
2172class SettingsProperty(Property):
2173    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2176class SortKeyProperty(Property):
2177    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlSecurityProperty(Property):
2180class SqlSecurityProperty(Property):
2181    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2184class StabilityProperty(Property):
2185    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2188class TemporaryProperty(Property):
2189    arg_types = {}
arg_types = {}
key = 'temporaryproperty'
class TransientProperty(Property):
2192class TransientProperty(Property):
2193    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2196class VolatileProperty(Property):
2197    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2200class WithDataProperty(Property):
2201    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2204class WithJournalTableProperty(Property):
2205    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class Properties(Expression):
2208class Properties(Expression):
2209    arg_types = {"expressions": True}
2210
2211    NAME_TO_PROPERTY = {
2212        "ALGORITHM": AlgorithmProperty,
2213        "AUTO_INCREMENT": AutoIncrementProperty,
2214        "CHARACTER SET": CharacterSetProperty,
2215        "CLUSTERED_BY": ClusteredByProperty,
2216        "COLLATE": CollateProperty,
2217        "COMMENT": SchemaCommentProperty,
2218        "DEFINER": DefinerProperty,
2219        "DISTKEY": DistKeyProperty,
2220        "DISTSTYLE": DistStyleProperty,
2221        "ENGINE": EngineProperty,
2222        "EXECUTE AS": ExecuteAsProperty,
2223        "FORMAT": FileFormatProperty,
2224        "LANGUAGE": LanguageProperty,
2225        "LOCATION": LocationProperty,
2226        "PARTITIONED_BY": PartitionedByProperty,
2227        "RETURNS": ReturnsProperty,
2228        "ROW_FORMAT": RowFormatProperty,
2229        "SORTKEY": SortKeyProperty,
2230    }
2231
2232    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2233
2234    # CREATE property locations
2235    # Form: schema specified
2236    #   create [POST_CREATE]
2237    #     table a [POST_NAME]
2238    #     (b int) [POST_SCHEMA]
2239    #     with ([POST_WITH])
2240    #     index (b) [POST_INDEX]
2241    #
2242    # Form: alias selection
2243    #   create [POST_CREATE]
2244    #     table a [POST_NAME]
2245    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2246    #     index (c) [POST_INDEX]
2247    class Location(AutoName):
2248        POST_CREATE = auto()
2249        POST_NAME = auto()
2250        POST_SCHEMA = auto()
2251        POST_WITH = auto()
2252        POST_ALIAS = auto()
2253        POST_EXPRESSION = auto()
2254        POST_INDEX = auto()
2255        UNSUPPORTED = auto()
2256
2257    @classmethod
2258    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2259        expressions = []
2260        for key, value in properties_dict.items():
2261            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2262            if property_cls:
2263                expressions.append(property_cls(this=convert(value)))
2264            else:
2265                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2266
2267        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:
2257    @classmethod
2258    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2259        expressions = []
2260        for key, value in properties_dict.items():
2261            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2262            if property_cls:
2263                expressions.append(property_cls(this=convert(value)))
2264            else:
2265                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2266
2267        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2247    class Location(AutoName):
2248        POST_CREATE = auto()
2249        POST_NAME = auto()
2250        POST_SCHEMA = auto()
2251        POST_WITH = auto()
2252        POST_ALIAS = auto()
2253        POST_EXPRESSION = auto()
2254        POST_INDEX = auto()
2255        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):
2270class Qualify(Expression):
2271    pass
key = 'qualify'
class Return(Expression):
2275class Return(Expression):
2276    pass
key = 'return'
class Reference(Expression):
2279class Reference(Expression):
2280    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2283class Tuple(Expression):
2284    arg_types = {"expressions": False}
2285
2286    def isin(
2287        self,
2288        *expressions: t.Any,
2289        query: t.Optional[ExpOrStr] = None,
2290        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2291        copy: bool = True,
2292        **opts,
2293    ) -> In:
2294        return In(
2295            this=maybe_copy(self, copy),
2296            expressions=[convert(e, copy=copy) for e in expressions],
2297            query=maybe_parse(query, copy=copy, **opts) if query else None,
2298            unnest=Unnest(
2299                expressions=[
2300                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2301                ]
2302            )
2303            if unnest
2304            else None,
2305        )
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:
2286    def isin(
2287        self,
2288        *expressions: t.Any,
2289        query: t.Optional[ExpOrStr] = None,
2290        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2291        copy: bool = True,
2292        **opts,
2293    ) -> In:
2294        return In(
2295            this=maybe_copy(self, copy),
2296            expressions=[convert(e, copy=copy) for e in expressions],
2297            query=maybe_parse(query, copy=copy, **opts) if query else None,
2298            unnest=Unnest(
2299                expressions=[
2300                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2301                ]
2302            )
2303            if unnest
2304            else None,
2305        )
key = 'tuple'
class Subqueryable(Unionable):
2308class Subqueryable(Unionable):
2309    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2310        """
2311        Convert this expression to an aliased expression that can be used as a Subquery.
2312
2313        Example:
2314            >>> subquery = Select().select("x").from_("tbl").subquery()
2315            >>> Select().select("x").from_(subquery).sql()
2316            'SELECT x FROM (SELECT x FROM tbl)'
2317
2318        Args:
2319            alias (str | Identifier): an optional alias for the subquery
2320            copy (bool): if `False`, modify this expression instance in-place.
2321
2322        Returns:
2323            Alias: the subquery
2324        """
2325        instance = maybe_copy(self, copy)
2326        if not isinstance(alias, Expression):
2327            alias = TableAlias(this=to_identifier(alias)) if alias else None
2328
2329        return Subquery(this=instance, alias=alias)
2330
2331    def limit(
2332        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2333    ) -> Select:
2334        raise NotImplementedError
2335
2336    @property
2337    def ctes(self):
2338        with_ = self.args.get("with")
2339        if not with_:
2340            return []
2341        return with_.expressions
2342
2343    @property
2344    def selects(self) -> t.List[Expression]:
2345        raise NotImplementedError("Subqueryable objects must implement `selects`")
2346
2347    @property
2348    def named_selects(self) -> t.List[str]:
2349        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2350
2351    def select(
2352        self,
2353        *expressions: t.Optional[ExpOrStr],
2354        append: bool = True,
2355        dialect: DialectType = None,
2356        copy: bool = True,
2357        **opts,
2358    ) -> Subqueryable:
2359        raise NotImplementedError("Subqueryable objects must implement `select`")
2360
2361    def with_(
2362        self,
2363        alias: ExpOrStr,
2364        as_: ExpOrStr,
2365        recursive: t.Optional[bool] = None,
2366        append: bool = True,
2367        dialect: DialectType = None,
2368        copy: bool = True,
2369        **opts,
2370    ) -> Subqueryable:
2371        """
2372        Append to or set the common table expressions.
2373
2374        Example:
2375            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2376            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2377
2378        Args:
2379            alias: the SQL code string to parse as the table name.
2380                If an `Expression` instance is passed, this is used as-is.
2381            as_: the SQL code string to parse as the table expression.
2382                If an `Expression` instance is passed, it will be used as-is.
2383            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2384            append: if `True`, add to any existing expressions.
2385                Otherwise, this resets the expressions.
2386            dialect: the dialect used to parse the input expression.
2387            copy: if `False`, modify this expression instance in-place.
2388            opts: other options to use to parse the input expressions.
2389
2390        Returns:
2391            The modified expression.
2392        """
2393        return _apply_cte_builder(
2394            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2395        )
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
2309    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2310        """
2311        Convert this expression to an aliased expression that can be used as a Subquery.
2312
2313        Example:
2314            >>> subquery = Select().select("x").from_("tbl").subquery()
2315            >>> Select().select("x").from_(subquery).sql()
2316            'SELECT x FROM (SELECT x FROM tbl)'
2317
2318        Args:
2319            alias (str | Identifier): an optional alias for the subquery
2320            copy (bool): if `False`, modify this expression instance in-place.
2321
2322        Returns:
2323            Alias: the subquery
2324        """
2325        instance = maybe_copy(self, copy)
2326        if not isinstance(alias, Expression):
2327            alias = TableAlias(this=to_identifier(alias)) if alias else None
2328
2329        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:
2331    def limit(
2332        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2333    ) -> Select:
2334        raise NotImplementedError
ctes
selects: List[Expression]
named_selects: List[str]
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:
2351    def select(
2352        self,
2353        *expressions: t.Optional[ExpOrStr],
2354        append: bool = True,
2355        dialect: DialectType = None,
2356        copy: bool = True,
2357        **opts,
2358    ) -> Subqueryable:
2359        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:
2361    def with_(
2362        self,
2363        alias: ExpOrStr,
2364        as_: ExpOrStr,
2365        recursive: t.Optional[bool] = None,
2366        append: bool = True,
2367        dialect: DialectType = None,
2368        copy: bool = True,
2369        **opts,
2370    ) -> Subqueryable:
2371        """
2372        Append to or set the common table expressions.
2373
2374        Example:
2375            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2376            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2377
2378        Args:
2379            alias: the SQL code string to parse as the table name.
2380                If an `Expression` instance is passed, this is used as-is.
2381            as_: the SQL code string to parse as the table expression.
2382                If an `Expression` instance is passed, it will be used as-is.
2383            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2384            append: if `True`, add to any existing expressions.
2385                Otherwise, this resets the expressions.
2386            dialect: the dialect used to parse the input expression.
2387            copy: if `False`, modify this expression instance in-place.
2388            opts: other options to use to parse the input expressions.
2389
2390        Returns:
2391            The modified expression.
2392        """
2393        return _apply_cte_builder(
2394            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2395        )

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):
2423class WithTableHint(Expression):
2424    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2428class IndexTableHint(Expression):
2429    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class Table(Expression):
2432class Table(Expression):
2433    arg_types = {
2434        "this": True,
2435        "alias": False,
2436        "db": False,
2437        "catalog": False,
2438        "laterals": False,
2439        "joins": False,
2440        "pivots": False,
2441        "hints": False,
2442        "system_time": False,
2443        "version": False,
2444    }
2445
2446    @property
2447    def name(self) -> str:
2448        if isinstance(self.this, Func):
2449            return ""
2450        return self.this.name
2451
2452    @property
2453    def db(self) -> str:
2454        return self.text("db")
2455
2456    @property
2457    def catalog(self) -> str:
2458        return self.text("catalog")
2459
2460    @property
2461    def selects(self) -> t.List[Expression]:
2462        return []
2463
2464    @property
2465    def named_selects(self) -> t.List[str]:
2466        return []
2467
2468    @property
2469    def parts(self) -> t.List[Identifier]:
2470        """Return the parts of a table in order catalog, db, table."""
2471        parts: t.List[Identifier] = []
2472
2473        for arg in ("catalog", "db", "this"):
2474            part = self.args.get(arg)
2475
2476            if isinstance(part, Identifier):
2477                parts.append(part)
2478            elif isinstance(part, Dot):
2479                parts.extend(part.flatten())
2480
2481        return parts
arg_types = {'this': True, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False}
name: str
db: str
catalog: str
selects: List[Expression]
named_selects: List[str]
parts: List[Identifier]

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

key = 'table'
class Union(Subqueryable):
2484class Union(Subqueryable):
2485    arg_types = {
2486        "with": False,
2487        "this": True,
2488        "expression": True,
2489        "distinct": False,
2490        "by_name": False,
2491        **QUERY_MODIFIERS,
2492    }
2493
2494    def limit(
2495        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2496    ) -> Select:
2497        """
2498        Set the LIMIT expression.
2499
2500        Example:
2501            >>> select("1").union(select("1")).limit(1).sql()
2502            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2503
2504        Args:
2505            expression: the SQL code string to parse.
2506                This can also be an integer.
2507                If a `Limit` instance is passed, this is used as-is.
2508                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2509            dialect: the dialect used to parse the input expression.
2510            copy: if `False`, modify this expression instance in-place.
2511            opts: other options to use to parse the input expressions.
2512
2513        Returns:
2514            The limited subqueryable.
2515        """
2516        return (
2517            select("*")
2518            .from_(self.subquery(alias="_l_0", copy=copy))
2519            .limit(expression, dialect=dialect, copy=False, **opts)
2520        )
2521
2522    def select(
2523        self,
2524        *expressions: t.Optional[ExpOrStr],
2525        append: bool = True,
2526        dialect: DialectType = None,
2527        copy: bool = True,
2528        **opts,
2529    ) -> Union:
2530        """Append to or set the SELECT of the union recursively.
2531
2532        Example:
2533            >>> from sqlglot import parse_one
2534            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2535            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2536
2537        Args:
2538            *expressions: the SQL code strings to parse.
2539                If an `Expression` instance is passed, it will be used as-is.
2540            append: if `True`, add to any existing expressions.
2541                Otherwise, this resets the expressions.
2542            dialect: the dialect used to parse the input expressions.
2543            copy: if `False`, modify this expression instance in-place.
2544            opts: other options to use to parse the input expressions.
2545
2546        Returns:
2547            Union: the modified expression.
2548        """
2549        this = self.copy() if copy else self
2550        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2551        this.expression.unnest().select(
2552            *expressions, append=append, dialect=dialect, copy=False, **opts
2553        )
2554        return this
2555
2556    @property
2557    def named_selects(self) -> t.List[str]:
2558        return self.this.unnest().named_selects
2559
2560    @property
2561    def is_star(self) -> bool:
2562        return self.this.is_star or self.expression.is_star
2563
2564    @property
2565    def selects(self) -> t.List[Expression]:
2566        return self.this.unnest().selects
2567
2568    @property
2569    def left(self):
2570        return self.this
2571
2572    @property
2573    def right(self):
2574        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:
2494    def limit(
2495        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2496    ) -> Select:
2497        """
2498        Set the LIMIT expression.
2499
2500        Example:
2501            >>> select("1").union(select("1")).limit(1).sql()
2502            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2503
2504        Args:
2505            expression: the SQL code string to parse.
2506                This can also be an integer.
2507                If a `Limit` instance is passed, this is used as-is.
2508                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2509            dialect: the dialect used to parse the input expression.
2510            copy: if `False`, modify this expression instance in-place.
2511            opts: other options to use to parse the input expressions.
2512
2513        Returns:
2514            The limited subqueryable.
2515        """
2516        return (
2517            select("*")
2518            .from_(self.subquery(alias="_l_0", copy=copy))
2519            .limit(expression, dialect=dialect, copy=False, **opts)
2520        )

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:
2522    def select(
2523        self,
2524        *expressions: t.Optional[ExpOrStr],
2525        append: bool = True,
2526        dialect: DialectType = None,
2527        copy: bool = True,
2528        **opts,
2529    ) -> Union:
2530        """Append to or set the SELECT of the union recursively.
2531
2532        Example:
2533            >>> from sqlglot import parse_one
2534            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2535            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2536
2537        Args:
2538            *expressions: the SQL code strings to parse.
2539                If an `Expression` instance is passed, it will be used as-is.
2540            append: if `True`, add to any existing expressions.
2541                Otherwise, this resets the expressions.
2542            dialect: the dialect used to parse the input expressions.
2543            copy: if `False`, modify this expression instance in-place.
2544            opts: other options to use to parse the input expressions.
2545
2546        Returns:
2547            Union: the modified expression.
2548        """
2549        this = self.copy() if copy else self
2550        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2551        this.expression.unnest().select(
2552            *expressions, append=append, dialect=dialect, copy=False, **opts
2553        )
2554        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]
is_star: bool

Checks whether an expression is a star.

selects: List[Expression]
left
right
key = 'union'
class Except(Union):
2577class Except(Union):
2578    pass
key = 'except'
class Intersect(Union):
2581class Intersect(Union):
2582    pass
key = 'intersect'
class Unnest(UDTF):
2585class Unnest(UDTF):
2586    arg_types = {
2587        "expressions": True,
2588        "alias": False,
2589        "offset": False,
2590    }
arg_types = {'expressions': True, 'alias': False, 'offset': False}
key = 'unnest'
class Update(Expression):
2593class Update(Expression):
2594    arg_types = {
2595        "with": False,
2596        "this": False,
2597        "expressions": True,
2598        "from": False,
2599        "where": False,
2600        "returning": False,
2601        "order": False,
2602        "limit": False,
2603    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
2606class Values(UDTF):
2607    arg_types = {
2608        "expressions": True,
2609        "ordinality": False,
2610        "alias": False,
2611    }
arg_types = {'expressions': True, 'ordinality': False, 'alias': False}
key = 'values'
class Var(Expression):
2614class Var(Expression):
2615    pass
key = 'var'
class Version(Expression):
2618class Version(Expression):
2619    """
2620    Time travel, iceberg, bigquery etc
2621    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
2622    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
2623    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
2624    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
2625    this is either TIMESTAMP or VERSION
2626    kind is ("AS OF", "BETWEEN")
2627    """
2628
2629    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
2632class Schema(Expression):
2633    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
2638class Lock(Expression):
2639    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Subqueryable):
2642class Select(Subqueryable):
2643    arg_types = {
2644        "with": False,
2645        "kind": False,
2646        "expressions": False,
2647        "hint": False,
2648        "distinct": False,
2649        "into": False,
2650        "from": False,
2651        **QUERY_MODIFIERS,
2652    }
2653
2654    def from_(
2655        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2656    ) -> Select:
2657        """
2658        Set the FROM expression.
2659
2660        Example:
2661            >>> Select().from_("tbl").select("x").sql()
2662            'SELECT x FROM tbl'
2663
2664        Args:
2665            expression : the SQL code strings to parse.
2666                If a `From` instance is passed, this is used as-is.
2667                If another `Expression` instance is passed, it will be wrapped in a `From`.
2668            dialect: the dialect used to parse the input expression.
2669            copy: if `False`, modify this expression instance in-place.
2670            opts: other options to use to parse the input expressions.
2671
2672        Returns:
2673            The modified Select expression.
2674        """
2675        return _apply_builder(
2676            expression=expression,
2677            instance=self,
2678            arg="from",
2679            into=From,
2680            prefix="FROM",
2681            dialect=dialect,
2682            copy=copy,
2683            **opts,
2684        )
2685
2686    def group_by(
2687        self,
2688        *expressions: t.Optional[ExpOrStr],
2689        append: bool = True,
2690        dialect: DialectType = None,
2691        copy: bool = True,
2692        **opts,
2693    ) -> Select:
2694        """
2695        Set the GROUP BY expression.
2696
2697        Example:
2698            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2699            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2700
2701        Args:
2702            *expressions: the SQL code strings to parse.
2703                If a `Group` instance is passed, this is used as-is.
2704                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2705                If nothing is passed in then a group by is not applied to the expression
2706            append: if `True`, add to any existing expressions.
2707                Otherwise, this flattens all the `Group` expression into a single expression.
2708            dialect: the dialect used to parse the input expression.
2709            copy: if `False`, modify this expression instance in-place.
2710            opts: other options to use to parse the input expressions.
2711
2712        Returns:
2713            The modified Select expression.
2714        """
2715        if not expressions:
2716            return self if not copy else self.copy()
2717
2718        return _apply_child_list_builder(
2719            *expressions,
2720            instance=self,
2721            arg="group",
2722            append=append,
2723            copy=copy,
2724            prefix="GROUP BY",
2725            into=Group,
2726            dialect=dialect,
2727            **opts,
2728        )
2729
2730    def order_by(
2731        self,
2732        *expressions: t.Optional[ExpOrStr],
2733        append: bool = True,
2734        dialect: DialectType = None,
2735        copy: bool = True,
2736        **opts,
2737    ) -> Select:
2738        """
2739        Set the ORDER BY expression.
2740
2741        Example:
2742            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2743            'SELECT x FROM tbl ORDER BY x DESC'
2744
2745        Args:
2746            *expressions: the SQL code strings to parse.
2747                If a `Group` instance is passed, this is used as-is.
2748                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2749            append: if `True`, add to any existing expressions.
2750                Otherwise, this flattens all the `Order` expression into a single expression.
2751            dialect: the dialect used to parse the input expression.
2752            copy: if `False`, modify this expression instance in-place.
2753            opts: other options to use to parse the input expressions.
2754
2755        Returns:
2756            The modified Select expression.
2757        """
2758        return _apply_child_list_builder(
2759            *expressions,
2760            instance=self,
2761            arg="order",
2762            append=append,
2763            copy=copy,
2764            prefix="ORDER BY",
2765            into=Order,
2766            dialect=dialect,
2767            **opts,
2768        )
2769
2770    def sort_by(
2771        self,
2772        *expressions: t.Optional[ExpOrStr],
2773        append: bool = True,
2774        dialect: DialectType = None,
2775        copy: bool = True,
2776        **opts,
2777    ) -> Select:
2778        """
2779        Set the SORT BY expression.
2780
2781        Example:
2782            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2783            'SELECT x FROM tbl SORT BY x DESC'
2784
2785        Args:
2786            *expressions: the SQL code strings to parse.
2787                If a `Group` instance is passed, this is used as-is.
2788                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2789            append: if `True`, add to any existing expressions.
2790                Otherwise, this flattens all the `Order` expression into a single expression.
2791            dialect: the dialect used to parse the input expression.
2792            copy: if `False`, modify this expression instance in-place.
2793            opts: other options to use to parse the input expressions.
2794
2795        Returns:
2796            The modified Select expression.
2797        """
2798        return _apply_child_list_builder(
2799            *expressions,
2800            instance=self,
2801            arg="sort",
2802            append=append,
2803            copy=copy,
2804            prefix="SORT BY",
2805            into=Sort,
2806            dialect=dialect,
2807            **opts,
2808        )
2809
2810    def cluster_by(
2811        self,
2812        *expressions: t.Optional[ExpOrStr],
2813        append: bool = True,
2814        dialect: DialectType = None,
2815        copy: bool = True,
2816        **opts,
2817    ) -> Select:
2818        """
2819        Set the CLUSTER BY expression.
2820
2821        Example:
2822            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2823            'SELECT x FROM tbl CLUSTER BY x DESC'
2824
2825        Args:
2826            *expressions: the SQL code strings to parse.
2827                If a `Group` instance is passed, this is used as-is.
2828                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2829            append: if `True`, add to any existing expressions.
2830                Otherwise, this flattens all the `Order` expression into a single expression.
2831            dialect: the dialect used to parse the input expression.
2832            copy: if `False`, modify this expression instance in-place.
2833            opts: other options to use to parse the input expressions.
2834
2835        Returns:
2836            The modified Select expression.
2837        """
2838        return _apply_child_list_builder(
2839            *expressions,
2840            instance=self,
2841            arg="cluster",
2842            append=append,
2843            copy=copy,
2844            prefix="CLUSTER BY",
2845            into=Cluster,
2846            dialect=dialect,
2847            **opts,
2848        )
2849
2850    def limit(
2851        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2852    ) -> Select:
2853        """
2854        Set the LIMIT expression.
2855
2856        Example:
2857            >>> Select().from_("tbl").select("x").limit(10).sql()
2858            'SELECT x FROM tbl LIMIT 10'
2859
2860        Args:
2861            expression: the SQL code string to parse.
2862                This can also be an integer.
2863                If a `Limit` instance is passed, this is used as-is.
2864                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2865            dialect: the dialect used to parse the input expression.
2866            copy: if `False`, modify this expression instance in-place.
2867            opts: other options to use to parse the input expressions.
2868
2869        Returns:
2870            Select: the modified expression.
2871        """
2872        return _apply_builder(
2873            expression=expression,
2874            instance=self,
2875            arg="limit",
2876            into=Limit,
2877            prefix="LIMIT",
2878            dialect=dialect,
2879            copy=copy,
2880            into_arg="expression",
2881            **opts,
2882        )
2883
2884    def offset(
2885        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2886    ) -> Select:
2887        """
2888        Set the OFFSET expression.
2889
2890        Example:
2891            >>> Select().from_("tbl").select("x").offset(10).sql()
2892            'SELECT x FROM tbl OFFSET 10'
2893
2894        Args:
2895            expression: the SQL code string to parse.
2896                This can also be an integer.
2897                If a `Offset` instance is passed, this is used as-is.
2898                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
2899            dialect: the dialect used to parse the input expression.
2900            copy: if `False`, modify this expression instance in-place.
2901            opts: other options to use to parse the input expressions.
2902
2903        Returns:
2904            The modified Select expression.
2905        """
2906        return _apply_builder(
2907            expression=expression,
2908            instance=self,
2909            arg="offset",
2910            into=Offset,
2911            prefix="OFFSET",
2912            dialect=dialect,
2913            copy=copy,
2914            **opts,
2915        )
2916
2917    def select(
2918        self,
2919        *expressions: t.Optional[ExpOrStr],
2920        append: bool = True,
2921        dialect: DialectType = None,
2922        copy: bool = True,
2923        **opts,
2924    ) -> Select:
2925        """
2926        Append to or set the SELECT expressions.
2927
2928        Example:
2929            >>> Select().select("x", "y").sql()
2930            'SELECT x, y'
2931
2932        Args:
2933            *expressions: the SQL code strings to parse.
2934                If an `Expression` instance is passed, it will be used as-is.
2935            append: if `True`, add to any existing expressions.
2936                Otherwise, this resets the expressions.
2937            dialect: the dialect used to parse the input expressions.
2938            copy: if `False`, modify this expression instance in-place.
2939            opts: other options to use to parse the input expressions.
2940
2941        Returns:
2942            The modified Select expression.
2943        """
2944        return _apply_list_builder(
2945            *expressions,
2946            instance=self,
2947            arg="expressions",
2948            append=append,
2949            dialect=dialect,
2950            copy=copy,
2951            **opts,
2952        )
2953
2954    def lateral(
2955        self,
2956        *expressions: t.Optional[ExpOrStr],
2957        append: bool = True,
2958        dialect: DialectType = None,
2959        copy: bool = True,
2960        **opts,
2961    ) -> Select:
2962        """
2963        Append to or set the LATERAL expressions.
2964
2965        Example:
2966            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
2967            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
2968
2969        Args:
2970            *expressions: the SQL code strings to parse.
2971                If an `Expression` instance is passed, it will be used as-is.
2972            append: if `True`, add to any existing expressions.
2973                Otherwise, this resets the expressions.
2974            dialect: the dialect used to parse the input expressions.
2975            copy: if `False`, modify this expression instance in-place.
2976            opts: other options to use to parse the input expressions.
2977
2978        Returns:
2979            The modified Select expression.
2980        """
2981        return _apply_list_builder(
2982            *expressions,
2983            instance=self,
2984            arg="laterals",
2985            append=append,
2986            into=Lateral,
2987            prefix="LATERAL VIEW",
2988            dialect=dialect,
2989            copy=copy,
2990            **opts,
2991        )
2992
2993    def join(
2994        self,
2995        expression: ExpOrStr,
2996        on: t.Optional[ExpOrStr] = None,
2997        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
2998        append: bool = True,
2999        join_type: t.Optional[str] = None,
3000        join_alias: t.Optional[Identifier | str] = None,
3001        dialect: DialectType = None,
3002        copy: bool = True,
3003        **opts,
3004    ) -> Select:
3005        """
3006        Append to or set the JOIN expressions.
3007
3008        Example:
3009            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3010            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3011
3012            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3013            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3014
3015            Use `join_type` to change the type of join:
3016
3017            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3018            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3019
3020        Args:
3021            expression: the SQL code string to parse.
3022                If an `Expression` instance is passed, it will be used as-is.
3023            on: optionally specify the join "on" criteria as a SQL string.
3024                If an `Expression` instance is passed, it will be used as-is.
3025            using: optionally specify the join "using" criteria as a SQL string.
3026                If an `Expression` instance is passed, it will be used as-is.
3027            append: if `True`, add to any existing expressions.
3028                Otherwise, this resets the expressions.
3029            join_type: if set, alter the parsed join type.
3030            join_alias: an optional alias for the joined source.
3031            dialect: the dialect used to parse the input expressions.
3032            copy: if `False`, modify this expression instance in-place.
3033            opts: other options to use to parse the input expressions.
3034
3035        Returns:
3036            Select: the modified expression.
3037        """
3038        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3039
3040        try:
3041            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3042        except ParseError:
3043            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3044
3045        join = expression if isinstance(expression, Join) else Join(this=expression)
3046
3047        if isinstance(join.this, Select):
3048            join.this.replace(join.this.subquery())
3049
3050        if join_type:
3051            method: t.Optional[Token]
3052            side: t.Optional[Token]
3053            kind: t.Optional[Token]
3054
3055            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3056
3057            if method:
3058                join.set("method", method.text)
3059            if side:
3060                join.set("side", side.text)
3061            if kind:
3062                join.set("kind", kind.text)
3063
3064        if on:
3065            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3066            join.set("on", on)
3067
3068        if using:
3069            join = _apply_list_builder(
3070                *ensure_list(using),
3071                instance=join,
3072                arg="using",
3073                append=append,
3074                copy=copy,
3075                into=Identifier,
3076                **opts,
3077            )
3078
3079        if join_alias:
3080            join.set("this", alias_(join.this, join_alias, table=True))
3081
3082        return _apply_list_builder(
3083            join,
3084            instance=self,
3085            arg="joins",
3086            append=append,
3087            copy=copy,
3088            **opts,
3089        )
3090
3091    def where(
3092        self,
3093        *expressions: t.Optional[ExpOrStr],
3094        append: bool = True,
3095        dialect: DialectType = None,
3096        copy: bool = True,
3097        **opts,
3098    ) -> Select:
3099        """
3100        Append to or set the WHERE expressions.
3101
3102        Example:
3103            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3104            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3105
3106        Args:
3107            *expressions: the SQL code strings to parse.
3108                If an `Expression` instance is passed, it will be used as-is.
3109                Multiple expressions are combined with an AND operator.
3110            append: if `True`, AND the new expressions to any existing expression.
3111                Otherwise, this resets the expression.
3112            dialect: the dialect used to parse the input expressions.
3113            copy: if `False`, modify this expression instance in-place.
3114            opts: other options to use to parse the input expressions.
3115
3116        Returns:
3117            Select: the modified expression.
3118        """
3119        return _apply_conjunction_builder(
3120            *expressions,
3121            instance=self,
3122            arg="where",
3123            append=append,
3124            into=Where,
3125            dialect=dialect,
3126            copy=copy,
3127            **opts,
3128        )
3129
3130    def having(
3131        self,
3132        *expressions: t.Optional[ExpOrStr],
3133        append: bool = True,
3134        dialect: DialectType = None,
3135        copy: bool = True,
3136        **opts,
3137    ) -> Select:
3138        """
3139        Append to or set the HAVING expressions.
3140
3141        Example:
3142            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3143            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3144
3145        Args:
3146            *expressions: the SQL code strings to parse.
3147                If an `Expression` instance is passed, it will be used as-is.
3148                Multiple expressions are combined with an AND operator.
3149            append: if `True`, AND the new expressions to any existing expression.
3150                Otherwise, this resets the expression.
3151            dialect: the dialect used to parse the input expressions.
3152            copy: if `False`, modify this expression instance in-place.
3153            opts: other options to use to parse the input expressions.
3154
3155        Returns:
3156            The modified Select expression.
3157        """
3158        return _apply_conjunction_builder(
3159            *expressions,
3160            instance=self,
3161            arg="having",
3162            append=append,
3163            into=Having,
3164            dialect=dialect,
3165            copy=copy,
3166            **opts,
3167        )
3168
3169    def window(
3170        self,
3171        *expressions: t.Optional[ExpOrStr],
3172        append: bool = True,
3173        dialect: DialectType = None,
3174        copy: bool = True,
3175        **opts,
3176    ) -> Select:
3177        return _apply_list_builder(
3178            *expressions,
3179            instance=self,
3180            arg="windows",
3181            append=append,
3182            into=Window,
3183            dialect=dialect,
3184            copy=copy,
3185            **opts,
3186        )
3187
3188    def qualify(
3189        self,
3190        *expressions: t.Optional[ExpOrStr],
3191        append: bool = True,
3192        dialect: DialectType = None,
3193        copy: bool = True,
3194        **opts,
3195    ) -> Select:
3196        return _apply_conjunction_builder(
3197            *expressions,
3198            instance=self,
3199            arg="qualify",
3200            append=append,
3201            into=Qualify,
3202            dialect=dialect,
3203            copy=copy,
3204            **opts,
3205        )
3206
3207    def distinct(
3208        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3209    ) -> Select:
3210        """
3211        Set the OFFSET expression.
3212
3213        Example:
3214            >>> Select().from_("tbl").select("x").distinct().sql()
3215            'SELECT DISTINCT x FROM tbl'
3216
3217        Args:
3218            ons: the expressions to distinct on
3219            distinct: whether the Select should be distinct
3220            copy: if `False`, modify this expression instance in-place.
3221
3222        Returns:
3223            Select: the modified expression.
3224        """
3225        instance = maybe_copy(self, copy)
3226        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3227        instance.set("distinct", Distinct(on=on) if distinct else None)
3228        return instance
3229
3230    def ctas(
3231        self,
3232        table: ExpOrStr,
3233        properties: t.Optional[t.Dict] = None,
3234        dialect: DialectType = None,
3235        copy: bool = True,
3236        **opts,
3237    ) -> Create:
3238        """
3239        Convert this expression to a CREATE TABLE AS statement.
3240
3241        Example:
3242            >>> Select().select("*").from_("tbl").ctas("x").sql()
3243            'CREATE TABLE x AS SELECT * FROM tbl'
3244
3245        Args:
3246            table: the SQL code string to parse as the table name.
3247                If another `Expression` instance is passed, it will be used as-is.
3248            properties: an optional mapping of table properties
3249            dialect: the dialect used to parse the input table.
3250            copy: if `False`, modify this expression instance in-place.
3251            opts: other options to use to parse the input table.
3252
3253        Returns:
3254            The new Create expression.
3255        """
3256        instance = maybe_copy(self, copy)
3257        table_expression = maybe_parse(
3258            table,
3259            into=Table,
3260            dialect=dialect,
3261            **opts,
3262        )
3263        properties_expression = None
3264        if properties:
3265            properties_expression = Properties.from_dict(properties)
3266
3267        return Create(
3268            this=table_expression,
3269            kind="table",
3270            expression=instance,
3271            properties=properties_expression,
3272        )
3273
3274    def lock(self, update: bool = True, copy: bool = True) -> Select:
3275        """
3276        Set the locking read mode for this expression.
3277
3278        Examples:
3279            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3280            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3281
3282            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3283            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3284
3285        Args:
3286            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3287            copy: if `False`, modify this expression instance in-place.
3288
3289        Returns:
3290            The modified expression.
3291        """
3292        inst = maybe_copy(self, copy)
3293        inst.set("locks", [Lock(update=update)])
3294
3295        return inst
3296
3297    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3298        """
3299        Set hints for this expression.
3300
3301        Examples:
3302            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3303            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3304
3305        Args:
3306            hints: The SQL code strings to parse as the hints.
3307                If an `Expression` instance is passed, it will be used as-is.
3308            dialect: The dialect used to parse the hints.
3309            copy: If `False`, modify this expression instance in-place.
3310
3311        Returns:
3312            The modified expression.
3313        """
3314        inst = maybe_copy(self, copy)
3315        inst.set(
3316            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3317        )
3318
3319        return inst
3320
3321    @property
3322    def named_selects(self) -> t.List[str]:
3323        return [e.output_name for e in self.expressions if e.alias_or_name]
3324
3325    @property
3326    def is_star(self) -> bool:
3327        return any(expression.is_star for expression in self.expressions)
3328
3329    @property
3330    def selects(self) -> t.List[Expression]:
3331        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:
2654    def from_(
2655        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2656    ) -> Select:
2657        """
2658        Set the FROM expression.
2659
2660        Example:
2661            >>> Select().from_("tbl").select("x").sql()
2662            'SELECT x FROM tbl'
2663
2664        Args:
2665            expression : the SQL code strings to parse.
2666                If a `From` instance is passed, this is used as-is.
2667                If another `Expression` instance is passed, it will be wrapped in a `From`.
2668            dialect: the dialect used to parse the input expression.
2669            copy: if `False`, modify this expression instance in-place.
2670            opts: other options to use to parse the input expressions.
2671
2672        Returns:
2673            The modified Select expression.
2674        """
2675        return _apply_builder(
2676            expression=expression,
2677            instance=self,
2678            arg="from",
2679            into=From,
2680            prefix="FROM",
2681            dialect=dialect,
2682            copy=copy,
2683            **opts,
2684        )

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:
2686    def group_by(
2687        self,
2688        *expressions: t.Optional[ExpOrStr],
2689        append: bool = True,
2690        dialect: DialectType = None,
2691        copy: bool = True,
2692        **opts,
2693    ) -> Select:
2694        """
2695        Set the GROUP BY expression.
2696
2697        Example:
2698            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2699            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2700
2701        Args:
2702            *expressions: the SQL code strings to parse.
2703                If a `Group` instance is passed, this is used as-is.
2704                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2705                If nothing is passed in then a group by is not applied to the expression
2706            append: if `True`, add to any existing expressions.
2707                Otherwise, this flattens all the `Group` expression into a single expression.
2708            dialect: the dialect used to parse the input expression.
2709            copy: if `False`, modify this expression instance in-place.
2710            opts: other options to use to parse the input expressions.
2711
2712        Returns:
2713            The modified Select expression.
2714        """
2715        if not expressions:
2716            return self if not copy else self.copy()
2717
2718        return _apply_child_list_builder(
2719            *expressions,
2720            instance=self,
2721            arg="group",
2722            append=append,
2723            copy=copy,
2724            prefix="GROUP BY",
2725            into=Group,
2726            dialect=dialect,
2727            **opts,
2728        )

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:
2730    def order_by(
2731        self,
2732        *expressions: t.Optional[ExpOrStr],
2733        append: bool = True,
2734        dialect: DialectType = None,
2735        copy: bool = True,
2736        **opts,
2737    ) -> Select:
2738        """
2739        Set the ORDER BY expression.
2740
2741        Example:
2742            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2743            'SELECT x FROM tbl ORDER BY x DESC'
2744
2745        Args:
2746            *expressions: the SQL code strings to parse.
2747                If a `Group` instance is passed, this is used as-is.
2748                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2749            append: if `True`, add to any existing expressions.
2750                Otherwise, this flattens all the `Order` expression into a single expression.
2751            dialect: the dialect used to parse the input expression.
2752            copy: if `False`, modify this expression instance in-place.
2753            opts: other options to use to parse the input expressions.
2754
2755        Returns:
2756            The modified Select expression.
2757        """
2758        return _apply_child_list_builder(
2759            *expressions,
2760            instance=self,
2761            arg="order",
2762            append=append,
2763            copy=copy,
2764            prefix="ORDER BY",
2765            into=Order,
2766            dialect=dialect,
2767            **opts,
2768        )

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:
2770    def sort_by(
2771        self,
2772        *expressions: t.Optional[ExpOrStr],
2773        append: bool = True,
2774        dialect: DialectType = None,
2775        copy: bool = True,
2776        **opts,
2777    ) -> Select:
2778        """
2779        Set the SORT BY expression.
2780
2781        Example:
2782            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2783            'SELECT x FROM tbl SORT BY x DESC'
2784
2785        Args:
2786            *expressions: the SQL code strings to parse.
2787                If a `Group` instance is passed, this is used as-is.
2788                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2789            append: if `True`, add to any existing expressions.
2790                Otherwise, this flattens all the `Order` expression into a single expression.
2791            dialect: the dialect used to parse the input expression.
2792            copy: if `False`, modify this expression instance in-place.
2793            opts: other options to use to parse the input expressions.
2794
2795        Returns:
2796            The modified Select expression.
2797        """
2798        return _apply_child_list_builder(
2799            *expressions,
2800            instance=self,
2801            arg="sort",
2802            append=append,
2803            copy=copy,
2804            prefix="SORT BY",
2805            into=Sort,
2806            dialect=dialect,
2807            **opts,
2808        )

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:
2810    def cluster_by(
2811        self,
2812        *expressions: t.Optional[ExpOrStr],
2813        append: bool = True,
2814        dialect: DialectType = None,
2815        copy: bool = True,
2816        **opts,
2817    ) -> Select:
2818        """
2819        Set the CLUSTER BY expression.
2820
2821        Example:
2822            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2823            'SELECT x FROM tbl CLUSTER BY x DESC'
2824
2825        Args:
2826            *expressions: the SQL code strings to parse.
2827                If a `Group` instance is passed, this is used as-is.
2828                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2829            append: if `True`, add to any existing expressions.
2830                Otherwise, this flattens all the `Order` expression into a single expression.
2831            dialect: the dialect used to parse the input expression.
2832            copy: if `False`, modify this expression instance in-place.
2833            opts: other options to use to parse the input expressions.
2834
2835        Returns:
2836            The modified Select expression.
2837        """
2838        return _apply_child_list_builder(
2839            *expressions,
2840            instance=self,
2841            arg="cluster",
2842            append=append,
2843            copy=copy,
2844            prefix="CLUSTER BY",
2845            into=Cluster,
2846            dialect=dialect,
2847            **opts,
2848        )

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:
2850    def limit(
2851        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2852    ) -> Select:
2853        """
2854        Set the LIMIT expression.
2855
2856        Example:
2857            >>> Select().from_("tbl").select("x").limit(10).sql()
2858            'SELECT x FROM tbl LIMIT 10'
2859
2860        Args:
2861            expression: the SQL code string to parse.
2862                This can also be an integer.
2863                If a `Limit` instance is passed, this is used as-is.
2864                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2865            dialect: the dialect used to parse the input expression.
2866            copy: if `False`, modify this expression instance in-place.
2867            opts: other options to use to parse the input expressions.
2868
2869        Returns:
2870            Select: the modified expression.
2871        """
2872        return _apply_builder(
2873            expression=expression,
2874            instance=self,
2875            arg="limit",
2876            into=Limit,
2877            prefix="LIMIT",
2878            dialect=dialect,
2879            copy=copy,
2880            into_arg="expression",
2881            **opts,
2882        )

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:
2884    def offset(
2885        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2886    ) -> Select:
2887        """
2888        Set the OFFSET expression.
2889
2890        Example:
2891            >>> Select().from_("tbl").select("x").offset(10).sql()
2892            'SELECT x FROM tbl OFFSET 10'
2893
2894        Args:
2895            expression: the SQL code string to parse.
2896                This can also be an integer.
2897                If a `Offset` instance is passed, this is used as-is.
2898                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
2899            dialect: the dialect used to parse the input expression.
2900            copy: if `False`, modify this expression instance in-place.
2901            opts: other options to use to parse the input expressions.
2902
2903        Returns:
2904            The modified Select expression.
2905        """
2906        return _apply_builder(
2907            expression=expression,
2908            instance=self,
2909            arg="offset",
2910            into=Offset,
2911            prefix="OFFSET",
2912            dialect=dialect,
2913            copy=copy,
2914            **opts,
2915        )

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:
2917    def select(
2918        self,
2919        *expressions: t.Optional[ExpOrStr],
2920        append: bool = True,
2921        dialect: DialectType = None,
2922        copy: bool = True,
2923        **opts,
2924    ) -> Select:
2925        """
2926        Append to or set the SELECT expressions.
2927
2928        Example:
2929            >>> Select().select("x", "y").sql()
2930            'SELECT x, y'
2931
2932        Args:
2933            *expressions: the SQL code strings to parse.
2934                If an `Expression` instance is passed, it will be used as-is.
2935            append: if `True`, add to any existing expressions.
2936                Otherwise, this resets the expressions.
2937            dialect: the dialect used to parse the input expressions.
2938            copy: if `False`, modify this expression instance in-place.
2939            opts: other options to use to parse the input expressions.
2940
2941        Returns:
2942            The modified Select expression.
2943        """
2944        return _apply_list_builder(
2945            *expressions,
2946            instance=self,
2947            arg="expressions",
2948            append=append,
2949            dialect=dialect,
2950            copy=copy,
2951            **opts,
2952        )

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:
2954    def lateral(
2955        self,
2956        *expressions: t.Optional[ExpOrStr],
2957        append: bool = True,
2958        dialect: DialectType = None,
2959        copy: bool = True,
2960        **opts,
2961    ) -> Select:
2962        """
2963        Append to or set the LATERAL expressions.
2964
2965        Example:
2966            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
2967            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
2968
2969        Args:
2970            *expressions: the SQL code strings to parse.
2971                If an `Expression` instance is passed, it will be used as-is.
2972            append: if `True`, add to any existing expressions.
2973                Otherwise, this resets the expressions.
2974            dialect: the dialect used to parse the input expressions.
2975            copy: if `False`, modify this expression instance in-place.
2976            opts: other options to use to parse the input expressions.
2977
2978        Returns:
2979            The modified Select expression.
2980        """
2981        return _apply_list_builder(
2982            *expressions,
2983            instance=self,
2984            arg="laterals",
2985            append=append,
2986            into=Lateral,
2987            prefix="LATERAL VIEW",
2988            dialect=dialect,
2989            copy=copy,
2990            **opts,
2991        )

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:
2993    def join(
2994        self,
2995        expression: ExpOrStr,
2996        on: t.Optional[ExpOrStr] = None,
2997        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
2998        append: bool = True,
2999        join_type: t.Optional[str] = None,
3000        join_alias: t.Optional[Identifier | str] = None,
3001        dialect: DialectType = None,
3002        copy: bool = True,
3003        **opts,
3004    ) -> Select:
3005        """
3006        Append to or set the JOIN expressions.
3007
3008        Example:
3009            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3010            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3011
3012            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3013            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3014
3015            Use `join_type` to change the type of join:
3016
3017            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3018            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3019
3020        Args:
3021            expression: the SQL code string to parse.
3022                If an `Expression` instance is passed, it will be used as-is.
3023            on: optionally specify the join "on" criteria as a SQL string.
3024                If an `Expression` instance is passed, it will be used as-is.
3025            using: optionally specify the join "using" criteria as a SQL string.
3026                If an `Expression` instance is passed, it will be used as-is.
3027            append: if `True`, add to any existing expressions.
3028                Otherwise, this resets the expressions.
3029            join_type: if set, alter the parsed join type.
3030            join_alias: an optional alias for the joined source.
3031            dialect: the dialect used to parse the input expressions.
3032            copy: if `False`, modify this expression instance in-place.
3033            opts: other options to use to parse the input expressions.
3034
3035        Returns:
3036            Select: the modified expression.
3037        """
3038        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3039
3040        try:
3041            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3042        except ParseError:
3043            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3044
3045        join = expression if isinstance(expression, Join) else Join(this=expression)
3046
3047        if isinstance(join.this, Select):
3048            join.this.replace(join.this.subquery())
3049
3050        if join_type:
3051            method: t.Optional[Token]
3052            side: t.Optional[Token]
3053            kind: t.Optional[Token]
3054
3055            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3056
3057            if method:
3058                join.set("method", method.text)
3059            if side:
3060                join.set("side", side.text)
3061            if kind:
3062                join.set("kind", kind.text)
3063
3064        if on:
3065            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3066            join.set("on", on)
3067
3068        if using:
3069            join = _apply_list_builder(
3070                *ensure_list(using),
3071                instance=join,
3072                arg="using",
3073                append=append,
3074                copy=copy,
3075                into=Identifier,
3076                **opts,
3077            )
3078
3079        if join_alias:
3080            join.set("this", alias_(join.this, join_alias, table=True))
3081
3082        return _apply_list_builder(
3083            join,
3084            instance=self,
3085            arg="joins",
3086            append=append,
3087            copy=copy,
3088            **opts,
3089        )

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:
3091    def where(
3092        self,
3093        *expressions: t.Optional[ExpOrStr],
3094        append: bool = True,
3095        dialect: DialectType = None,
3096        copy: bool = True,
3097        **opts,
3098    ) -> Select:
3099        """
3100        Append to or set the WHERE expressions.
3101
3102        Example:
3103            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3104            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3105
3106        Args:
3107            *expressions: the SQL code strings to parse.
3108                If an `Expression` instance is passed, it will be used as-is.
3109                Multiple expressions are combined with an AND operator.
3110            append: if `True`, AND the new expressions to any existing expression.
3111                Otherwise, this resets the expression.
3112            dialect: the dialect used to parse the input expressions.
3113            copy: if `False`, modify this expression instance in-place.
3114            opts: other options to use to parse the input expressions.
3115
3116        Returns:
3117            Select: the modified expression.
3118        """
3119        return _apply_conjunction_builder(
3120            *expressions,
3121            instance=self,
3122            arg="where",
3123            append=append,
3124            into=Where,
3125            dialect=dialect,
3126            copy=copy,
3127            **opts,
3128        )

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:
3130    def having(
3131        self,
3132        *expressions: t.Optional[ExpOrStr],
3133        append: bool = True,
3134        dialect: DialectType = None,
3135        copy: bool = True,
3136        **opts,
3137    ) -> Select:
3138        """
3139        Append to or set the HAVING expressions.
3140
3141        Example:
3142            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3143            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3144
3145        Args:
3146            *expressions: the SQL code strings to parse.
3147                If an `Expression` instance is passed, it will be used as-is.
3148                Multiple expressions are combined with an AND operator.
3149            append: if `True`, AND the new expressions to any existing expression.
3150                Otherwise, this resets the expression.
3151            dialect: the dialect used to parse the input expressions.
3152            copy: if `False`, modify this expression instance in-place.
3153            opts: other options to use to parse the input expressions.
3154
3155        Returns:
3156            The modified Select expression.
3157        """
3158        return _apply_conjunction_builder(
3159            *expressions,
3160            instance=self,
3161            arg="having",
3162            append=append,
3163            into=Having,
3164            dialect=dialect,
3165            copy=copy,
3166            **opts,
3167        )

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:
3169    def window(
3170        self,
3171        *expressions: t.Optional[ExpOrStr],
3172        append: bool = True,
3173        dialect: DialectType = None,
3174        copy: bool = True,
3175        **opts,
3176    ) -> Select:
3177        return _apply_list_builder(
3178            *expressions,
3179            instance=self,
3180            arg="windows",
3181            append=append,
3182            into=Window,
3183            dialect=dialect,
3184            copy=copy,
3185            **opts,
3186        )
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:
3188    def qualify(
3189        self,
3190        *expressions: t.Optional[ExpOrStr],
3191        append: bool = True,
3192        dialect: DialectType = None,
3193        copy: bool = True,
3194        **opts,
3195    ) -> Select:
3196        return _apply_conjunction_builder(
3197            *expressions,
3198            instance=self,
3199            arg="qualify",
3200            append=append,
3201            into=Qualify,
3202            dialect=dialect,
3203            copy=copy,
3204            **opts,
3205        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3207    def distinct(
3208        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3209    ) -> Select:
3210        """
3211        Set the OFFSET expression.
3212
3213        Example:
3214            >>> Select().from_("tbl").select("x").distinct().sql()
3215            'SELECT DISTINCT x FROM tbl'
3216
3217        Args:
3218            ons: the expressions to distinct on
3219            distinct: whether the Select should be distinct
3220            copy: if `False`, modify this expression instance in-place.
3221
3222        Returns:
3223            Select: the modified expression.
3224        """
3225        instance = maybe_copy(self, copy)
3226        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3227        instance.set("distinct", Distinct(on=on) if distinct else None)
3228        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:
3230    def ctas(
3231        self,
3232        table: ExpOrStr,
3233        properties: t.Optional[t.Dict] = None,
3234        dialect: DialectType = None,
3235        copy: bool = True,
3236        **opts,
3237    ) -> Create:
3238        """
3239        Convert this expression to a CREATE TABLE AS statement.
3240
3241        Example:
3242            >>> Select().select("*").from_("tbl").ctas("x").sql()
3243            'CREATE TABLE x AS SELECT * FROM tbl'
3244
3245        Args:
3246            table: the SQL code string to parse as the table name.
3247                If another `Expression` instance is passed, it will be used as-is.
3248            properties: an optional mapping of table properties
3249            dialect: the dialect used to parse the input table.
3250            copy: if `False`, modify this expression instance in-place.
3251            opts: other options to use to parse the input table.
3252
3253        Returns:
3254            The new Create expression.
3255        """
3256        instance = maybe_copy(self, copy)
3257        table_expression = maybe_parse(
3258            table,
3259            into=Table,
3260            dialect=dialect,
3261            **opts,
3262        )
3263        properties_expression = None
3264        if properties:
3265            properties_expression = Properties.from_dict(properties)
3266
3267        return Create(
3268            this=table_expression,
3269            kind="table",
3270            expression=instance,
3271            properties=properties_expression,
3272        )

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:
3274    def lock(self, update: bool = True, copy: bool = True) -> Select:
3275        """
3276        Set the locking read mode for this expression.
3277
3278        Examples:
3279            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3280            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3281
3282            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3283            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3284
3285        Args:
3286            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3287            copy: if `False`, modify this expression instance in-place.
3288
3289        Returns:
3290            The modified expression.
3291        """
3292        inst = maybe_copy(self, copy)
3293        inst.set("locks", [Lock(update=update)])
3294
3295        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:
3297    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3298        """
3299        Set hints for this expression.
3300
3301        Examples:
3302            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3303            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3304
3305        Args:
3306            hints: The SQL code strings to parse as the hints.
3307                If an `Expression` instance is passed, it will be used as-is.
3308            dialect: The dialect used to parse the hints.
3309            copy: If `False`, modify this expression instance in-place.
3310
3311        Returns:
3312            The modified expression.
3313        """
3314        inst = maybe_copy(self, copy)
3315        inst.set(
3316            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3317        )
3318
3319        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]
is_star: bool

Checks whether an expression is a star.

selects: List[Expression]
key = 'select'
class Subquery(DerivedTable, Unionable):
3334class Subquery(DerivedTable, Unionable):
3335    arg_types = {
3336        "this": True,
3337        "alias": False,
3338        "with": False,
3339        **QUERY_MODIFIERS,
3340    }
3341
3342    def unnest(self):
3343        """
3344        Returns the first non subquery.
3345        """
3346        expression = self
3347        while isinstance(expression, Subquery):
3348            expression = expression.this
3349        return expression
3350
3351    def unwrap(self) -> Subquery:
3352        expression = self
3353        while expression.same_parent and expression.is_wrapper:
3354            expression = t.cast(Subquery, expression.parent)
3355        return expression
3356
3357    @property
3358    def is_wrapper(self) -> bool:
3359        """
3360        Whether this Subquery acts as a simple wrapper around another expression.
3361
3362        SELECT * FROM (((SELECT * FROM t)))
3363                      ^
3364                      This corresponds to a "wrapper" Subquery node
3365        """
3366        return all(v is None for k, v in self.args.items() if k != "this")
3367
3368    @property
3369    def is_star(self) -> bool:
3370        return self.this.is_star
3371
3372    @property
3373    def output_name(self) -> str:
3374        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):
3342    def unnest(self):
3343        """
3344        Returns the first non subquery.
3345        """
3346        expression = self
3347        while isinstance(expression, Subquery):
3348            expression = expression.this
3349        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3351    def unwrap(self) -> Subquery:
3352        expression = self
3353        while expression.same_parent and expression.is_wrapper:
3354            expression = t.cast(Subquery, expression.parent)
3355        return expression
is_wrapper: bool

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

Checks whether an expression is a star.

output_name: str

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):
3377class TableSample(Expression):
3378    arg_types = {
3379        "this": False,
3380        "expressions": False,
3381        "method": False,
3382        "bucket_numerator": False,
3383        "bucket_denominator": False,
3384        "bucket_field": False,
3385        "percent": False,
3386        "rows": False,
3387        "size": False,
3388        "seed": False,
3389        "kind": False,
3390    }
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, 'kind': False}
key = 'tablesample'
class Tag(Expression):
3393class Tag(Expression):
3394    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3395
3396    arg_types = {
3397        "this": False,
3398        "prefix": False,
3399        "postfix": False,
3400    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3405class Pivot(Expression):
3406    arg_types = {
3407        "this": False,
3408        "alias": False,
3409        "expressions": True,
3410        "field": False,
3411        "unpivot": False,
3412        "using": False,
3413        "group": False,
3414        "columns": False,
3415        "include_nulls": False,
3416    }
arg_types = {'this': False, 'alias': False, 'expressions': True, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False}
key = 'pivot'
class Window(Condition):
3419class Window(Condition):
3420    arg_types = {
3421        "this": True,
3422        "partition_by": False,
3423        "order": False,
3424        "spec": False,
3425        "alias": False,
3426        "over": False,
3427        "first": False,
3428    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3431class WindowSpec(Expression):
3432    arg_types = {
3433        "kind": False,
3434        "start": False,
3435        "start_side": False,
3436        "end": False,
3437        "end_side": False,
3438    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3441class Where(Expression):
3442    pass
key = 'where'
class Star(Expression):
3445class Star(Expression):
3446    arg_types = {"except": False, "replace": False}
3447
3448    @property
3449    def name(self) -> str:
3450        return "*"
3451
3452    @property
3453    def output_name(self) -> str:
3454        return self.name
arg_types = {'except': False, 'replace': False}
name: str
output_name: str

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):
3457class Parameter(Condition):
3458    arg_types = {"this": True, "wrapped": False}
arg_types = {'this': True, 'wrapped': False}
key = 'parameter'
class SessionParameter(Condition):
3461class SessionParameter(Condition):
3462    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3465class Placeholder(Condition):
3466    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3469class Null(Condition):
3470    arg_types: t.Dict[str, t.Any] = {}
3471
3472    @property
3473    def name(self) -> str:
3474        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
key = 'null'
class Boolean(Condition):
3477class Boolean(Condition):
3478    pass
key = 'boolean'
class DataTypeParam(Expression):
3481class DataTypeParam(Expression):
3482    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3485class DataType(Expression):
3486    arg_types = {
3487        "this": True,
3488        "expressions": False,
3489        "nested": False,
3490        "values": False,
3491        "prefix": False,
3492        "kind": False,
3493    }
3494
3495    class Type(AutoName):
3496        ARRAY = auto()
3497        BIGDECIMAL = auto()
3498        BIGINT = auto()
3499        BIGSERIAL = auto()
3500        BINARY = auto()
3501        BIT = auto()
3502        BOOLEAN = auto()
3503        CHAR = auto()
3504        DATE = auto()
3505        DATEMULTIRANGE = auto()
3506        DATERANGE = auto()
3507        DATETIME = auto()
3508        DATETIME64 = auto()
3509        DECIMAL = auto()
3510        DOUBLE = auto()
3511        ENUM = auto()
3512        ENUM8 = auto()
3513        ENUM16 = auto()
3514        FIXEDSTRING = auto()
3515        FLOAT = auto()
3516        GEOGRAPHY = auto()
3517        GEOMETRY = auto()
3518        HLLSKETCH = auto()
3519        HSTORE = auto()
3520        IMAGE = auto()
3521        INET = auto()
3522        INT = auto()
3523        INT128 = auto()
3524        INT256 = auto()
3525        INT4MULTIRANGE = auto()
3526        INT4RANGE = auto()
3527        INT8MULTIRANGE = auto()
3528        INT8RANGE = auto()
3529        INTERVAL = auto()
3530        IPADDRESS = auto()
3531        IPPREFIX = auto()
3532        JSON = auto()
3533        JSONB = auto()
3534        LONGBLOB = auto()
3535        LONGTEXT = auto()
3536        LOWCARDINALITY = auto()
3537        MAP = auto()
3538        MEDIUMBLOB = auto()
3539        MEDIUMINT = auto()
3540        MEDIUMTEXT = auto()
3541        MONEY = auto()
3542        NCHAR = auto()
3543        NESTED = auto()
3544        NULL = auto()
3545        NULLABLE = auto()
3546        NUMMULTIRANGE = auto()
3547        NUMRANGE = auto()
3548        NVARCHAR = auto()
3549        OBJECT = auto()
3550        ROWVERSION = auto()
3551        SERIAL = auto()
3552        SET = auto()
3553        SMALLINT = auto()
3554        SMALLMONEY = auto()
3555        SMALLSERIAL = auto()
3556        STRUCT = auto()
3557        SUPER = auto()
3558        TEXT = auto()
3559        TINYBLOB = auto()
3560        TINYTEXT = auto()
3561        TIME = auto()
3562        TIMETZ = auto()
3563        TIMESTAMP = auto()
3564        TIMESTAMPLTZ = auto()
3565        TIMESTAMPTZ = auto()
3566        TINYINT = auto()
3567        TSMULTIRANGE = auto()
3568        TSRANGE = auto()
3569        TSTZMULTIRANGE = auto()
3570        TSTZRANGE = auto()
3571        UBIGINT = auto()
3572        UINT = auto()
3573        UINT128 = auto()
3574        UINT256 = auto()
3575        UMEDIUMINT = auto()
3576        UNIQUEIDENTIFIER = auto()
3577        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3578        USERDEFINED = "USER-DEFINED"
3579        USMALLINT = auto()
3580        UTINYINT = auto()
3581        UUID = auto()
3582        VARBINARY = auto()
3583        VARCHAR = auto()
3584        VARIANT = auto()
3585        XML = auto()
3586        YEAR = auto()
3587
3588    TEXT_TYPES = {
3589        Type.CHAR,
3590        Type.NCHAR,
3591        Type.VARCHAR,
3592        Type.NVARCHAR,
3593        Type.TEXT,
3594    }
3595
3596    INTEGER_TYPES = {
3597        Type.INT,
3598        Type.TINYINT,
3599        Type.SMALLINT,
3600        Type.BIGINT,
3601        Type.INT128,
3602        Type.INT256,
3603    }
3604
3605    FLOAT_TYPES = {
3606        Type.FLOAT,
3607        Type.DOUBLE,
3608    }
3609
3610    NUMERIC_TYPES = {
3611        *INTEGER_TYPES,
3612        *FLOAT_TYPES,
3613    }
3614
3615    TEMPORAL_TYPES = {
3616        Type.TIME,
3617        Type.TIMETZ,
3618        Type.TIMESTAMP,
3619        Type.TIMESTAMPTZ,
3620        Type.TIMESTAMPLTZ,
3621        Type.DATE,
3622        Type.DATETIME,
3623        Type.DATETIME64,
3624    }
3625
3626    @classmethod
3627    def build(
3628        cls,
3629        dtype: str | DataType | DataType.Type,
3630        dialect: DialectType = None,
3631        udt: bool = False,
3632        **kwargs,
3633    ) -> DataType:
3634        """
3635        Constructs a DataType object.
3636
3637        Args:
3638            dtype: the data type of interest.
3639            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3640            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3641                DataType, thus creating a user-defined type.
3642            kawrgs: additional arguments to pass in the constructor of DataType.
3643
3644        Returns:
3645            The constructed DataType object.
3646        """
3647        from sqlglot import parse_one
3648
3649        if isinstance(dtype, str):
3650            if dtype.upper() == "UNKNOWN":
3651                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3652
3653            try:
3654                data_type_exp = parse_one(dtype, read=dialect, into=DataType)
3655            except ParseError:
3656                if udt:
3657                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3658                raise
3659        elif isinstance(dtype, DataType.Type):
3660            data_type_exp = DataType(this=dtype)
3661        elif isinstance(dtype, DataType):
3662            return dtype
3663        else:
3664            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3665
3666        return DataType(**{**data_type_exp.args, **kwargs})
3667
3668    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
3669        """
3670        Checks whether this DataType matches one of the provided data types. Nested types or precision
3671        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3672
3673        Args:
3674            dtypes: the data types to compare this DataType to.
3675
3676        Returns:
3677            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3678        """
3679        for dtype in dtypes:
3680            other = DataType.build(dtype, udt=True)
3681
3682            if (
3683                other.expressions
3684                or self.this == DataType.Type.USERDEFINED
3685                or other.this == DataType.Type.USERDEFINED
3686            ):
3687                matches = self == other
3688            else:
3689                matches = self.this == other.this
3690
3691            if matches:
3692                return True
3693        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.CHAR: 'CHAR'>, <Type.NCHAR: 'NCHAR'>}
INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>}
TEMPORAL_TYPES = {<Type.TIME: 'TIME'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP: 'TIMESTAMP'>}
@classmethod
def build( cls, dtype: str | DataType | DataType.Type, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, **kwargs) -> DataType:
3626    @classmethod
3627    def build(
3628        cls,
3629        dtype: str | DataType | DataType.Type,
3630        dialect: DialectType = None,
3631        udt: bool = False,
3632        **kwargs,
3633    ) -> DataType:
3634        """
3635        Constructs a DataType object.
3636
3637        Args:
3638            dtype: the data type of interest.
3639            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3640            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3641                DataType, thus creating a user-defined type.
3642            kawrgs: additional arguments to pass in the constructor of DataType.
3643
3644        Returns:
3645            The constructed DataType object.
3646        """
3647        from sqlglot import parse_one
3648
3649        if isinstance(dtype, str):
3650            if dtype.upper() == "UNKNOWN":
3651                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3652
3653            try:
3654                data_type_exp = parse_one(dtype, read=dialect, into=DataType)
3655            except ParseError:
3656                if udt:
3657                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3658                raise
3659        elif isinstance(dtype, DataType.Type):
3660            data_type_exp = DataType(this=dtype)
3661        elif isinstance(dtype, DataType):
3662            return dtype
3663        else:
3664            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3665
3666        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: str | DataType | DataType.Type) -> bool:
3668    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
3669        """
3670        Checks whether this DataType matches one of the provided data types. Nested types or precision
3671        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3672
3673        Args:
3674            dtypes: the data types to compare this DataType to.
3675
3676        Returns:
3677            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3678        """
3679        for dtype in dtypes:
3680            other = DataType.build(dtype, udt=True)
3681
3682            if (
3683                other.expressions
3684                or self.this == DataType.Type.USERDEFINED
3685                or other.this == DataType.Type.USERDEFINED
3686            ):
3687                matches = self == other
3688            else:
3689                matches = self.this == other.this
3690
3691            if matches:
3692                return True
3693        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):
3495    class Type(AutoName):
3496        ARRAY = auto()
3497        BIGDECIMAL = auto()
3498        BIGINT = auto()
3499        BIGSERIAL = auto()
3500        BINARY = auto()
3501        BIT = auto()
3502        BOOLEAN = auto()
3503        CHAR = auto()
3504        DATE = auto()
3505        DATEMULTIRANGE = auto()
3506        DATERANGE = auto()
3507        DATETIME = auto()
3508        DATETIME64 = auto()
3509        DECIMAL = auto()
3510        DOUBLE = auto()
3511        ENUM = auto()
3512        ENUM8 = auto()
3513        ENUM16 = auto()
3514        FIXEDSTRING = auto()
3515        FLOAT = auto()
3516        GEOGRAPHY = auto()
3517        GEOMETRY = auto()
3518        HLLSKETCH = auto()
3519        HSTORE = auto()
3520        IMAGE = auto()
3521        INET = auto()
3522        INT = auto()
3523        INT128 = auto()
3524        INT256 = auto()
3525        INT4MULTIRANGE = auto()
3526        INT4RANGE = auto()
3527        INT8MULTIRANGE = auto()
3528        INT8RANGE = auto()
3529        INTERVAL = auto()
3530        IPADDRESS = auto()
3531        IPPREFIX = auto()
3532        JSON = auto()
3533        JSONB = auto()
3534        LONGBLOB = auto()
3535        LONGTEXT = auto()
3536        LOWCARDINALITY = auto()
3537        MAP = auto()
3538        MEDIUMBLOB = auto()
3539        MEDIUMINT = auto()
3540        MEDIUMTEXT = auto()
3541        MONEY = auto()
3542        NCHAR = auto()
3543        NESTED = auto()
3544        NULL = auto()
3545        NULLABLE = auto()
3546        NUMMULTIRANGE = auto()
3547        NUMRANGE = auto()
3548        NVARCHAR = auto()
3549        OBJECT = auto()
3550        ROWVERSION = auto()
3551        SERIAL = auto()
3552        SET = auto()
3553        SMALLINT = auto()
3554        SMALLMONEY = auto()
3555        SMALLSERIAL = auto()
3556        STRUCT = auto()
3557        SUPER = auto()
3558        TEXT = auto()
3559        TINYBLOB = auto()
3560        TINYTEXT = auto()
3561        TIME = auto()
3562        TIMETZ = auto()
3563        TIMESTAMP = auto()
3564        TIMESTAMPLTZ = auto()
3565        TIMESTAMPTZ = auto()
3566        TINYINT = auto()
3567        TSMULTIRANGE = auto()
3568        TSRANGE = auto()
3569        TSTZMULTIRANGE = auto()
3570        TSTZRANGE = auto()
3571        UBIGINT = auto()
3572        UINT = auto()
3573        UINT128 = auto()
3574        UINT256 = auto()
3575        UMEDIUMINT = auto()
3576        UNIQUEIDENTIFIER = auto()
3577        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3578        USERDEFINED = "USER-DEFINED"
3579        USMALLINT = auto()
3580        UTINYINT = auto()
3581        UUID = auto()
3582        VARBINARY = auto()
3583        VARCHAR = auto()
3584        VARIANT = auto()
3585        XML = auto()
3586        YEAR = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
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'>
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'>
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'>
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'>
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
class PseudoType(Expression):
3697class PseudoType(Expression):
3698    pass
key = 'pseudotype'
class ObjectIdentifier(Expression):
3702class ObjectIdentifier(Expression):
3703    pass
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3707class SubqueryPredicate(Predicate):
3708    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3711class All(SubqueryPredicate):
3712    pass
key = 'all'
class Any(SubqueryPredicate):
3715class Any(SubqueryPredicate):
3716    pass
key = 'any'
class Exists(SubqueryPredicate):
3719class Exists(SubqueryPredicate):
3720    pass
key = 'exists'
class Command(Expression):
3725class Command(Expression):
3726    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3729class Transaction(Expression):
3730    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3733class Commit(Expression):
3734    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3737class Rollback(Expression):
3738    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3741class AlterTable(Expression):
3742    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):
3745class AddConstraint(Expression):
3746    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3749class DropPartition(Expression):
3750    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3754class Binary(Condition):
3755    arg_types = {"this": True, "expression": True}
3756
3757    @property
3758    def left(self):
3759        return self.this
3760
3761    @property
3762    def right(self):
3763        return self.expression
arg_types = {'this': True, 'expression': True}
left
right
key = 'binary'
class Add(Binary):
3766class Add(Binary):
3767    pass
key = 'add'
class Connector(Binary):
3770class Connector(Binary):
3771    pass
key = 'connector'
class And(Connector):
3774class And(Connector):
3775    pass
key = 'and'
class Or(Connector):
3778class Or(Connector):
3779    pass
key = 'or'
class BitwiseAnd(Binary):
3782class BitwiseAnd(Binary):
3783    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3786class BitwiseLeftShift(Binary):
3787    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3790class BitwiseOr(Binary):
3791    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3794class BitwiseRightShift(Binary):
3795    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3798class BitwiseXor(Binary):
3799    pass
key = 'bitwisexor'
class Div(Binary):
3802class Div(Binary):
3803    pass
key = 'div'
class Overlaps(Binary):
3806class Overlaps(Binary):
3807    pass
key = 'overlaps'
class Dot(Binary):
3810class Dot(Binary):
3811    @property
3812    def name(self) -> str:
3813        return self.expression.name
3814
3815    @property
3816    def output_name(self) -> str:
3817        return self.name
3818
3819    @classmethod
3820    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3821        """Build a Dot object with a sequence of expressions."""
3822        if len(expressions) < 2:
3823            raise ValueError(f"Dot requires >= 2 expressions.")
3824
3825        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
name: str
output_name: str

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:
3819    @classmethod
3820    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3821        """Build a Dot object with a sequence of expressions."""
3822        if len(expressions) < 2:
3823            raise ValueError(f"Dot requires >= 2 expressions.")
3824
3825        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))

Build a Dot object with a sequence of expressions.

key = 'dot'
class DPipe(Binary):
3828class DPipe(Binary):
3829    pass
key = 'dpipe'
class SafeDPipe(DPipe):
3832class SafeDPipe(DPipe):
3833    pass
key = 'safedpipe'
class EQ(Binary, Predicate):
3836class EQ(Binary, Predicate):
3837    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
3840class NullSafeEQ(Binary, Predicate):
3841    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
3844class NullSafeNEQ(Binary, Predicate):
3845    pass
key = 'nullsafeneq'
class Distance(Binary):
3848class Distance(Binary):
3849    pass
key = 'distance'
class Escape(Binary):
3852class Escape(Binary):
3853    pass
key = 'escape'
class Glob(Binary, Predicate):
3856class Glob(Binary, Predicate):
3857    pass
key = 'glob'
class GT(Binary, Predicate):
3860class GT(Binary, Predicate):
3861    pass
key = 'gt'
class GTE(Binary, Predicate):
3864class GTE(Binary, Predicate):
3865    pass
key = 'gte'
class ILike(Binary, Predicate):
3868class ILike(Binary, Predicate):
3869    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
3872class ILikeAny(Binary, Predicate):
3873    pass
key = 'ilikeany'
class IntDiv(Binary):
3876class IntDiv(Binary):
3877    pass
key = 'intdiv'
class Is(Binary, Predicate):
3880class Is(Binary, Predicate):
3881    pass
key = 'is'
class Kwarg(Binary):
3884class Kwarg(Binary):
3885    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
3888class Like(Binary, Predicate):
3889    pass
key = 'like'
class LikeAny(Binary, Predicate):
3892class LikeAny(Binary, Predicate):
3893    pass
key = 'likeany'
class LT(Binary, Predicate):
3896class LT(Binary, Predicate):
3897    pass
key = 'lt'
class LTE(Binary, Predicate):
3900class LTE(Binary, Predicate):
3901    pass
key = 'lte'
class Mod(Binary):
3904class Mod(Binary):
3905    pass
key = 'mod'
class Mul(Binary):
3908class Mul(Binary):
3909    pass
key = 'mul'
class NEQ(Binary, Predicate):
3912class NEQ(Binary, Predicate):
3913    pass
key = 'neq'
class SimilarTo(Binary, Predicate):
3916class SimilarTo(Binary, Predicate):
3917    pass
key = 'similarto'
class Slice(Binary):
3920class Slice(Binary):
3921    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
3924class Sub(Binary):
3925    pass
key = 'sub'
class ArrayOverlaps(Binary):
3928class ArrayOverlaps(Binary):
3929    pass
key = 'arrayoverlaps'
class Unary(Condition):
3934class Unary(Condition):
3935    pass
key = 'unary'
class BitwiseNot(Unary):
3938class BitwiseNot(Unary):
3939    pass
key = 'bitwisenot'
class Not(Unary):
3942class Not(Unary):
3943    pass
key = 'not'
class Paren(Unary):
3946class Paren(Unary):
3947    arg_types = {"this": True, "with": False}
3948
3949    @property
3950    def output_name(self) -> str:
3951        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str

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):
3954class Neg(Unary):
3955    pass
key = 'neg'
class Alias(Expression):
3958class Alias(Expression):
3959    arg_types = {"this": True, "alias": False}
3960
3961    @property
3962    def output_name(self) -> str:
3963        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str

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 Aliases(Expression):
3966class Aliases(Expression):
3967    arg_types = {"this": True, "expressions": True}
3968
3969    @property
3970    def aliases(self):
3971        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
key = 'aliases'
class AtTimeZone(Expression):
3974class AtTimeZone(Expression):
3975    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
3978class Between(Predicate):
3979    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
3982class Bracket(Condition):
3983    arg_types = {"this": True, "expressions": True}
3984
3985    @property
3986    def output_name(self) -> str:
3987        if len(self.expressions) == 1:
3988            return self.expressions[0].output_name
3989
3990        return super().output_name
arg_types = {'this': True, 'expressions': True}
output_name: str

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 SafeBracket(Bracket):
3993class SafeBracket(Bracket):
3994    """Represents array lookup where OOB index yields NULL instead of causing a failure."""

Represents array lookup where OOB index yields NULL instead of causing a failure.

key = 'safebracket'
class Distinct(Expression):
3997class Distinct(Expression):
3998    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4001class In(Predicate):
4002    arg_types = {
4003        "this": True,
4004        "expressions": False,
4005        "query": False,
4006        "unnest": False,
4007        "field": False,
4008        "is_global": False,
4009    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class TimeUnit(Expression):
4012class TimeUnit(Expression):
4013    """Automatically converts unit arg into a var."""
4014
4015    arg_types = {"unit": False}
4016
4017    def __init__(self, **args):
4018        unit = args.get("unit")
4019        if isinstance(unit, (Column, Literal)):
4020            args["unit"] = Var(this=unit.name)
4021        elif isinstance(unit, Week):
4022            unit.set("this", Var(this=unit.this.name))
4023
4024        super().__init__(**args)
4025
4026    @property
4027    def unit(self) -> t.Optional[Var]:
4028        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4017    def __init__(self, **args):
4018        unit = args.get("unit")
4019        if isinstance(unit, (Column, Literal)):
4020            args["unit"] = Var(this=unit.name)
4021        elif isinstance(unit, Week):
4022            unit.set("this", Var(this=unit.this.name))
4023
4024        super().__init__(**args)
arg_types = {'unit': False}
unit: Optional[Var]
key = 'timeunit'
class IntervalSpan(Expression):
4034class IntervalSpan(Expression):
4035    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4038class Interval(TimeUnit):
4039    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4042class IgnoreNulls(Expression):
4043    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4046class RespectNulls(Expression):
4047    pass
key = 'respectnulls'
class Func(Condition):
4051class Func(Condition):
4052    """
4053    The base class for all function expressions.
4054
4055    Attributes:
4056        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4057            treated as a variable length argument and the argument's value will be stored as a list.
4058        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4059            for this function expression. These values are used to map this node to a name during parsing
4060            as well as to provide the function's name during SQL string generation. By default the SQL
4061            name is set to the expression's class name transformed to snake case.
4062    """
4063
4064    is_var_len_args = False
4065
4066    @classmethod
4067    def from_arg_list(cls, args):
4068        if cls.is_var_len_args:
4069            all_arg_keys = list(cls.arg_types)
4070            # If this function supports variable length argument treat the last argument as such.
4071            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4072            num_non_var = len(non_var_len_arg_keys)
4073
4074            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4075            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4076        else:
4077            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4078
4079        return cls(**args_dict)
4080
4081    @classmethod
4082    def sql_names(cls):
4083        if cls is Func:
4084            raise NotImplementedError(
4085                "SQL name is only supported by concrete function implementations"
4086            )
4087        if "_sql_names" not in cls.__dict__:
4088            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4089        return cls._sql_names
4090
4091    @classmethod
4092    def sql_name(cls):
4093        return cls.sql_names()[0]
4094
4095    @classmethod
4096    def default_parser_mappings(cls):
4097        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):
4066    @classmethod
4067    def from_arg_list(cls, args):
4068        if cls.is_var_len_args:
4069            all_arg_keys = list(cls.arg_types)
4070            # If this function supports variable length argument treat the last argument as such.
4071            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4072            num_non_var = len(non_var_len_arg_keys)
4073
4074            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4075            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4076        else:
4077            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4078
4079        return cls(**args_dict)
@classmethod
def sql_names(cls):
4081    @classmethod
4082    def sql_names(cls):
4083        if cls is Func:
4084            raise NotImplementedError(
4085                "SQL name is only supported by concrete function implementations"
4086            )
4087        if "_sql_names" not in cls.__dict__:
4088            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4089        return cls._sql_names
@classmethod
def sql_name(cls):
4091    @classmethod
4092    def sql_name(cls):
4093        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4095    @classmethod
4096    def default_parser_mappings(cls):
4097        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4100class AggFunc(Func):
4101    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4104class ParameterizedAgg(AggFunc):
4105    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4108class Abs(Func):
4109    pass
key = 'abs'
class Transform(Func):
4113class Transform(Func):
4114    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4117class Anonymous(Func):
4118    arg_types = {"this": True, "expressions": False}
4119    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class Hll(AggFunc):
4124class Hll(AggFunc):
4125    arg_types = {"this": True, "expressions": False}
4126    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4129class ApproxDistinct(AggFunc):
4130    arg_types = {"this": True, "accuracy": False}
4131    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4134class Array(Func):
4135    arg_types = {"expressions": False}
4136    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToChar(Func):
4140class ToChar(Func):
4141    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tochar'
class GenerateSeries(Func):
4144class GenerateSeries(Func):
4145    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4148class ArrayAgg(AggFunc):
4149    pass
key = 'arrayagg'
class ArrayAll(Func):
4152class ArrayAll(Func):
4153    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4156class ArrayAny(Func):
4157    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4160class ArrayConcat(Func):
4161    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4162    arg_types = {"this": True, "expressions": False}
4163    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4166class ArrayContains(Binary, Func):
4167    pass
key = 'arraycontains'
class ArrayContained(Binary):
4170class ArrayContained(Binary):
4171    pass
key = 'arraycontained'
class ArrayFilter(Func):
4174class ArrayFilter(Func):
4175    arg_types = {"this": True, "expression": True}
4176    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4179class ArrayJoin(Func):
4180    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4183class ArraySize(Func):
4184    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4187class ArraySort(Func):
4188    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4191class ArraySum(Func):
4192    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4195class ArrayUnionAgg(AggFunc):
4196    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4199class Avg(AggFunc):
4200    pass
key = 'avg'
class AnyValue(AggFunc):
4203class AnyValue(AggFunc):
4204    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):
4207class First(Func):
4208    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4211class Last(Func):
4212    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4215class Case(Func):
4216    arg_types = {"this": False, "ifs": True, "default": False}
4217
4218    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4219        instance = maybe_copy(self, copy)
4220        instance.append(
4221            "ifs",
4222            If(
4223                this=maybe_parse(condition, copy=copy, **opts),
4224                true=maybe_parse(then, copy=copy, **opts),
4225            ),
4226        )
4227        return instance
4228
4229    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4230        instance = maybe_copy(self, copy)
4231        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4232        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:
4218    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4219        instance = maybe_copy(self, copy)
4220        instance.append(
4221            "ifs",
4222            If(
4223                this=maybe_parse(condition, copy=copy, **opts),
4224                true=maybe_parse(then, copy=copy, **opts),
4225            ),
4226        )
4227        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4229    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4230        instance = maybe_copy(self, copy)
4231        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4232        return instance
key = 'case'
class Cast(Func):
4235class Cast(Func):
4236    arg_types = {"this": True, "to": True, "format": False}
4237
4238    @property
4239    def name(self) -> str:
4240        return self.this.name
4241
4242    @property
4243    def to(self) -> DataType:
4244        return self.args["to"]
4245
4246    @property
4247    def output_name(self) -> str:
4248        return self.name
4249
4250    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
4251        """
4252        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4253        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4254        array<int> != array<float>.
4255
4256        Args:
4257            dtypes: the data types to compare this Cast's DataType to.
4258
4259        Returns:
4260            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4261        """
4262        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False}
name: str
to: DataType
output_name: str

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: str | DataType | DataType.Type) -> bool:
4250    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
4251        """
4252        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4253        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4254        array<int> != array<float>.
4255
4256        Args:
4257            dtypes: the data types to compare this Cast's DataType to.
4258
4259        Returns:
4260            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4261        """
4262        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):
4265class TryCast(Cast):
4266    pass
key = 'trycast'
class CastToStrType(Func):
4269class CastToStrType(Func):
4270    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary):
4273class Collate(Binary):
4274    pass
key = 'collate'
class Ceil(Func):
4277class Ceil(Func):
4278    arg_types = {"this": True, "decimals": False}
4279    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4282class Coalesce(Func):
4283    arg_types = {"this": True, "expressions": False}
4284    is_var_len_args = True
4285    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Concat(Func):
4288class Concat(Func):
4289    arg_types = {"expressions": True}
4290    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'concat'
class SafeConcat(Concat):
4293class SafeConcat(Concat):
4294    pass
key = 'safeconcat'
class ConcatWs(Concat):
4297class ConcatWs(Concat):
4298    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4301class Count(AggFunc):
4302    arg_types = {"this": False, "expressions": False}
4303    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4306class CountIf(AggFunc):
4307    pass
key = 'countif'
class CurrentDate(Func):
4310class CurrentDate(Func):
4311    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4314class CurrentDatetime(Func):
4315    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4318class CurrentTime(Func):
4319    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4322class CurrentTimestamp(Func):
4323    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4326class CurrentUser(Func):
4327    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, TimeUnit):
4330class DateAdd(Func, TimeUnit):
4331    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, TimeUnit):
4334class DateSub(Func, TimeUnit):
4335    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4338class DateDiff(Func, TimeUnit):
4339    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4340    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4343class DateTrunc(Func):
4344    arg_types = {"unit": True, "this": True, "zone": False}
4345
4346    @property
4347    def unit(self) -> Expression:
4348        return self.args["unit"]
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
key = 'datetrunc'
class DatetimeAdd(Func, TimeUnit):
4351class DatetimeAdd(Func, TimeUnit):
4352    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, TimeUnit):
4355class DatetimeSub(Func, TimeUnit):
4356    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4359class DatetimeDiff(Func, TimeUnit):
4360    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4363class DatetimeTrunc(Func, TimeUnit):
4364    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4367class DayOfWeek(Func):
4368    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4371class DayOfMonth(Func):
4372    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4375class DayOfYear(Func):
4376    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class WeekOfYear(Func):
4379class WeekOfYear(Func):
4380    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4383class MonthsBetween(Func):
4384    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDateOfMonth(Func):
4387class LastDateOfMonth(Func):
4388    pass
key = 'lastdateofmonth'
class Extract(Func):
4391class Extract(Func):
4392    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4395class Timestamp(Func):
4396    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4399class TimestampAdd(Func, TimeUnit):
4400    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4403class TimestampSub(Func, TimeUnit):
4404    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4407class TimestampDiff(Func, TimeUnit):
4408    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4411class TimestampTrunc(Func, TimeUnit):
4412    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4415class TimeAdd(Func, TimeUnit):
4416    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4419class TimeSub(Func, TimeUnit):
4420    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4423class TimeDiff(Func, TimeUnit):
4424    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4427class TimeTrunc(Func, TimeUnit):
4428    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4431class DateFromParts(Func):
4432    _sql_names = ["DATEFROMPARTS"]
4433    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class DateStrToDate(Func):
4436class DateStrToDate(Func):
4437    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4440class DateToDateStr(Func):
4441    pass
key = 'datetodatestr'
class DateToDi(Func):
4444class DateToDi(Func):
4445    pass
key = 'datetodi'
class Date(Func):
4449class Date(Func):
4450    arg_types = {"this": False, "zone": False, "expressions": False}
4451    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4454class Day(Func):
4455    pass
key = 'day'
class Decode(Func):
4458class Decode(Func):
4459    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4462class DiToDate(Func):
4463    pass
key = 'ditodate'
class Encode(Func):
4466class Encode(Func):
4467    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4470class Exp(Func):
4471    pass
key = 'exp'
class Explode(Func):
4474class Explode(Func):
4475    pass
key = 'explode'
class Floor(Func):
4478class Floor(Func):
4479    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4482class FromBase64(Func):
4483    pass
key = 'frombase64'
class ToBase64(Func):
4486class ToBase64(Func):
4487    pass
key = 'tobase64'
class Greatest(Func):
4490class Greatest(Func):
4491    arg_types = {"this": True, "expressions": False}
4492    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4495class GroupConcat(AggFunc):
4496    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4499class Hex(Func):
4500    pass
key = 'hex'
class Xor(Connector, Func):
4503class Xor(Connector, Func):
4504    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4507class If(Func):
4508    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Initcap(Func):
4511class Initcap(Func):
4512    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4515class IsNan(Func):
4516    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class FormatJson(Expression):
4519class FormatJson(Expression):
4520    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4523class JSONKeyValue(Expression):
4524    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4527class JSONObject(Func):
4528    arg_types = {
4529        "expressions": False,
4530        "null_handling": False,
4531        "unique_keys": False,
4532        "return_type": False,
4533        "encoding": False,
4534    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4538class JSONArray(Func):
4539    arg_types = {
4540        "expressions": True,
4541        "null_handling": False,
4542        "return_type": False,
4543        "strict": False,
4544    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4548class JSONArrayAgg(Func):
4549    arg_types = {
4550        "this": True,
4551        "order": False,
4552        "null_handling": False,
4553        "return_type": False,
4554        "strict": False,
4555    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4560class JSONColumnDef(Expression):
4561    arg_types = {"this": True, "kind": False, "path": False}
arg_types = {'this': True, 'kind': False, 'path': False}
key = 'jsoncolumndef'
class JSONTable(Func):
4565class JSONTable(Func):
4566    arg_types = {
4567        "this": True,
4568        "expressions": True,
4569        "path": False,
4570        "error_handling": False,
4571        "empty_handling": False,
4572    }
arg_types = {'this': True, 'expressions': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4575class OpenJSONColumnDef(Expression):
4576    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):
4579class OpenJSON(Func):
4580    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4583class JSONBContains(Binary):
4584    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4587class JSONExtract(Binary, Func):
4588    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4591class JSONExtractScalar(JSONExtract):
4592    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4595class JSONBExtract(JSONExtract):
4596    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4599class JSONBExtractScalar(JSONExtract):
4600    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4603class JSONFormat(Func):
4604    arg_types = {"this": False, "options": False}
4605    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4609class JSONArrayContains(Binary, Predicate, Func):
4610    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4613class ParseJSON(Func):
4614    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4615    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
key = 'parsejson'
class Least(Func):
4618class Least(Func):
4619    arg_types = {"this": True, "expressions": False}
4620    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4623class Left(Func):
4624    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4631class Length(Func):
4632    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4635class Levenshtein(Func):
4636    arg_types = {
4637        "this": True,
4638        "expression": False,
4639        "ins_cost": False,
4640        "del_cost": False,
4641        "sub_cost": False,
4642    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4645class Ln(Func):
4646    pass
key = 'ln'
class Log(Func):
4649class Log(Func):
4650    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4653class Log2(Func):
4654    pass
key = 'log2'
class Log10(Func):
4657class Log10(Func):
4658    pass
key = 'log10'
class LogicalOr(AggFunc):
4661class LogicalOr(AggFunc):
4662    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4665class LogicalAnd(AggFunc):
4666    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4669class Lower(Func):
4670    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4673class Map(Func):
4674    arg_types = {"keys": False, "values": False}
arg_types = {'keys': False, 'values': False}
key = 'map'
class MapFromEntries(Func):
4677class MapFromEntries(Func):
4678    pass
key = 'mapfromentries'
class StarMap(Func):
4681class StarMap(Func):
4682    pass
key = 'starmap'
class VarMap(Func):
4685class VarMap(Func):
4686    arg_types = {"keys": True, "values": True}
4687    is_var_len_args = True
4688
4689    @property
4690    def keys(self) -> t.List[Expression]:
4691        return self.args["keys"].expressions
4692
4693    @property
4694    def values(self) -> t.List[Expression]:
4695        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
values: List[Expression]
key = 'varmap'
class MatchAgainst(Func):
4699class MatchAgainst(Func):
4700    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4703class Max(AggFunc):
4704    arg_types = {"this": True, "expressions": False}
4705    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
4708class MD5(Func):
4709    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
4713class MD5Digest(Func):
4714    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
4717class Min(AggFunc):
4718    arg_types = {"this": True, "expressions": False}
4719    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
4722class Month(Func):
4723    pass
key = 'month'
class Nvl2(Func):
4726class Nvl2(Func):
4727    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Posexplode(Func):
4730class Posexplode(Func):
4731    pass
key = 'posexplode'
class Pow(Binary, Func):
4734class Pow(Binary, Func):
4735    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
4738class PercentileCont(AggFunc):
4739    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
4742class PercentileDisc(AggFunc):
4743    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
4746class Quantile(AggFunc):
4747    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
4750class ApproxQuantile(Quantile):
4751    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class RangeN(Func):
4754class RangeN(Func):
4755    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
4758class ReadCSV(Func):
4759    _sql_names = ["READ_CSV"]
4760    is_var_len_args = True
4761    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
4764class Reduce(Func):
4765    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):
4768class RegexpExtract(Func):
4769    arg_types = {
4770        "this": True,
4771        "expression": True,
4772        "position": False,
4773        "occurrence": False,
4774        "parameters": False,
4775        "group": False,
4776    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
4779class RegexpReplace(Func):
4780    arg_types = {
4781        "this": True,
4782        "expression": True,
4783        "replacement": True,
4784        "position": False,
4785        "occurrence": False,
4786        "parameters": False,
4787    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
4790class RegexpLike(Binary, Func):
4791    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Func):
4794class RegexpILike(Func):
4795    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
4800class RegexpSplit(Func):
4801    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
4804class Repeat(Func):
4805    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
4808class Round(Func):
4809    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
4812class RowNumber(Func):
4813    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
4816class SafeDivide(Func):
4817    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SetAgg(AggFunc):
4820class SetAgg(AggFunc):
4821    pass
key = 'setagg'
class SHA(Func):
4824class SHA(Func):
4825    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
4828class SHA2(Func):
4829    _sql_names = ["SHA2"]
4830    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
4833class SortArray(Func):
4834    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
4837class Split(Func):
4838    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
4843class Substring(Func):
4844    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
4847class StandardHash(Func):
4848    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
4851class StartsWith(Func):
4852    _sql_names = ["STARTS_WITH", "STARTSWITH"]
4853    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
4856class StrPosition(Func):
4857    arg_types = {
4858        "this": True,
4859        "substr": True,
4860        "position": False,
4861        "instance": False,
4862    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
4865class StrToDate(Func):
4866    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
4869class StrToTime(Func):
4870    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
4875class StrToUnix(Func):
4876    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
4881class StrToMap(Func):
4882    arg_types = {
4883        "this": True,
4884        "pair_delim": False,
4885        "key_value_delim": False,
4886        "duplicate_resolution_callback": False,
4887    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
4890class NumberToStr(Func):
4891    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
4894class FromBase(Func):
4895    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
4898class Struct(Func):
4899    arg_types = {"expressions": True}
4900    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
4903class StructExtract(Func):
4904    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
4909class Stuff(Func):
4910    _sql_names = ["STUFF", "INSERT"]
4911    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):
4914class Sum(AggFunc):
4915    pass
key = 'sum'
class Sqrt(Func):
4918class Sqrt(Func):
4919    pass
key = 'sqrt'
class Stddev(AggFunc):
4922class Stddev(AggFunc):
4923    pass
key = 'stddev'
class StddevPop(AggFunc):
4926class StddevPop(AggFunc):
4927    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
4930class StddevSamp(AggFunc):
4931    pass
key = 'stddevsamp'
class TimeToStr(Func):
4934class TimeToStr(Func):
4935    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
4938class TimeToTimeStr(Func):
4939    pass
key = 'timetotimestr'
class TimeToUnix(Func):
4942class TimeToUnix(Func):
4943    pass
key = 'timetounix'
class TimeStrToDate(Func):
4946class TimeStrToDate(Func):
4947    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
4950class TimeStrToTime(Func):
4951    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
4954class TimeStrToUnix(Func):
4955    pass
key = 'timestrtounix'
class Trim(Func):
4958class Trim(Func):
4959    arg_types = {
4960        "this": True,
4961        "expression": False,
4962        "position": False,
4963        "collation": False,
4964    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
4967class TsOrDsAdd(Func, TimeUnit):
4968    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsadd'
class TsOrDsToDateStr(Func):
4971class TsOrDsToDateStr(Func):
4972    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
4975class TsOrDsToDate(Func):
4976    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDiToDi(Func):
4979class TsOrDiToDi(Func):
4980    pass
key = 'tsorditodi'
class Unhex(Func):
4983class Unhex(Func):
4984    pass
key = 'unhex'
class UnixToStr(Func):
4987class UnixToStr(Func):
4988    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
4993class UnixToTime(Func):
4994    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
4995
4996    SECONDS = Literal.string("seconds")
4997    MILLIS = Literal.string("millis")
4998    MICROS = Literal.string("micros")
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False}
SECONDS = (LITERAL this: seconds, is_string: True)
MILLIS = (LITERAL this: millis, is_string: True)
MICROS = (LITERAL this: micros, is_string: True)
key = 'unixtotime'
class UnixToTimeStr(Func):
5001class UnixToTimeStr(Func):
5002    pass
key = 'unixtotimestr'
class Upper(Func):
5005class Upper(Func):
5006    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5009class Variance(AggFunc):
5010    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5013class VariancePop(AggFunc):
5014    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5017class Week(Func):
5018    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5021class XMLTable(Func):
5022    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):
5025class Year(Func):
5026    pass
key = 'year'
class Use(Expression):
5029class Use(Expression):
5030    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5033class Merge(Expression):
5034    arg_types = {"this": True, "using": True, "on": True, "expressions": True}
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True}
key = 'merge'
class When(Func):
5037class When(Func):
5038    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):
5043class NextValueFor(Func):
5044    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <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 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Ceil'>, <class 'Coalesce'>, <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 'Extract'>, <class 'First'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONTable'>, <class 'Last'>, <class 'LastDateOfMonth'>, <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 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'Pow'>, <class 'Quantile'>, <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 'SafeConcat'>, <class 'SafeDivide'>, <class 'SetAgg'>, <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 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'Unhex'>, <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'>]
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:
5081def maybe_parse(
5082    sql_or_expression: ExpOrStr,
5083    *,
5084    into: t.Optional[IntoType] = None,
5085    dialect: DialectType = None,
5086    prefix: t.Optional[str] = None,
5087    copy: bool = False,
5088    **opts,
5089) -> Expression:
5090    """Gracefully handle a possible string or expression.
5091
5092    Example:
5093        >>> maybe_parse("1")
5094        (LITERAL this: 1, is_string: False)
5095        >>> maybe_parse(to_identifier("x"))
5096        (IDENTIFIER this: x, quoted: False)
5097
5098    Args:
5099        sql_or_expression: the SQL code string or an expression
5100        into: the SQLGlot Expression to parse into
5101        dialect: the dialect used to parse the input expressions (in the case that an
5102            input expression is a SQL string).
5103        prefix: a string to prefix the sql with before it gets parsed
5104            (automatically includes a space)
5105        copy: whether or not to copy the expression.
5106        **opts: other options to use to parse the input expressions (again, in the case
5107            that an input expression is a SQL string).
5108
5109    Returns:
5110        Expression: the parsed or given expression.
5111    """
5112    if isinstance(sql_or_expression, Expression):
5113        if copy:
5114            return sql_or_expression.copy()
5115        return sql_or_expression
5116
5117    if sql_or_expression is None:
5118        raise ParseError(f"SQL cannot be None")
5119
5120    import sqlglot
5121
5122    sql = str(sql_or_expression)
5123    if prefix:
5124        sql = f"{prefix} {sql}"
5125
5126    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):
5139def maybe_copy(instance, copy=True):
5140    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, **opts) -> Union:
5321def union(
5322    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5323) -> Union:
5324    """
5325    Initializes a syntax tree from one UNION expression.
5326
5327    Example:
5328        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5329        'SELECT * FROM foo UNION SELECT * FROM bla'
5330
5331    Args:
5332        left: the SQL code string corresponding to the left-hand side.
5333            If an `Expression` instance is passed, it will be used as-is.
5334        right: the SQL code string corresponding to the right-hand side.
5335            If an `Expression` instance is passed, it will be used as-is.
5336        distinct: set the DISTINCT flag if and only if this is true.
5337        dialect: the dialect used to parse the input expression.
5338        opts: other options to use to parse the input expressions.
5339
5340    Returns:
5341        The new Union instance.
5342    """
5343    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5344    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5345
5346    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.
  • 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, **opts) -> Intersect:
5349def intersect(
5350    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5351) -> Intersect:
5352    """
5353    Initializes a syntax tree from one INTERSECT expression.
5354
5355    Example:
5356        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5357        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5358
5359    Args:
5360        left: the SQL code string corresponding to the left-hand side.
5361            If an `Expression` instance is passed, it will be used as-is.
5362        right: the SQL code string corresponding to the right-hand side.
5363            If an `Expression` instance is passed, it will be used as-is.
5364        distinct: set the DISTINCT flag if and only if this is true.
5365        dialect: the dialect used to parse the input expression.
5366        opts: other options to use to parse the input expressions.
5367
5368    Returns:
5369        The new Intersect instance.
5370    """
5371    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5372    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5373
5374    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.
  • 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, **opts) -> Except:
5377def except_(
5378    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5379) -> Except:
5380    """
5381    Initializes a syntax tree from one EXCEPT expression.
5382
5383    Example:
5384        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5385        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5386
5387    Args:
5388        left: the SQL code string corresponding to the left-hand side.
5389            If an `Expression` instance is passed, it will be used as-is.
5390        right: the SQL code string corresponding to the right-hand side.
5391            If an `Expression` instance is passed, it will be used as-is.
5392        distinct: set the DISTINCT flag if and only if this is true.
5393        dialect: the dialect used to parse the input expression.
5394        opts: other options to use to parse the input expressions.
5395
5396    Returns:
5397        The new Except instance.
5398    """
5399    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5400    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5401
5402    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.
  • 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:
5405def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5406    """
5407    Initializes a syntax tree from one or multiple SELECT expressions.
5408
5409    Example:
5410        >>> select("col1", "col2").from_("tbl").sql()
5411        'SELECT col1, col2 FROM tbl'
5412
5413    Args:
5414        *expressions: the SQL code string to parse as the expressions of a
5415            SELECT statement. If an Expression instance is passed, this is used as-is.
5416        dialect: the dialect used to parse the input expressions (in the case that an
5417            input expression is a SQL string).
5418        **opts: other options to use to parse the input expressions (again, in the case
5419            that an input expression is a SQL string).
5420
5421    Returns:
5422        Select: the syntax tree for the SELECT statement.
5423    """
5424    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:
5427def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5428    """
5429    Initializes a syntax tree from a FROM expression.
5430
5431    Example:
5432        >>> from_("tbl").select("col1", "col2").sql()
5433        'SELECT col1, col2 FROM tbl'
5434
5435    Args:
5436        *expression: the SQL code string to parse as the FROM expressions of a
5437            SELECT statement. If an Expression instance is passed, this is used as-is.
5438        dialect: the dialect used to parse the input expression (in the case that the
5439            input expression is a SQL string).
5440        **opts: other options to use to parse the input expressions (again, in the case
5441            that the input expression is a SQL string).
5442
5443    Returns:
5444        Select: the syntax tree for the SELECT statement.
5445    """
5446    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:
5449def update(
5450    table: str | Table,
5451    properties: dict,
5452    where: t.Optional[ExpOrStr] = None,
5453    from_: t.Optional[ExpOrStr] = None,
5454    dialect: DialectType = None,
5455    **opts,
5456) -> Update:
5457    """
5458    Creates an update statement.
5459
5460    Example:
5461        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5462        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5463
5464    Args:
5465        *properties: dictionary of properties to set which are
5466            auto converted to sql objects eg None -> NULL
5467        where: sql conditional parsed into a WHERE statement
5468        from_: sql statement parsed into a FROM statement
5469        dialect: the dialect used to parse the input expressions.
5470        **opts: other options to use to parse the input expressions.
5471
5472    Returns:
5473        Update: the syntax tree for the UPDATE statement.
5474    """
5475    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5476    update_expr.set(
5477        "expressions",
5478        [
5479            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5480            for k, v in properties.items()
5481        ],
5482    )
5483    if from_:
5484        update_expr.set(
5485            "from",
5486            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5487        )
5488    if isinstance(where, Condition):
5489        where = Where(this=where)
5490    if where:
5491        update_expr.set(
5492            "where",
5493            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5494        )
5495    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:
5498def delete(
5499    table: ExpOrStr,
5500    where: t.Optional[ExpOrStr] = None,
5501    returning: t.Optional[ExpOrStr] = None,
5502    dialect: DialectType = None,
5503    **opts,
5504) -> Delete:
5505    """
5506    Builds a delete statement.
5507
5508    Example:
5509        >>> delete("my_table", where="id > 1").sql()
5510        'DELETE FROM my_table WHERE id > 1'
5511
5512    Args:
5513        where: sql conditional parsed into a WHERE statement
5514        returning: sql conditional parsed into a RETURNING statement
5515        dialect: the dialect used to parse the input expressions.
5516        **opts: other options to use to parse the input expressions.
5517
5518    Returns:
5519        Delete: the syntax tree for the DELETE statement.
5520    """
5521    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5522    if where:
5523        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5524    if returning:
5525        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5526    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[Union[str, Expression]]] = None, overwrite: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
5529def insert(
5530    expression: ExpOrStr,
5531    into: ExpOrStr,
5532    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5533    overwrite: t.Optional[bool] = None,
5534    dialect: DialectType = None,
5535    copy: bool = True,
5536    **opts,
5537) -> Insert:
5538    """
5539    Builds an INSERT statement.
5540
5541    Example:
5542        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5543        'INSERT INTO tbl VALUES (1, 2, 3)'
5544
5545    Args:
5546        expression: the sql string or expression of the INSERT statement
5547        into: the tbl to insert data to.
5548        columns: optionally the table's column names.
5549        overwrite: whether to INSERT OVERWRITE or not.
5550        dialect: the dialect used to parse the input expressions.
5551        copy: whether or not to copy the expression.
5552        **opts: other options to use to parse the input expressions.
5553
5554    Returns:
5555        Insert: the syntax tree for the INSERT statement.
5556    """
5557    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5558    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5559
5560    if columns:
5561        this = _apply_list_builder(
5562            *columns,
5563            instance=Schema(this=this),
5564            arg="expressions",
5565            into=Identifier,
5566            copy=False,
5567            dialect=dialect,
5568            **opts,
5569        )
5570
5571    return Insert(this=this, expression=expr, overwrite=overwrite)

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.
  • 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:
5574def condition(
5575    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5576) -> Condition:
5577    """
5578    Initialize a logical condition expression.
5579
5580    Example:
5581        >>> condition("x=1").sql()
5582        'x = 1'
5583
5584        This is helpful for composing larger logical syntax trees:
5585        >>> where = condition("x=1")
5586        >>> where = where.and_("y=1")
5587        >>> Select().from_("tbl").select("*").where(where).sql()
5588        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5589
5590    Args:
5591        *expression: the SQL code string to parse.
5592            If an Expression instance is passed, this is used as-is.
5593        dialect: the dialect used to parse the input expression (in the case that the
5594            input expression is a SQL string).
5595        copy: Whether or not to copy `expression` (only applies to expressions).
5596        **opts: other options to use to parse the input expressions (again, in the case
5597            that the input expression is a SQL string).
5598
5599    Returns:
5600        The new Condition instance
5601    """
5602    return maybe_parse(
5603        expression,
5604        into=Condition,
5605        dialect=dialect,
5606        copy=copy,
5607        **opts,
5608    )

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:
5611def and_(
5612    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5613) -> Condition:
5614    """
5615    Combine multiple conditions with an AND logical operator.
5616
5617    Example:
5618        >>> and_("x=1", and_("y=1", "z=1")).sql()
5619        'x = 1 AND (y = 1 AND z = 1)'
5620
5621    Args:
5622        *expressions: the SQL code strings to parse.
5623            If an Expression instance is passed, this is used as-is.
5624        dialect: the dialect used to parse the input expression.
5625        copy: whether or not to copy `expressions` (only applies to Expressions).
5626        **opts: other options to use to parse the input expressions.
5627
5628    Returns:
5629        And: the new condition
5630    """
5631    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:
5634def or_(
5635    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5636) -> Condition:
5637    """
5638    Combine multiple conditions with an OR logical operator.
5639
5640    Example:
5641        >>> or_("x=1", or_("y=1", "z=1")).sql()
5642        'x = 1 OR (y = 1 OR z = 1)'
5643
5644    Args:
5645        *expressions: the SQL code strings to parse.
5646            If an Expression instance is passed, this is used as-is.
5647        dialect: the dialect used to parse the input expression.
5648        copy: whether or not to copy `expressions` (only applies to Expressions).
5649        **opts: other options to use to parse the input expressions.
5650
5651    Returns:
5652        Or: the new condition
5653    """
5654    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:
5657def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
5658    """
5659    Wrap a condition with a NOT operator.
5660
5661    Example:
5662        >>> not_("this_suit='black'").sql()
5663        "NOT this_suit = 'black'"
5664
5665    Args:
5666        expression: the SQL code string to parse.
5667            If an Expression instance is passed, this is used as-is.
5668        dialect: the dialect used to parse the input expression.
5669        copy: whether to copy the expression or not.
5670        **opts: other options to use to parse the input expressions.
5671
5672    Returns:
5673        The new condition.
5674    """
5675    this = condition(
5676        expression,
5677        dialect=dialect,
5678        copy=copy,
5679        **opts,
5680    )
5681    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:
5684def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
5685    """
5686    Wrap an expression in parentheses.
5687
5688    Example:
5689        >>> paren("5 + 3").sql()
5690        '(5 + 3)'
5691
5692    Args:
5693        expression: the SQL code string to parse.
5694            If an Expression instance is passed, this is used as-is.
5695        copy: whether to copy the expression or not.
5696
5697    Returns:
5698        The wrapped expression.
5699    """
5700    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):
5718def to_identifier(name, quoted=None, copy=True):
5719    """Builds an identifier.
5720
5721    Args:
5722        name: The name to turn into an identifier.
5723        quoted: Whether or not force quote the identifier.
5724        copy: Whether or not to copy a passed in Identefier node.
5725
5726    Returns:
5727        The identifier ast node.
5728    """
5729
5730    if name is None:
5731        return None
5732
5733    if isinstance(name, Identifier):
5734        identifier = maybe_copy(name, copy)
5735    elif isinstance(name, str):
5736        identifier = Identifier(
5737            this=name,
5738            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
5739        )
5740    else:
5741        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
5742    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 a passed in Identefier node.
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:
5748def to_interval(interval: str | Literal) -> Interval:
5749    """Builds an interval expression from a string like '1 day' or '5 months'."""
5750    if isinstance(interval, Literal):
5751        if not interval.is_string:
5752            raise ValueError("Invalid interval string.")
5753
5754        interval = interval.this
5755
5756    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
5757
5758    if not interval_parts:
5759        raise ValueError("Invalid interval string.")
5760
5761    return Interval(
5762        this=Literal.string(interval_parts.group(1)),
5763        unit=Var(this=interval_parts.group(2)),
5764    )

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, **kwargs) -> Optional[Table]:
5777def to_table(
5778    sql_path: t.Optional[str | Table], dialect: DialectType = None, **kwargs
5779) -> t.Optional[Table]:
5780    """
5781    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
5782    If a table is passed in then that table is returned.
5783
5784    Args:
5785        sql_path: a `[catalog].[schema].[table]` string.
5786        dialect: the source dialect according to which the table name will be parsed.
5787        kwargs: the kwargs to instantiate the resulting `Table` expression with.
5788
5789    Returns:
5790        A table expression.
5791    """
5792    if sql_path is None or isinstance(sql_path, Table):
5793        return sql_path
5794    if not isinstance(sql_path, str):
5795        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
5796
5797    table = maybe_parse(sql_path, into=Table, dialect=dialect)
5798    if table:
5799        for k, v in kwargs.items():
5800            table.set(k, v)
5801
5802    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.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, **kwargs) -> Column:
5805def to_column(sql_path: str | Column, **kwargs) -> Column:
5806    """
5807    Create a column from a `[table].[column]` sql path. Schema is optional.
5808
5809    If a column is passed in then that column is returned.
5810
5811    Args:
5812        sql_path: `[table].[column]` string
5813    Returns:
5814        Table: A column expression
5815    """
5816    if sql_path is None or isinstance(sql_path, Column):
5817        return sql_path
5818    if not isinstance(sql_path, str):
5819        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
5820    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):
5823def alias_(
5824    expression: ExpOrStr,
5825    alias: str | Identifier,
5826    table: bool | t.Sequence[str | Identifier] = False,
5827    quoted: t.Optional[bool] = None,
5828    dialect: DialectType = None,
5829    copy: bool = True,
5830    **opts,
5831):
5832    """Create an Alias expression.
5833
5834    Example:
5835        >>> alias_('foo', 'bar').sql()
5836        'foo AS bar'
5837
5838        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
5839        '(SELECT 1, 2) AS bar(a, b)'
5840
5841    Args:
5842        expression: the SQL code strings to parse.
5843            If an Expression instance is passed, this is used as-is.
5844        alias: the alias name to use. If the name has
5845            special characters it is quoted.
5846        table: Whether or not to create a table alias, can also be a list of columns.
5847        quoted: whether or not to quote the alias
5848        dialect: the dialect used to parse the input expression.
5849        copy: Whether or not to copy the expression.
5850        **opts: other options to use to parse the input expressions.
5851
5852    Returns:
5853        Alias: the aliased expression
5854    """
5855    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5856    alias = to_identifier(alias, quoted=quoted)
5857
5858    if table:
5859        table_alias = TableAlias(this=alias)
5860        exp.set("alias", table_alias)
5861
5862        if not isinstance(table, bool):
5863            for column in table:
5864                table_alias.append("columns", to_identifier(column, quoted=quoted))
5865
5866        return exp
5867
5868    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
5869    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
5870    # for the complete Window expression.
5871    #
5872    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
5873
5874    if "alias" in exp.arg_types and not isinstance(exp, Window):
5875        exp.set("alias", alias)
5876        return exp
5877    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:
5880def subquery(
5881    expression: ExpOrStr,
5882    alias: t.Optional[Identifier | str] = None,
5883    dialect: DialectType = None,
5884    **opts,
5885) -> Select:
5886    """
5887    Build a subquery expression.
5888
5889    Example:
5890        >>> subquery('select x from tbl', 'bar').select('x').sql()
5891        'SELECT x FROM (SELECT x FROM tbl) AS bar'
5892
5893    Args:
5894        expression: the SQL code strings to parse.
5895            If an Expression instance is passed, this is used as-is.
5896        alias: the alias name to use.
5897        dialect: the dialect used to parse the input expression.
5898        **opts: other options to use to parse the input expressions.
5899
5900    Returns:
5901        A new Select instance with the subquery expression included.
5902    """
5903
5904    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
5905    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: str | Identifier, table: Union[Identifier, str, NoneType] = None, db: Union[Identifier, str, NoneType] = None, catalog: Union[Identifier, str, NoneType] = None, quoted: Optional[bool] = None) -> Column:
5908def column(
5909    col: str | Identifier,
5910    table: t.Optional[str | Identifier] = None,
5911    db: t.Optional[str | Identifier] = None,
5912    catalog: t.Optional[str | Identifier] = None,
5913    quoted: t.Optional[bool] = None,
5914) -> Column:
5915    """
5916    Build a Column.
5917
5918    Args:
5919        col: Column name.
5920        table: Table name.
5921        db: Database name.
5922        catalog: Catalog name.
5923        quoted: Whether to force quotes on the column's identifiers.
5924
5925    Returns:
5926        The new Column instance.
5927    """
5928    return Column(
5929        this=to_identifier(col, quoted=quoted),
5930        table=to_identifier(table, quoted=quoted),
5931        db=to_identifier(db, quoted=quoted),
5932        catalog=to_identifier(catalog, quoted=quoted),
5933    )

Build a Column.

Arguments:
  • col: Column name.
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • quoted: Whether to force quotes on the column's identifiers.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: str | DataType | DataType.Type, **opts) -> Cast:
5936def cast(expression: ExpOrStr, to: str | DataType | DataType.Type, **opts) -> Cast:
5937    """Cast an expression to a data type.
5938
5939    Example:
5940        >>> cast('x + 1', 'int').sql()
5941        'CAST(x + 1 AS INT)'
5942
5943    Args:
5944        expression: The expression to cast.
5945        to: The datatype to cast to.
5946
5947    Returns:
5948        The new Cast instance.
5949    """
5950    expression = maybe_parse(expression, **opts)
5951    data_type = DataType.build(to, **opts)
5952    expression = Cast(this=expression, to=data_type)
5953    expression.type = data_type
5954    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:
5957def table_(
5958    table: Identifier | str,
5959    db: t.Optional[Identifier | str] = None,
5960    catalog: t.Optional[Identifier | str] = None,
5961    quoted: t.Optional[bool] = None,
5962    alias: t.Optional[Identifier | str] = None,
5963) -> Table:
5964    """Build a Table.
5965
5966    Args:
5967        table: Table name.
5968        db: Database name.
5969        catalog: Catalog name.
5970        quote: Whether to force quotes on the table's identifiers.
5971        alias: Table's alias.
5972
5973    Returns:
5974        The new Table instance.
5975    """
5976    return Table(
5977        this=to_identifier(table, quoted=quoted) if table else None,
5978        db=to_identifier(db, quoted=quoted) if db else None,
5979        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
5980        alias=TableAlias(this=to_identifier(alias)) if alias else None,
5981    )

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:
5984def values(
5985    values: t.Iterable[t.Tuple[t.Any, ...]],
5986    alias: t.Optional[str] = None,
5987    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
5988) -> Values:
5989    """Build VALUES statement.
5990
5991    Example:
5992        >>> values([(1, '2')]).sql()
5993        "VALUES (1, '2')"
5994
5995    Args:
5996        values: values statements that will be converted to SQL
5997        alias: optional alias
5998        columns: Optional list of ordered column names or ordered dictionary of column names to types.
5999         If either are provided then an alias is also required.
6000
6001    Returns:
6002        Values: the Values expression object
6003    """
6004    if columns and not alias:
6005        raise ValueError("Alias is required when providing columns")
6006
6007    return Values(
6008        expressions=[convert(tup) for tup in values],
6009        alias=(
6010            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6011            if columns
6012            else (TableAlias(this=to_identifier(alias)) if alias else None)
6013        ),
6014    )

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:
6017def var(name: t.Optional[ExpOrStr]) -> Var:
6018    """Build a SQL variable.
6019
6020    Example:
6021        >>> repr(var('x'))
6022        '(VAR this: x)'
6023
6024        >>> repr(var(column('x', table='y')))
6025        '(VAR this: x)'
6026
6027    Args:
6028        name: The name of the var or an expression who's name will become the var.
6029
6030    Returns:
6031        The new variable node.
6032    """
6033    if not name:
6034        raise ValueError("Cannot convert empty name into var.")
6035
6036    if isinstance(name, Expression):
6037        name = name.name
6038    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:
6041def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6042    """Build ALTER TABLE... RENAME... expression
6043
6044    Args:
6045        old_name: The old name of the table
6046        new_name: The new name of the table
6047
6048    Returns:
6049        Alter table expression
6050    """
6051    old_table = to_table(old_name)
6052    new_table = to_table(new_name)
6053    return AlterTable(
6054        this=old_table,
6055        actions=[
6056            RenameTable(this=new_table),
6057        ],
6058    )

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 convert(value: Any, copy: bool = False) -> Expression:
6061def convert(value: t.Any, copy: bool = False) -> Expression:
6062    """Convert a python value into an expression object.
6063
6064    Raises an error if a conversion is not possible.
6065
6066    Args:
6067        value: A python object.
6068        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6069
6070    Returns:
6071        Expression: the equivalent expression object.
6072    """
6073    if isinstance(value, Expression):
6074        return maybe_copy(value, copy)
6075    if isinstance(value, str):
6076        return Literal.string(value)
6077    if isinstance(value, bool):
6078        return Boolean(this=value)
6079    if value is None or (isinstance(value, float) and math.isnan(value)):
6080        return NULL
6081    if isinstance(value, numbers.Number):
6082        return Literal.number(value)
6083    if isinstance(value, datetime.datetime):
6084        datetime_literal = Literal.string(
6085            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6086        )
6087        return TimeStrToTime(this=datetime_literal)
6088    if isinstance(value, datetime.date):
6089        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6090        return DateStrToDate(this=date_literal)
6091    if isinstance(value, tuple):
6092        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6093    if isinstance(value, list):
6094        return Array(expressions=[convert(v, copy=copy) for v in value])
6095    if isinstance(value, dict):
6096        return Map(
6097            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6098            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6099        )
6100    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:
6103def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6104    """
6105    Replace children of an expression with the result of a lambda fun(child) -> exp.
6106    """
6107    for k, v in expression.args.items():
6108        is_list_arg = type(v) is list
6109
6110        child_nodes = v if is_list_arg else [v]
6111        new_child_nodes = []
6112
6113        for cn in child_nodes:
6114            if isinstance(cn, Expression):
6115                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6116                    new_child_nodes.append(child_node)
6117                    child_node.parent = expression
6118                    child_node.arg_key = k
6119            else:
6120                new_child_nodes.append(cn)
6121
6122        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]:
6125def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6126    """
6127    Return all table names referenced through columns in an expression.
6128
6129    Example:
6130        >>> import sqlglot
6131        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6132        ['a', 'c']
6133
6134    Args:
6135        expression: expression to find table names.
6136        exclude: a table name to exclude
6137
6138    Returns:
6139        A list of unique names.
6140    """
6141    return {
6142        table
6143        for table in (column.table for column in expression.find_all(Column))
6144        if table and table != exclude
6145    }

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) -> str:
6148def table_name(table: Table | str, dialect: DialectType = None) -> str:
6149    """Get the full name of a table as a string.
6150
6151    Args:
6152        table: Table expression node or string.
6153        dialect: The dialect to generate the table name for.
6154
6155    Examples:
6156        >>> from sqlglot import exp, parse_one
6157        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6158        'a.b.c'
6159
6160    Returns:
6161        The table name.
6162    """
6163
6164    table = maybe_parse(table, into=Table)
6165
6166    if not table:
6167        raise ValueError(f"Cannot parse {table}")
6168
6169    return ".".join(
6170        part.sql(dialect=dialect, identify=True)
6171        if not SAFE_IDENTIFIER_RE.match(part.name)
6172        else part.name
6173        for part in table.parts
6174    )

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.
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 replace_tables(expression: ~E, mapping: Dict[str, str], copy: bool = True) -> ~E:
6177def replace_tables(expression: E, mapping: t.Dict[str, str], copy: bool = True) -> E:
6178    """Replace all tables in expression according to the mapping.
6179
6180    Args:
6181        expression: expression node to be transformed and replaced.
6182        mapping: mapping of table names.
6183        copy: whether or not to copy the expression.
6184
6185    Examples:
6186        >>> from sqlglot import exp, parse_one
6187        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6188        'SELECT * FROM c'
6189
6190    Returns:
6191        The mapped expression.
6192    """
6193
6194    def _replace_tables(node: Expression) -> Expression:
6195        if isinstance(node, Table):
6196            new_name = mapping.get(table_name(node))
6197            if new_name:
6198                return to_table(
6199                    new_name,
6200                    **{k: v for k, v in node.args.items() if k not in ("this", "db", "catalog")},
6201                )
6202        return node
6203
6204    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.
  • 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'
Returns:

The mapped expression.

def replace_placeholders( expression: Expression, *args, **kwargs) -> Expression:
6207def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6208    """Replace placeholders in an expression.
6209
6210    Args:
6211        expression: expression node to be transformed and replaced.
6212        args: positional names that will substitute unnamed placeholders in the given order.
6213        kwargs: keyword arguments that will substitute named placeholders.
6214
6215    Examples:
6216        >>> from sqlglot import exp, parse_one
6217        >>> replace_placeholders(
6218        ...     parse_one("select * from :tbl where ? = ?"),
6219        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6220        ... ).sql()
6221        "SELECT * FROM foo WHERE str_col = 'b'"
6222
6223    Returns:
6224        The mapped expression.
6225    """
6226
6227    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6228        if isinstance(node, Placeholder):
6229            if node.name:
6230                new_name = kwargs.get(node.name)
6231                if new_name:
6232                    return convert(new_name)
6233            else:
6234                try:
6235                    return convert(next(args))
6236                except StopIteration:
6237                    pass
6238        return node
6239
6240    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], copy: bool = True) -> Expression:
6243def expand(
6244    expression: Expression, sources: t.Dict[str, Subqueryable], copy: bool = True
6245) -> Expression:
6246    """Transforms an expression by expanding all referenced sources into subqueries.
6247
6248    Examples:
6249        >>> from sqlglot import parse_one
6250        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6251        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6252
6253        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6254        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6255
6256    Args:
6257        expression: The expression to expand.
6258        sources: A dictionary of name to Subqueryables.
6259        copy: Whether or not to copy the expression during transformation. Defaults to True.
6260
6261    Returns:
6262        The transformed expression.
6263    """
6264
6265    def _expand(node: Expression):
6266        if isinstance(node, Table):
6267            name = table_name(node)
6268            source = sources.get(name)
6269            if source:
6270                subquery = source.subquery(node.alias or name)
6271                subquery.comments = [f"source: {name}"]
6272                return subquery.transform(_expand, copy=False)
6273        return node
6274
6275    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.
  • copy: Whether or not to copy the expression during transformation. Defaults to True.
Returns:

The transformed expression.

def func( name: str, *args, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Func:
6278def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func:
6279    """
6280    Returns a Func expression.
6281
6282    Examples:
6283        >>> func("abs", 5).sql()
6284        'ABS(5)'
6285
6286        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6287        'CAST(5 AS DOUBLE)'
6288
6289    Args:
6290        name: the name of the function to build.
6291        args: the args used to instantiate the function of interest.
6292        dialect: the source dialect.
6293        kwargs: the kwargs used to instantiate the function of interest.
6294
6295    Note:
6296        The arguments `args` and `kwargs` are mutually exclusive.
6297
6298    Returns:
6299        An instance of the function of interest, or an anonymous function, if `name` doesn't
6300        correspond to an existing `sqlglot.expressions.Func` class.
6301    """
6302    if args and kwargs:
6303        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6304
6305    from sqlglot.dialects.dialect import Dialect
6306
6307    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args]
6308    kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()}
6309
6310    parser = Dialect.get_or_raise(dialect)().parser()
6311    from_args_list = parser.FUNCTIONS.get(name.upper())
6312
6313    if from_args_list:
6314        function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs)  # type: ignore
6315    else:
6316        kwargs = kwargs or {"expressions": converted}
6317        function = Anonymous(this=name, **kwargs)
6318
6319    for error_message in function.error_messages(converted):
6320        raise ValueError(error_message)
6321
6322    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.
  • 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 true() -> Boolean:
6325def true() -> Boolean:
6326    """
6327    Returns a true Boolean expression.
6328    """
6329    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
6332def false() -> Boolean:
6333    """
6334    Returns a false Boolean expression.
6335    """
6336    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6339def null() -> Null:
6340    """
6341    Returns a Null expression.
6342    """
6343    return Null()

Returns a Null expression.

TRUE = (BOOLEAN this: True)
FALSE = (BOOLEAN this: False)
NULL = (NULL )