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

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1195class ColumnPosition(Expression):
1196    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1199class ColumnDef(Expression):
1200    arg_types = {
1201        "this": True,
1202        "kind": False,
1203        "constraints": False,
1204        "exists": False,
1205        "position": False,
1206    }
1207
1208    @property
1209    def constraints(self) -> t.List[ColumnConstraint]:
1210        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):
1213class AlterColumn(Expression):
1214    arg_types = {
1215        "this": True,
1216        "dtype": False,
1217        "collate": False,
1218        "using": False,
1219        "default": False,
1220        "drop": False,
1221    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False}
key = 'altercolumn'
class RenameTable(Expression):
1224class RenameTable(Expression):
1225    pass
key = 'renametable'
class Comment(Expression):
1228class Comment(Expression):
1229    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):
1232class Comprehension(Expression):
1233    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):
1237class MergeTreeTTLAction(Expression):
1238    arg_types = {
1239        "this": True,
1240        "delete": False,
1241        "recompress": False,
1242        "to_disk": False,
1243        "to_volume": False,
1244    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1248class MergeTreeTTL(Expression):
1249    arg_types = {
1250        "expressions": True,
1251        "where": False,
1252        "group": False,
1253        "aggregates": False,
1254    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1258class IndexConstraintOption(Expression):
1259    arg_types = {
1260        "key_block_size": False,
1261        "using": False,
1262        "parser": False,
1263        "comment": False,
1264        "visible": False,
1265        "engine_attr": False,
1266        "secondary_engine_attr": False,
1267    }
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):
1270class ColumnConstraint(Expression):
1271    arg_types = {"this": False, "kind": True}
1272
1273    @property
1274    def kind(self) -> ColumnConstraintKind:
1275        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1278class ColumnConstraintKind(Expression):
1279    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1282class AutoIncrementColumnConstraint(ColumnConstraintKind):
1283    pass
key = 'autoincrementcolumnconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1286class CaseSpecificColumnConstraint(ColumnConstraintKind):
1287    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1290class CharacterSetColumnConstraint(ColumnConstraintKind):
1291    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1294class CheckColumnConstraint(ColumnConstraintKind):
1295    pass
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1298class ClusteredColumnConstraint(ColumnConstraintKind):
1299    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1302class CollateColumnConstraint(ColumnConstraintKind):
1303    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1306class CommentColumnConstraint(ColumnConstraintKind):
1307    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1310class CompressColumnConstraint(ColumnConstraintKind):
1311    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1314class DateFormatColumnConstraint(ColumnConstraintKind):
1315    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1318class DefaultColumnConstraint(ColumnConstraintKind):
1319    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1322class EncodeColumnConstraint(ColumnConstraintKind):
1323    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1326class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1327    # this: True -> ALWAYS, this: False -> BY DEFAULT
1328    arg_types = {
1329        "this": False,
1330        "expression": False,
1331        "on_null": False,
1332        "start": False,
1333        "increment": False,
1334        "minvalue": False,
1335        "maxvalue": False,
1336        "cycle": False,
1337    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1341class IndexColumnConstraint(ColumnConstraintKind):
1342    arg_types = {
1343        "this": False,
1344        "schema": True,
1345        "kind": False,
1346        "index_type": False,
1347        "options": False,
1348    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1351class InlineLengthColumnConstraint(ColumnConstraintKind):
1352    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1355class NonClusteredColumnConstraint(ColumnConstraintKind):
1356    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1359class NotForReplicationColumnConstraint(ColumnConstraintKind):
1360    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1363class NotNullColumnConstraint(ColumnConstraintKind):
1364    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1368class OnUpdateColumnConstraint(ColumnConstraintKind):
1369    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1372class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1373    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1376class TitleColumnConstraint(ColumnConstraintKind):
1377    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1380class UniqueColumnConstraint(ColumnConstraintKind):
1381    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1384class UppercaseColumnConstraint(ColumnConstraintKind):
1385    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1388class PathColumnConstraint(ColumnConstraintKind):
1389    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1394class ComputedColumnConstraint(ColumnConstraintKind):
1395    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1398class Constraint(Expression):
1399    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(Expression):
1402class Delete(Expression):
1403    arg_types = {
1404        "with": False,
1405        "this": False,
1406        "using": False,
1407        "where": False,
1408        "returning": False,
1409        "limit": False,
1410        "tables": False,  # Multiple-Table Syntax (MySQL)
1411    }
1412
1413    def delete(
1414        self,
1415        table: ExpOrStr,
1416        dialect: DialectType = None,
1417        copy: bool = True,
1418        **opts,
1419    ) -> Delete:
1420        """
1421        Create a DELETE expression or replace the table on an existing DELETE expression.
1422
1423        Example:
1424            >>> delete("tbl").sql()
1425            'DELETE FROM tbl'
1426
1427        Args:
1428            table: the table from which to delete.
1429            dialect: the dialect used to parse the input expression.
1430            copy: if `False`, modify this expression instance in-place.
1431            opts: other options to use to parse the input expressions.
1432
1433        Returns:
1434            Delete: the modified expression.
1435        """
1436        return _apply_builder(
1437            expression=table,
1438            instance=self,
1439            arg="this",
1440            dialect=dialect,
1441            into=Table,
1442            copy=copy,
1443            **opts,
1444        )
1445
1446    def where(
1447        self,
1448        *expressions: t.Optional[ExpOrStr],
1449        append: bool = True,
1450        dialect: DialectType = None,
1451        copy: bool = True,
1452        **opts,
1453    ) -> Delete:
1454        """
1455        Append to or set the WHERE expressions.
1456
1457        Example:
1458            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1459            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1460
1461        Args:
1462            *expressions: the SQL code strings to parse.
1463                If an `Expression` instance is passed, it will be used as-is.
1464                Multiple expressions are combined with an AND operator.
1465            append: if `True`, AND the new expressions to any existing expression.
1466                Otherwise, this resets the expression.
1467            dialect: the dialect used to parse the input expressions.
1468            copy: if `False`, modify this expression instance in-place.
1469            opts: other options to use to parse the input expressions.
1470
1471        Returns:
1472            Delete: the modified expression.
1473        """
1474        return _apply_conjunction_builder(
1475            *expressions,
1476            instance=self,
1477            arg="where",
1478            append=append,
1479            into=Where,
1480            dialect=dialect,
1481            copy=copy,
1482            **opts,
1483        )
1484
1485    def returning(
1486        self,
1487        expression: ExpOrStr,
1488        dialect: DialectType = None,
1489        copy: bool = True,
1490        **opts,
1491    ) -> Delete:
1492        """
1493        Set the RETURNING expression. Not supported by all dialects.
1494
1495        Example:
1496            >>> delete("tbl").returning("*", dialect="postgres").sql()
1497            'DELETE FROM tbl RETURNING *'
1498
1499        Args:
1500            expression: the SQL code strings to parse.
1501                If an `Expression` instance is passed, it will be used as-is.
1502            dialect: the dialect used to parse the input expressions.
1503            copy: if `False`, modify this expression instance in-place.
1504            opts: other options to use to parse the input expressions.
1505
1506        Returns:
1507            Delete: the modified expression.
1508        """
1509        return _apply_builder(
1510            expression=expression,
1511            instance=self,
1512            arg="returning",
1513            prefix="RETURNING",
1514            dialect=dialect,
1515            copy=copy,
1516            into=Returning,
1517            **opts,
1518        )
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:
1413    def delete(
1414        self,
1415        table: ExpOrStr,
1416        dialect: DialectType = None,
1417        copy: bool = True,
1418        **opts,
1419    ) -> Delete:
1420        """
1421        Create a DELETE expression or replace the table on an existing DELETE expression.
1422
1423        Example:
1424            >>> delete("tbl").sql()
1425            'DELETE FROM tbl'
1426
1427        Args:
1428            table: the table from which to delete.
1429            dialect: the dialect used to parse the input expression.
1430            copy: if `False`, modify this expression instance in-place.
1431            opts: other options to use to parse the input expressions.
1432
1433        Returns:
1434            Delete: the modified expression.
1435        """
1436        return _apply_builder(
1437            expression=table,
1438            instance=self,
1439            arg="this",
1440            dialect=dialect,
1441            into=Table,
1442            copy=copy,
1443            **opts,
1444        )

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

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

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):
1521class Drop(Expression):
1522    arg_types = {
1523        "this": False,
1524        "kind": False,
1525        "exists": False,
1526        "temporary": False,
1527        "materialized": False,
1528        "cascade": False,
1529        "constraints": False,
1530        "purge": False,
1531    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1534class Filter(Expression):
1535    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1538class Check(Expression):
1539    pass
key = 'check'
class Connect(Expression):
1543class Connect(Expression):
1544    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1547class Prior(Expression):
1548    pass
key = 'prior'
class Directory(Expression):
1551class Directory(Expression):
1552    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1553    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1556class ForeignKey(Expression):
1557    arg_types = {
1558        "expressions": True,
1559        "reference": False,
1560        "delete": False,
1561        "update": False,
1562    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1565class ColumnPrefix(Expression):
1566    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1569class PrimaryKey(Expression):
1570    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1575class Into(Expression):
1576    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1579class From(Expression):
1580    @property
1581    def name(self) -> str:
1582        return self.this.name
1583
1584    @property
1585    def alias_or_name(self) -> str:
1586        return self.this.alias_or_name
name: str
alias_or_name: str
key = 'from'
class Having(Expression):
1589class Having(Expression):
1590    pass
key = 'having'
class Hint(Expression):
1593class Hint(Expression):
1594    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1597class JoinHint(Expression):
1598    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1601class Identifier(Expression):
1602    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1603
1604    @property
1605    def quoted(self) -> bool:
1606        return bool(self.args.get("quoted"))
1607
1608    @property
1609    def hashable_args(self) -> t.Any:
1610        return (self.this, self.quoted)
1611
1612    @property
1613    def output_name(self) -> str:
1614        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 Opclass(Expression):
1618class Opclass(Expression):
1619    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1622class Index(Expression):
1623    arg_types = {
1624        "this": False,
1625        "table": False,
1626        "using": False,
1627        "where": False,
1628        "columns": False,
1629        "unique": False,
1630        "primary": False,
1631        "amp": False,  # teradata
1632        "partition_by": False,  # teradata
1633        "where": False,  # postgres partial indexes
1634    }
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):
1637class Insert(DDL):
1638    arg_types = {
1639        "with": False,
1640        "this": True,
1641        "expression": False,
1642        "conflict": False,
1643        "returning": False,
1644        "overwrite": False,
1645        "exists": False,
1646        "partition": False,
1647        "alternative": False,
1648        "where": False,
1649        "ignore": False,
1650        "by_name": False,
1651    }
1652
1653    def with_(
1654        self,
1655        alias: ExpOrStr,
1656        as_: ExpOrStr,
1657        recursive: t.Optional[bool] = None,
1658        append: bool = True,
1659        dialect: DialectType = None,
1660        copy: bool = True,
1661        **opts,
1662    ) -> Insert:
1663        """
1664        Append to or set the common table expressions.
1665
1666        Example:
1667            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1668            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1669
1670        Args:
1671            alias: the SQL code string to parse as the table name.
1672                If an `Expression` instance is passed, this is used as-is.
1673            as_: the SQL code string to parse as the table expression.
1674                If an `Expression` instance is passed, it will be used as-is.
1675            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1676            append: if `True`, add to any existing expressions.
1677                Otherwise, this resets the expressions.
1678            dialect: the dialect used to parse the input expression.
1679            copy: if `False`, modify this expression instance in-place.
1680            opts: other options to use to parse the input expressions.
1681
1682        Returns:
1683            The modified expression.
1684        """
1685        return _apply_cte_builder(
1686            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1687        )
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:
1653    def with_(
1654        self,
1655        alias: ExpOrStr,
1656        as_: ExpOrStr,
1657        recursive: t.Optional[bool] = None,
1658        append: bool = True,
1659        dialect: DialectType = None,
1660        copy: bool = True,
1661        **opts,
1662    ) -> Insert:
1663        """
1664        Append to or set the common table expressions.
1665
1666        Example:
1667            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1668            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1669
1670        Args:
1671            alias: the SQL code string to parse as the table name.
1672                If an `Expression` instance is passed, this is used as-is.
1673            as_: the SQL code string to parse as the table expression.
1674                If an `Expression` instance is passed, it will be used as-is.
1675            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1676            append: if `True`, add to any existing expressions.
1677                Otherwise, this resets the expressions.
1678            dialect: the dialect used to parse the input expression.
1679            copy: if `False`, modify this expression instance in-place.
1680            opts: other options to use to parse the input expressions.
1681
1682        Returns:
1683            The modified expression.
1684        """
1685        return _apply_cte_builder(
1686            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1687        )

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

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):
2431class WithTableHint(Expression):
2432    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2436class IndexTableHint(Expression):
2437    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class Table(Expression):
2440class Table(Expression):
2441    arg_types = {
2442        "this": True,
2443        "alias": False,
2444        "db": False,
2445        "catalog": False,
2446        "laterals": False,
2447        "joins": False,
2448        "pivots": False,
2449        "hints": False,
2450        "system_time": False,
2451        "version": False,
2452    }
2453
2454    @property
2455    def name(self) -> str:
2456        if isinstance(self.this, Func):
2457            return ""
2458        return self.this.name
2459
2460    @property
2461    def db(self) -> str:
2462        return self.text("db")
2463
2464    @property
2465    def catalog(self) -> str:
2466        return self.text("catalog")
2467
2468    @property
2469    def selects(self) -> t.List[Expression]:
2470        return []
2471
2472    @property
2473    def named_selects(self) -> t.List[str]:
2474        return []
2475
2476    @property
2477    def parts(self) -> t.List[Identifier]:
2478        """Return the parts of a table in order catalog, db, table."""
2479        parts: t.List[Identifier] = []
2480
2481        for arg in ("catalog", "db", "this"):
2482            part = self.args.get(arg)
2483
2484            if isinstance(part, Identifier):
2485                parts.append(part)
2486            elif isinstance(part, Dot):
2487                parts.extend(part.flatten())
2488
2489        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):
2492class Union(Subqueryable):
2493    arg_types = {
2494        "with": False,
2495        "this": True,
2496        "expression": True,
2497        "distinct": False,
2498        "by_name": False,
2499        **QUERY_MODIFIERS,
2500    }
2501
2502    def limit(
2503        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2504    ) -> Select:
2505        """
2506        Set the LIMIT expression.
2507
2508        Example:
2509            >>> select("1").union(select("1")).limit(1).sql()
2510            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2511
2512        Args:
2513            expression: the SQL code string to parse.
2514                This can also be an integer.
2515                If a `Limit` instance is passed, this is used as-is.
2516                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2517            dialect: the dialect used to parse the input expression.
2518            copy: if `False`, modify this expression instance in-place.
2519            opts: other options to use to parse the input expressions.
2520
2521        Returns:
2522            The limited subqueryable.
2523        """
2524        return (
2525            select("*")
2526            .from_(self.subquery(alias="_l_0", copy=copy))
2527            .limit(expression, dialect=dialect, copy=False, **opts)
2528        )
2529
2530    def select(
2531        self,
2532        *expressions: t.Optional[ExpOrStr],
2533        append: bool = True,
2534        dialect: DialectType = None,
2535        copy: bool = True,
2536        **opts,
2537    ) -> Union:
2538        """Append to or set the SELECT of the union recursively.
2539
2540        Example:
2541            >>> from sqlglot import parse_one
2542            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2543            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2544
2545        Args:
2546            *expressions: the SQL code strings to parse.
2547                If an `Expression` instance is passed, it will be used as-is.
2548            append: if `True`, add to any existing expressions.
2549                Otherwise, this resets the expressions.
2550            dialect: the dialect used to parse the input expressions.
2551            copy: if `False`, modify this expression instance in-place.
2552            opts: other options to use to parse the input expressions.
2553
2554        Returns:
2555            Union: the modified expression.
2556        """
2557        this = self.copy() if copy else self
2558        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2559        this.expression.unnest().select(
2560            *expressions, append=append, dialect=dialect, copy=False, **opts
2561        )
2562        return this
2563
2564    @property
2565    def named_selects(self) -> t.List[str]:
2566        return self.this.unnest().named_selects
2567
2568    @property
2569    def is_star(self) -> bool:
2570        return self.this.is_star or self.expression.is_star
2571
2572    @property
2573    def selects(self) -> t.List[Expression]:
2574        return self.this.unnest().selects
2575
2576    @property
2577    def left(self):
2578        return self.this
2579
2580    @property
2581    def right(self):
2582        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:
2502    def limit(
2503        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2504    ) -> Select:
2505        """
2506        Set the LIMIT expression.
2507
2508        Example:
2509            >>> select("1").union(select("1")).limit(1).sql()
2510            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2511
2512        Args:
2513            expression: the SQL code string to parse.
2514                This can also be an integer.
2515                If a `Limit` instance is passed, this is used as-is.
2516                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2517            dialect: the dialect used to parse the input expression.
2518            copy: if `False`, modify this expression instance in-place.
2519            opts: other options to use to parse the input expressions.
2520
2521        Returns:
2522            The limited subqueryable.
2523        """
2524        return (
2525            select("*")
2526            .from_(self.subquery(alias="_l_0", copy=copy))
2527            .limit(expression, dialect=dialect, copy=False, **opts)
2528        )

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

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

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

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

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

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

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

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

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

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

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

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

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

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:
3283    def lock(self, update: bool = True, copy: bool = True) -> Select:
3284        """
3285        Set the locking read mode for this expression.
3286
3287        Examples:
3288            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3289            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3290
3291            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3292            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3293
3294        Args:
3295            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3296            copy: if `False`, modify this expression instance in-place.
3297
3298        Returns:
3299            The modified expression.
3300        """
3301        inst = maybe_copy(self, copy)
3302        inst.set("locks", [Lock(update=update)])
3303
3304        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:
3306    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3307        """
3308        Set hints for this expression.
3309
3310        Examples:
3311            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3312            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3313
3314        Args:
3315            hints: The SQL code strings to parse as the hints.
3316                If an `Expression` instance is passed, it will be used as-is.
3317            dialect: The dialect used to parse the hints.
3318            copy: If `False`, modify this expression instance in-place.
3319
3320        Returns:
3321            The modified expression.
3322        """
3323        inst = maybe_copy(self, copy)
3324        inst.set(
3325            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3326        )
3327
3328        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):
3343class Subquery(DerivedTable, Unionable):
3344    arg_types = {
3345        "this": True,
3346        "alias": False,
3347        "with": False,
3348        **QUERY_MODIFIERS,
3349    }
3350
3351    def unnest(self):
3352        """
3353        Returns the first non subquery.
3354        """
3355        expression = self
3356        while isinstance(expression, Subquery):
3357            expression = expression.this
3358        return expression
3359
3360    def unwrap(self) -> Subquery:
3361        expression = self
3362        while expression.same_parent and expression.is_wrapper:
3363            expression = t.cast(Subquery, expression.parent)
3364        return expression
3365
3366    @property
3367    def is_wrapper(self) -> bool:
3368        """
3369        Whether this Subquery acts as a simple wrapper around another expression.
3370
3371        SELECT * FROM (((SELECT * FROM t)))
3372                      ^
3373                      This corresponds to a "wrapper" Subquery node
3374        """
3375        return all(v is None for k, v in self.args.items() if k != "this")
3376
3377    @property
3378    def is_star(self) -> bool:
3379        return self.this.is_star
3380
3381    @property
3382    def output_name(self) -> str:
3383        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):
3351    def unnest(self):
3352        """
3353        Returns the first non subquery.
3354        """
3355        expression = self
3356        while isinstance(expression, Subquery):
3357            expression = expression.this
3358        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3360    def unwrap(self) -> Subquery:
3361        expression = self
3362        while expression.same_parent and expression.is_wrapper:
3363            expression = t.cast(Subquery, expression.parent)
3364        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):
3386class TableSample(Expression):
3387    arg_types = {
3388        "this": False,
3389        "expressions": False,
3390        "method": False,
3391        "bucket_numerator": False,
3392        "bucket_denominator": False,
3393        "bucket_field": False,
3394        "percent": False,
3395        "rows": False,
3396        "size": False,
3397        "seed": False,
3398        "kind": False,
3399    }
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):
3402class Tag(Expression):
3403    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3404
3405    arg_types = {
3406        "this": False,
3407        "prefix": False,
3408        "postfix": False,
3409    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3414class Pivot(Expression):
3415    arg_types = {
3416        "this": False,
3417        "alias": False,
3418        "expressions": True,
3419        "field": False,
3420        "unpivot": False,
3421        "using": False,
3422        "group": False,
3423        "columns": False,
3424        "include_nulls": False,
3425    }
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):
3428class Window(Condition):
3429    arg_types = {
3430        "this": True,
3431        "partition_by": False,
3432        "order": False,
3433        "spec": False,
3434        "alias": False,
3435        "over": False,
3436        "first": False,
3437    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3440class WindowSpec(Expression):
3441    arg_types = {
3442        "kind": False,
3443        "start": False,
3444        "start_side": False,
3445        "end": False,
3446        "end_side": False,
3447    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3450class Where(Expression):
3451    pass
key = 'where'
class Star(Expression):
3454class Star(Expression):
3455    arg_types = {"except": False, "replace": False}
3456
3457    @property
3458    def name(self) -> str:
3459        return "*"
3460
3461    @property
3462    def output_name(self) -> str:
3463        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):
3466class Parameter(Condition):
3467    arg_types = {"this": True, "wrapped": False}
arg_types = {'this': True, 'wrapped': False}
key = 'parameter'
class SessionParameter(Condition):
3470class SessionParameter(Condition):
3471    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3474class Placeholder(Condition):
3475    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3478class Null(Condition):
3479    arg_types: t.Dict[str, t.Any] = {}
3480
3481    @property
3482    def name(self) -> str:
3483        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
key = 'null'
class Boolean(Condition):
3486class Boolean(Condition):
3487    pass
key = 'boolean'
class DataTypeParam(Expression):
3490class DataTypeParam(Expression):
3491    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3494class DataType(Expression):
3495    arg_types = {
3496        "this": True,
3497        "expressions": False,
3498        "nested": False,
3499        "values": False,
3500        "prefix": False,
3501        "kind": False,
3502    }
3503
3504    class Type(AutoName):
3505        ARRAY = auto()
3506        BIGDECIMAL = auto()
3507        BIGINT = auto()
3508        BIGSERIAL = auto()
3509        BINARY = auto()
3510        BIT = auto()
3511        BOOLEAN = auto()
3512        CHAR = auto()
3513        DATE = auto()
3514        DATEMULTIRANGE = auto()
3515        DATERANGE = auto()
3516        DATETIME = auto()
3517        DATETIME64 = auto()
3518        DECIMAL = auto()
3519        DOUBLE = auto()
3520        ENUM = auto()
3521        ENUM8 = auto()
3522        ENUM16 = auto()
3523        FIXEDSTRING = auto()
3524        FLOAT = auto()
3525        GEOGRAPHY = auto()
3526        GEOMETRY = auto()
3527        HLLSKETCH = auto()
3528        HSTORE = auto()
3529        IMAGE = auto()
3530        INET = auto()
3531        INT = auto()
3532        INT128 = auto()
3533        INT256 = auto()
3534        INT4MULTIRANGE = auto()
3535        INT4RANGE = auto()
3536        INT8MULTIRANGE = auto()
3537        INT8RANGE = auto()
3538        INTERVAL = auto()
3539        IPADDRESS = auto()
3540        IPPREFIX = auto()
3541        JSON = auto()
3542        JSONB = auto()
3543        LONGBLOB = auto()
3544        LONGTEXT = auto()
3545        LOWCARDINALITY = auto()
3546        MAP = auto()
3547        MEDIUMBLOB = auto()
3548        MEDIUMINT = auto()
3549        MEDIUMTEXT = auto()
3550        MONEY = auto()
3551        NCHAR = auto()
3552        NESTED = auto()
3553        NULL = auto()
3554        NULLABLE = auto()
3555        NUMMULTIRANGE = auto()
3556        NUMRANGE = auto()
3557        NVARCHAR = auto()
3558        OBJECT = auto()
3559        ROWVERSION = auto()
3560        SERIAL = auto()
3561        SET = auto()
3562        SMALLINT = auto()
3563        SMALLMONEY = auto()
3564        SMALLSERIAL = auto()
3565        STRUCT = auto()
3566        SUPER = auto()
3567        TEXT = auto()
3568        TINYBLOB = auto()
3569        TINYTEXT = auto()
3570        TIME = auto()
3571        TIMETZ = auto()
3572        TIMESTAMP = auto()
3573        TIMESTAMPLTZ = auto()
3574        TIMESTAMPTZ = auto()
3575        TINYINT = auto()
3576        TSMULTIRANGE = auto()
3577        TSRANGE = auto()
3578        TSTZMULTIRANGE = auto()
3579        TSTZRANGE = auto()
3580        UBIGINT = auto()
3581        UINT = auto()
3582        UINT128 = auto()
3583        UINT256 = auto()
3584        UMEDIUMINT = auto()
3585        UDECIMAL = auto()
3586        UNIQUEIDENTIFIER = auto()
3587        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3588        USERDEFINED = "USER-DEFINED"
3589        USMALLINT = auto()
3590        UTINYINT = auto()
3591        UUID = auto()
3592        VARBINARY = auto()
3593        VARCHAR = auto()
3594        VARIANT = auto()
3595        XML = auto()
3596        YEAR = auto()
3597
3598    TEXT_TYPES = {
3599        Type.CHAR,
3600        Type.NCHAR,
3601        Type.VARCHAR,
3602        Type.NVARCHAR,
3603        Type.TEXT,
3604    }
3605
3606    INTEGER_TYPES = {
3607        Type.INT,
3608        Type.TINYINT,
3609        Type.SMALLINT,
3610        Type.BIGINT,
3611        Type.INT128,
3612        Type.INT256,
3613    }
3614
3615    FLOAT_TYPES = {
3616        Type.FLOAT,
3617        Type.DOUBLE,
3618    }
3619
3620    NUMERIC_TYPES = {
3621        *INTEGER_TYPES,
3622        *FLOAT_TYPES,
3623    }
3624
3625    TEMPORAL_TYPES = {
3626        Type.TIME,
3627        Type.TIMETZ,
3628        Type.TIMESTAMP,
3629        Type.TIMESTAMPTZ,
3630        Type.TIMESTAMPLTZ,
3631        Type.DATE,
3632        Type.DATETIME,
3633        Type.DATETIME64,
3634    }
3635
3636    @classmethod
3637    def build(
3638        cls,
3639        dtype: str | DataType | DataType.Type,
3640        dialect: DialectType = None,
3641        udt: bool = False,
3642        **kwargs,
3643    ) -> DataType:
3644        """
3645        Constructs a DataType object.
3646
3647        Args:
3648            dtype: the data type of interest.
3649            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3650            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3651                DataType, thus creating a user-defined type.
3652            kawrgs: additional arguments to pass in the constructor of DataType.
3653
3654        Returns:
3655            The constructed DataType object.
3656        """
3657        from sqlglot import parse_one
3658
3659        if isinstance(dtype, str):
3660            if dtype.upper() == "UNKNOWN":
3661                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3662
3663            try:
3664                data_type_exp = parse_one(dtype, read=dialect, into=DataType)
3665            except ParseError:
3666                if udt:
3667                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3668                raise
3669        elif isinstance(dtype, DataType.Type):
3670            data_type_exp = DataType(this=dtype)
3671        elif isinstance(dtype, DataType):
3672            return dtype
3673        else:
3674            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3675
3676        return DataType(**{**data_type_exp.args, **kwargs})
3677
3678    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
3679        """
3680        Checks whether this DataType matches one of the provided data types. Nested types or precision
3681        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3682
3683        Args:
3684            dtypes: the data types to compare this DataType to.
3685
3686        Returns:
3687            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3688        """
3689        for dtype in dtypes:
3690            other = DataType.build(dtype, udt=True)
3691
3692            if (
3693                other.expressions
3694                or self.this == DataType.Type.USERDEFINED
3695                or other.this == DataType.Type.USERDEFINED
3696            ):
3697                matches = self == other
3698            else:
3699                matches = self.this == other.this
3700
3701            if matches:
3702                return True
3703        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>}
INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT128: 'INT128'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>}
TEMPORAL_TYPES = {<Type.DATETIME: 'DATETIME'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIME: 'TIME'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}
@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:
3636    @classmethod
3637    def build(
3638        cls,
3639        dtype: str | DataType | DataType.Type,
3640        dialect: DialectType = None,
3641        udt: bool = False,
3642        **kwargs,
3643    ) -> DataType:
3644        """
3645        Constructs a DataType object.
3646
3647        Args:
3648            dtype: the data type of interest.
3649            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3650            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3651                DataType, thus creating a user-defined type.
3652            kawrgs: additional arguments to pass in the constructor of DataType.
3653
3654        Returns:
3655            The constructed DataType object.
3656        """
3657        from sqlglot import parse_one
3658
3659        if isinstance(dtype, str):
3660            if dtype.upper() == "UNKNOWN":
3661                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3662
3663            try:
3664                data_type_exp = parse_one(dtype, read=dialect, into=DataType)
3665            except ParseError:
3666                if udt:
3667                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3668                raise
3669        elif isinstance(dtype, DataType.Type):
3670            data_type_exp = DataType(this=dtype)
3671        elif isinstance(dtype, DataType):
3672            return dtype
3673        else:
3674            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3675
3676        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:
3678    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
3679        """
3680        Checks whether this DataType matches one of the provided data types. Nested types or precision
3681        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3682
3683        Args:
3684            dtypes: the data types to compare this DataType to.
3685
3686        Returns:
3687            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3688        """
3689        for dtype in dtypes:
3690            other = DataType.build(dtype, udt=True)
3691
3692            if (
3693                other.expressions
3694                or self.this == DataType.Type.USERDEFINED
3695                or other.this == DataType.Type.USERDEFINED
3696            ):
3697                matches = self == other
3698            else:
3699                matches = self.this == other.this
3700
3701            if matches:
3702                return True
3703        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):
3504    class Type(AutoName):
3505        ARRAY = auto()
3506        BIGDECIMAL = auto()
3507        BIGINT = auto()
3508        BIGSERIAL = auto()
3509        BINARY = auto()
3510        BIT = auto()
3511        BOOLEAN = auto()
3512        CHAR = auto()
3513        DATE = auto()
3514        DATEMULTIRANGE = auto()
3515        DATERANGE = auto()
3516        DATETIME = auto()
3517        DATETIME64 = auto()
3518        DECIMAL = auto()
3519        DOUBLE = auto()
3520        ENUM = auto()
3521        ENUM8 = auto()
3522        ENUM16 = auto()
3523        FIXEDSTRING = auto()
3524        FLOAT = auto()
3525        GEOGRAPHY = auto()
3526        GEOMETRY = auto()
3527        HLLSKETCH = auto()
3528        HSTORE = auto()
3529        IMAGE = auto()
3530        INET = auto()
3531        INT = auto()
3532        INT128 = auto()
3533        INT256 = auto()
3534        INT4MULTIRANGE = auto()
3535        INT4RANGE = auto()
3536        INT8MULTIRANGE = auto()
3537        INT8RANGE = auto()
3538        INTERVAL = auto()
3539        IPADDRESS = auto()
3540        IPPREFIX = auto()
3541        JSON = auto()
3542        JSONB = auto()
3543        LONGBLOB = auto()
3544        LONGTEXT = auto()
3545        LOWCARDINALITY = auto()
3546        MAP = auto()
3547        MEDIUMBLOB = auto()
3548        MEDIUMINT = auto()
3549        MEDIUMTEXT = auto()
3550        MONEY = auto()
3551        NCHAR = auto()
3552        NESTED = auto()
3553        NULL = auto()
3554        NULLABLE = auto()
3555        NUMMULTIRANGE = auto()
3556        NUMRANGE = auto()
3557        NVARCHAR = auto()
3558        OBJECT = auto()
3559        ROWVERSION = auto()
3560        SERIAL = auto()
3561        SET = auto()
3562        SMALLINT = auto()
3563        SMALLMONEY = auto()
3564        SMALLSERIAL = auto()
3565        STRUCT = auto()
3566        SUPER = auto()
3567        TEXT = auto()
3568        TINYBLOB = auto()
3569        TINYTEXT = auto()
3570        TIME = auto()
3571        TIMETZ = auto()
3572        TIMESTAMP = auto()
3573        TIMESTAMPLTZ = auto()
3574        TIMESTAMPTZ = auto()
3575        TINYINT = auto()
3576        TSMULTIRANGE = auto()
3577        TSRANGE = auto()
3578        TSTZMULTIRANGE = auto()
3579        TSTZRANGE = auto()
3580        UBIGINT = auto()
3581        UINT = auto()
3582        UINT128 = auto()
3583        UINT256 = auto()
3584        UMEDIUMINT = auto()
3585        UDECIMAL = auto()
3586        UNIQUEIDENTIFIER = auto()
3587        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3588        USERDEFINED = "USER-DEFINED"
3589        USMALLINT = auto()
3590        UTINYINT = auto()
3591        UUID = auto()
3592        VARBINARY = auto()
3593        VARCHAR = auto()
3594        VARIANT = auto()
3595        XML = auto()
3596        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'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
Inherited Members
enum.Enum
name
value
class PseudoType(DataType):
3707class PseudoType(DataType):
3708    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3712class ObjectIdentifier(DataType):
3713    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3717class SubqueryPredicate(Predicate):
3718    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3721class All(SubqueryPredicate):
3722    pass
key = 'all'
class Any(SubqueryPredicate):
3725class Any(SubqueryPredicate):
3726    pass
key = 'any'
class Exists(SubqueryPredicate):
3729class Exists(SubqueryPredicate):
3730    pass
key = 'exists'
class Command(Expression):
3735class Command(Expression):
3736    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3739class Transaction(Expression):
3740    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3743class Commit(Expression):
3744    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3747class Rollback(Expression):
3748    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3751class AlterTable(Expression):
3752    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):
3755class AddConstraint(Expression):
3756    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3759class DropPartition(Expression):
3760    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3764class Binary(Condition):
3765    arg_types = {"this": True, "expression": True}
3766
3767    @property
3768    def left(self):
3769        return self.this
3770
3771    @property
3772    def right(self):
3773        return self.expression
arg_types = {'this': True, 'expression': True}
left
right
key = 'binary'
class Add(Binary):
3776class Add(Binary):
3777    pass
key = 'add'
class Connector(Binary):
3780class Connector(Binary):
3781    pass
key = 'connector'
class And(Connector):
3784class And(Connector):
3785    pass
key = 'and'
class Or(Connector):
3788class Or(Connector):
3789    pass
key = 'or'
class BitwiseAnd(Binary):
3792class BitwiseAnd(Binary):
3793    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3796class BitwiseLeftShift(Binary):
3797    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3800class BitwiseOr(Binary):
3801    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3804class BitwiseRightShift(Binary):
3805    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3808class BitwiseXor(Binary):
3809    pass
key = 'bitwisexor'
class Div(Binary):
3812class Div(Binary):
3813    pass
key = 'div'
class Overlaps(Binary):
3816class Overlaps(Binary):
3817    pass
key = 'overlaps'
class Dot(Binary):
3820class Dot(Binary):
3821    @property
3822    def name(self) -> str:
3823        return self.expression.name
3824
3825    @property
3826    def output_name(self) -> str:
3827        return self.name
3828
3829    @classmethod
3830    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3831        """Build a Dot object with a sequence of expressions."""
3832        if len(expressions) < 2:
3833            raise ValueError(f"Dot requires >= 2 expressions.")
3834
3835        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:
3829    @classmethod
3830    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3831        """Build a Dot object with a sequence of expressions."""
3832        if len(expressions) < 2:
3833            raise ValueError(f"Dot requires >= 2 expressions.")
3834
3835        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):
3838class DPipe(Binary):
3839    pass
key = 'dpipe'
class SafeDPipe(DPipe):
3842class SafeDPipe(DPipe):
3843    pass
key = 'safedpipe'
class EQ(Binary, Predicate):
3846class EQ(Binary, Predicate):
3847    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
3850class NullSafeEQ(Binary, Predicate):
3851    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
3854class NullSafeNEQ(Binary, Predicate):
3855    pass
key = 'nullsafeneq'
class Distance(Binary):
3858class Distance(Binary):
3859    pass
key = 'distance'
class Escape(Binary):
3862class Escape(Binary):
3863    pass
key = 'escape'
class Glob(Binary, Predicate):
3866class Glob(Binary, Predicate):
3867    pass
key = 'glob'
class GT(Binary, Predicate):
3870class GT(Binary, Predicate):
3871    pass
key = 'gt'
class GTE(Binary, Predicate):
3874class GTE(Binary, Predicate):
3875    pass
key = 'gte'
class ILike(Binary, Predicate):
3878class ILike(Binary, Predicate):
3879    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
3882class ILikeAny(Binary, Predicate):
3883    pass
key = 'ilikeany'
class IntDiv(Binary):
3886class IntDiv(Binary):
3887    pass
key = 'intdiv'
class Is(Binary, Predicate):
3890class Is(Binary, Predicate):
3891    pass
key = 'is'
class Kwarg(Binary):
3894class Kwarg(Binary):
3895    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
3898class Like(Binary, Predicate):
3899    pass
key = 'like'
class LikeAny(Binary, Predicate):
3902class LikeAny(Binary, Predicate):
3903    pass
key = 'likeany'
class LT(Binary, Predicate):
3906class LT(Binary, Predicate):
3907    pass
key = 'lt'
class LTE(Binary, Predicate):
3910class LTE(Binary, Predicate):
3911    pass
key = 'lte'
class Mod(Binary):
3914class Mod(Binary):
3915    pass
key = 'mod'
class Mul(Binary):
3918class Mul(Binary):
3919    pass
key = 'mul'
class NEQ(Binary, Predicate):
3922class NEQ(Binary, Predicate):
3923    pass
key = 'neq'
class SimilarTo(Binary, Predicate):
3926class SimilarTo(Binary, Predicate):
3927    pass
key = 'similarto'
class Slice(Binary):
3930class Slice(Binary):
3931    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
3934class Sub(Binary):
3935    pass
key = 'sub'
class ArrayOverlaps(Binary):
3938class ArrayOverlaps(Binary):
3939    pass
key = 'arrayoverlaps'
class Unary(Condition):
3944class Unary(Condition):
3945    pass
key = 'unary'
class BitwiseNot(Unary):
3948class BitwiseNot(Unary):
3949    pass
key = 'bitwisenot'
class Not(Unary):
3952class Not(Unary):
3953    pass
key = 'not'
class Paren(Unary):
3956class Paren(Unary):
3957    arg_types = {"this": True, "with": False}
3958
3959    @property
3960    def output_name(self) -> str:
3961        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):
3964class Neg(Unary):
3965    pass
key = 'neg'
class Alias(Expression):
3968class Alias(Expression):
3969    arg_types = {"this": True, "alias": False}
3970
3971    @property
3972    def output_name(self) -> str:
3973        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):
3976class Aliases(Expression):
3977    arg_types = {"this": True, "expressions": True}
3978
3979    @property
3980    def aliases(self):
3981        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
key = 'aliases'
class AtTimeZone(Expression):
3984class AtTimeZone(Expression):
3985    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
3988class Between(Predicate):
3989    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
3992class Bracket(Condition):
3993    arg_types = {"this": True, "expressions": True}
3994
3995    @property
3996    def output_name(self) -> str:
3997        if len(self.expressions) == 1:
3998            return self.expressions[0].output_name
3999
4000        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):
4003class SafeBracket(Bracket):
4004    """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):
4007class Distinct(Expression):
4008    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4011class In(Predicate):
4012    arg_types = {
4013        "this": True,
4014        "expressions": False,
4015        "query": False,
4016        "unnest": False,
4017        "field": False,
4018        "is_global": False,
4019    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class TimeUnit(Expression):
4022class TimeUnit(Expression):
4023    """Automatically converts unit arg into a var."""
4024
4025    arg_types = {"unit": False}
4026
4027    def __init__(self, **args):
4028        unit = args.get("unit")
4029        if isinstance(unit, (Column, Literal)):
4030            args["unit"] = Var(this=unit.name)
4031        elif isinstance(unit, Week):
4032            unit.set("this", Var(this=unit.this.name))
4033
4034        super().__init__(**args)
4035
4036    @property
4037    def unit(self) -> t.Optional[Var]:
4038        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4027    def __init__(self, **args):
4028        unit = args.get("unit")
4029        if isinstance(unit, (Column, Literal)):
4030            args["unit"] = Var(this=unit.name)
4031        elif isinstance(unit, Week):
4032            unit.set("this", Var(this=unit.this.name))
4033
4034        super().__init__(**args)
arg_types = {'unit': False}
unit: Optional[Var]
key = 'timeunit'
class IntervalSpan(DataType):
4044class IntervalSpan(DataType):
4045    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4048class Interval(TimeUnit):
4049    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4052class IgnoreNulls(Expression):
4053    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4056class RespectNulls(Expression):
4057    pass
key = 'respectnulls'
class Func(Condition):
4061class Func(Condition):
4062    """
4063    The base class for all function expressions.
4064
4065    Attributes:
4066        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4067            treated as a variable length argument and the argument's value will be stored as a list.
4068        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4069            for this function expression. These values are used to map this node to a name during parsing
4070            as well as to provide the function's name during SQL string generation. By default the SQL
4071            name is set to the expression's class name transformed to snake case.
4072    """
4073
4074    is_var_len_args = False
4075
4076    @classmethod
4077    def from_arg_list(cls, args):
4078        if cls.is_var_len_args:
4079            all_arg_keys = list(cls.arg_types)
4080            # If this function supports variable length argument treat the last argument as such.
4081            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4082            num_non_var = len(non_var_len_arg_keys)
4083
4084            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4085            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4086        else:
4087            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4088
4089        return cls(**args_dict)
4090
4091    @classmethod
4092    def sql_names(cls):
4093        if cls is Func:
4094            raise NotImplementedError(
4095                "SQL name is only supported by concrete function implementations"
4096            )
4097        if "_sql_names" not in cls.__dict__:
4098            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4099        return cls._sql_names
4100
4101    @classmethod
4102    def sql_name(cls):
4103        return cls.sql_names()[0]
4104
4105    @classmethod
4106    def default_parser_mappings(cls):
4107        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):
4076    @classmethod
4077    def from_arg_list(cls, args):
4078        if cls.is_var_len_args:
4079            all_arg_keys = list(cls.arg_types)
4080            # If this function supports variable length argument treat the last argument as such.
4081            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4082            num_non_var = len(non_var_len_arg_keys)
4083
4084            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4085            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4086        else:
4087            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4088
4089        return cls(**args_dict)
@classmethod
def sql_names(cls):
4091    @classmethod
4092    def sql_names(cls):
4093        if cls is Func:
4094            raise NotImplementedError(
4095                "SQL name is only supported by concrete function implementations"
4096            )
4097        if "_sql_names" not in cls.__dict__:
4098            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4099        return cls._sql_names
@classmethod
def sql_name(cls):
4101    @classmethod
4102    def sql_name(cls):
4103        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4105    @classmethod
4106    def default_parser_mappings(cls):
4107        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4110class AggFunc(Func):
4111    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4114class ParameterizedAgg(AggFunc):
4115    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4118class Abs(Func):
4119    pass
key = 'abs'
class Transform(Func):
4123class Transform(Func):
4124    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4127class Anonymous(Func):
4128    arg_types = {"this": True, "expressions": False}
4129    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class Hll(AggFunc):
4134class Hll(AggFunc):
4135    arg_types = {"this": True, "expressions": False}
4136    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4139class ApproxDistinct(AggFunc):
4140    arg_types = {"this": True, "accuracy": False}
4141    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4144class Array(Func):
4145    arg_types = {"expressions": False}
4146    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToChar(Func):
4150class ToChar(Func):
4151    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tochar'
class GenerateSeries(Func):
4154class GenerateSeries(Func):
4155    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4158class ArrayAgg(AggFunc):
4159    pass
key = 'arrayagg'
class ArrayAll(Func):
4162class ArrayAll(Func):
4163    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4166class ArrayAny(Func):
4167    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4170class ArrayConcat(Func):
4171    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4172    arg_types = {"this": True, "expressions": False}
4173    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4176class ArrayContains(Binary, Func):
4177    pass
key = 'arraycontains'
class ArrayContained(Binary):
4180class ArrayContained(Binary):
4181    pass
key = 'arraycontained'
class ArrayFilter(Func):
4184class ArrayFilter(Func):
4185    arg_types = {"this": True, "expression": True}
4186    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4189class ArrayJoin(Func):
4190    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4193class ArraySize(Func):
4194    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4197class ArraySort(Func):
4198    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4201class ArraySum(Func):
4202    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4205class ArrayUnionAgg(AggFunc):
4206    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4209class Avg(AggFunc):
4210    pass
key = 'avg'
class AnyValue(AggFunc):
4213class AnyValue(AggFunc):
4214    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):
4217class First(Func):
4218    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4221class Last(Func):
4222    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4225class Case(Func):
4226    arg_types = {"this": False, "ifs": True, "default": False}
4227
4228    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4229        instance = maybe_copy(self, copy)
4230        instance.append(
4231            "ifs",
4232            If(
4233                this=maybe_parse(condition, copy=copy, **opts),
4234                true=maybe_parse(then, copy=copy, **opts),
4235            ),
4236        )
4237        return instance
4238
4239    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4240        instance = maybe_copy(self, copy)
4241        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4242        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:
4228    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4229        instance = maybe_copy(self, copy)
4230        instance.append(
4231            "ifs",
4232            If(
4233                this=maybe_parse(condition, copy=copy, **opts),
4234                true=maybe_parse(then, copy=copy, **opts),
4235            ),
4236        )
4237        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4239    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4240        instance = maybe_copy(self, copy)
4241        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4242        return instance
key = 'case'
class Cast(Func):
4245class Cast(Func):
4246    arg_types = {"this": True, "to": True, "format": False}
4247
4248    @property
4249    def name(self) -> str:
4250        return self.this.name
4251
4252    @property
4253    def to(self) -> DataType:
4254        return self.args["to"]
4255
4256    @property
4257    def output_name(self) -> str:
4258        return self.name
4259
4260    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
4261        """
4262        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4263        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4264        array<int> != array<float>.
4265
4266        Args:
4267            dtypes: the data types to compare this Cast's DataType to.
4268
4269        Returns:
4270            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4271        """
4272        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:
4260    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
4261        """
4262        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4263        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4264        array<int> != array<float>.
4265
4266        Args:
4267            dtypes: the data types to compare this Cast's DataType to.
4268
4269        Returns:
4270            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4271        """
4272        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):
4275class TryCast(Cast):
4276    pass
key = 'trycast'
class CastToStrType(Func):
4279class CastToStrType(Func):
4280    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4283class Collate(Binary, Func):
4284    pass
key = 'collate'
class Ceil(Func):
4287class Ceil(Func):
4288    arg_types = {"this": True, "decimals": False}
4289    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4292class Coalesce(Func):
4293    arg_types = {"this": True, "expressions": False}
4294    is_var_len_args = True
4295    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4298class Chr(Func):
4299    arg_types = {"this": True, "charset": False, "expressions": False}
4300    is_var_len_args = True
4301    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4304class Concat(Func):
4305    arg_types = {"expressions": True}
4306    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'concat'
class SafeConcat(Concat):
4309class SafeConcat(Concat):
4310    pass
key = 'safeconcat'
class ConcatWs(Concat):
4313class ConcatWs(Concat):
4314    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4317class Count(AggFunc):
4318    arg_types = {"this": False, "expressions": False}
4319    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4322class CountIf(AggFunc):
4323    pass
key = 'countif'
class CurrentDate(Func):
4326class CurrentDate(Func):
4327    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4330class CurrentDatetime(Func):
4331    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4334class CurrentTime(Func):
4335    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4338class CurrentTimestamp(Func):
4339    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4342class CurrentUser(Func):
4343    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, TimeUnit):
4346class DateAdd(Func, TimeUnit):
4347    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, TimeUnit):
4350class DateSub(Func, TimeUnit):
4351    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4354class DateDiff(Func, TimeUnit):
4355    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4356    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4359class DateTrunc(Func):
4360    arg_types = {"unit": True, "this": True, "zone": False}
4361
4362    @property
4363    def unit(self) -> Expression:
4364        return self.args["unit"]
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
key = 'datetrunc'
class DatetimeAdd(Func, TimeUnit):
4367class DatetimeAdd(Func, TimeUnit):
4368    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, TimeUnit):
4371class DatetimeSub(Func, TimeUnit):
4372    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4375class DatetimeDiff(Func, TimeUnit):
4376    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4379class DatetimeTrunc(Func, TimeUnit):
4380    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4383class DayOfWeek(Func):
4384    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4387class DayOfMonth(Func):
4388    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4391class DayOfYear(Func):
4392    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4395class ToDays(Func):
4396    pass
key = 'todays'
class WeekOfYear(Func):
4399class WeekOfYear(Func):
4400    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4403class MonthsBetween(Func):
4404    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDateOfMonth(Func):
4407class LastDateOfMonth(Func):
4408    pass
key = 'lastdateofmonth'
class Extract(Func):
4411class Extract(Func):
4412    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4415class Timestamp(Func):
4416    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4419class TimestampAdd(Func, TimeUnit):
4420    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4423class TimestampSub(Func, TimeUnit):
4424    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4427class TimestampDiff(Func, TimeUnit):
4428    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4431class TimestampTrunc(Func, TimeUnit):
4432    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4435class TimeAdd(Func, TimeUnit):
4436    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4439class TimeSub(Func, TimeUnit):
4440    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4443class TimeDiff(Func, TimeUnit):
4444    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4447class TimeTrunc(Func, TimeUnit):
4448    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4451class DateFromParts(Func):
4452    _sql_names = ["DATEFROMPARTS"]
4453    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class DateStrToDate(Func):
4456class DateStrToDate(Func):
4457    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4460class DateToDateStr(Func):
4461    pass
key = 'datetodatestr'
class DateToDi(Func):
4464class DateToDi(Func):
4465    pass
key = 'datetodi'
class Date(Func):
4469class Date(Func):
4470    arg_types = {"this": False, "zone": False, "expressions": False}
4471    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4474class Day(Func):
4475    pass
key = 'day'
class Decode(Func):
4478class Decode(Func):
4479    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4482class DiToDate(Func):
4483    pass
key = 'ditodate'
class Encode(Func):
4486class Encode(Func):
4487    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4490class Exp(Func):
4491    pass
key = 'exp'
class Explode(Func):
4494class Explode(Func):
4495    pass
key = 'explode'
class Floor(Func):
4498class Floor(Func):
4499    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4502class FromBase64(Func):
4503    pass
key = 'frombase64'
class ToBase64(Func):
4506class ToBase64(Func):
4507    pass
key = 'tobase64'
class Greatest(Func):
4510class Greatest(Func):
4511    arg_types = {"this": True, "expressions": False}
4512    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4515class GroupConcat(AggFunc):
4516    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4519class Hex(Func):
4520    pass
key = 'hex'
class Xor(Connector, Func):
4523class Xor(Connector, Func):
4524    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4527class If(Func):
4528    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Initcap(Func):
4531class Initcap(Func):
4532    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4535class IsNan(Func):
4536    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class FormatJson(Expression):
4539class FormatJson(Expression):
4540    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4543class JSONKeyValue(Expression):
4544    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4547class JSONObject(Func):
4548    arg_types = {
4549        "expressions": False,
4550        "null_handling": False,
4551        "unique_keys": False,
4552        "return_type": False,
4553        "encoding": False,
4554    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4558class JSONArray(Func):
4559    arg_types = {
4560        "expressions": True,
4561        "null_handling": False,
4562        "return_type": False,
4563        "strict": False,
4564    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4568class JSONArrayAgg(Func):
4569    arg_types = {
4570        "this": True,
4571        "order": False,
4572        "null_handling": False,
4573        "return_type": False,
4574        "strict": False,
4575    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4580class JSONColumnDef(Expression):
4581    arg_types = {"this": True, "kind": False, "path": False}
arg_types = {'this': True, 'kind': False, 'path': False}
key = 'jsoncolumndef'
class JSONTable(Func):
4585class JSONTable(Func):
4586    arg_types = {
4587        "this": True,
4588        "expressions": True,
4589        "path": False,
4590        "error_handling": False,
4591        "empty_handling": False,
4592    }
arg_types = {'this': True, 'expressions': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4595class OpenJSONColumnDef(Expression):
4596    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):
4599class OpenJSON(Func):
4600    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4603class JSONBContains(Binary):
4604    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4607class JSONExtract(Binary, Func):
4608    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4611class JSONExtractScalar(JSONExtract):
4612    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4615class JSONBExtract(JSONExtract):
4616    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4619class JSONBExtractScalar(JSONExtract):
4620    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4623class JSONFormat(Func):
4624    arg_types = {"this": False, "options": False}
4625    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4629class JSONArrayContains(Binary, Predicate, Func):
4630    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4633class ParseJSON(Func):
4634    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4635    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
key = 'parsejson'
class Least(Func):
4638class Least(Func):
4639    arg_types = {"this": True, "expressions": False}
4640    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4643class Left(Func):
4644    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4651class Length(Func):
4652    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4655class Levenshtein(Func):
4656    arg_types = {
4657        "this": True,
4658        "expression": False,
4659        "ins_cost": False,
4660        "del_cost": False,
4661        "sub_cost": False,
4662    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4665class Ln(Func):
4666    pass
key = 'ln'
class Log(Func):
4669class Log(Func):
4670    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4673class Log2(Func):
4674    pass
key = 'log2'
class Log10(Func):
4677class Log10(Func):
4678    pass
key = 'log10'
class LogicalOr(AggFunc):
4681class LogicalOr(AggFunc):
4682    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4685class LogicalAnd(AggFunc):
4686    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4689class Lower(Func):
4690    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4693class Map(Func):
4694    arg_types = {"keys": False, "values": False}
arg_types = {'keys': False, 'values': False}
key = 'map'
class MapFromEntries(Func):
4697class MapFromEntries(Func):
4698    pass
key = 'mapfromentries'
class StarMap(Func):
4701class StarMap(Func):
4702    pass
key = 'starmap'
class VarMap(Func):
4705class VarMap(Func):
4706    arg_types = {"keys": True, "values": True}
4707    is_var_len_args = True
4708
4709    @property
4710    def keys(self) -> t.List[Expression]:
4711        return self.args["keys"].expressions
4712
4713    @property
4714    def values(self) -> t.List[Expression]:
4715        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):
4719class MatchAgainst(Func):
4720    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4723class Max(AggFunc):
4724    arg_types = {"this": True, "expressions": False}
4725    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
4728class MD5(Func):
4729    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
4733class MD5Digest(Func):
4734    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
4737class Min(AggFunc):
4738    arg_types = {"this": True, "expressions": False}
4739    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
4742class Month(Func):
4743    pass
key = 'month'
class Nvl2(Func):
4746class Nvl2(Func):
4747    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Posexplode(Func):
4750class Posexplode(Func):
4751    pass
key = 'posexplode'
class Pow(Binary, Func):
4754class Pow(Binary, Func):
4755    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
4758class PercentileCont(AggFunc):
4759    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
4762class PercentileDisc(AggFunc):
4763    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
4766class Quantile(AggFunc):
4767    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
4770class ApproxQuantile(Quantile):
4771    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):
4774class RangeN(Func):
4775    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
4778class ReadCSV(Func):
4779    _sql_names = ["READ_CSV"]
4780    is_var_len_args = True
4781    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
4784class Reduce(Func):
4785    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):
4788class RegexpExtract(Func):
4789    arg_types = {
4790        "this": True,
4791        "expression": True,
4792        "position": False,
4793        "occurrence": False,
4794        "parameters": False,
4795        "group": False,
4796    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
4799class RegexpReplace(Func):
4800    arg_types = {
4801        "this": True,
4802        "expression": True,
4803        "replacement": True,
4804        "position": False,
4805        "occurrence": False,
4806        "parameters": False,
4807    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
4810class RegexpLike(Binary, Func):
4811    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Func):
4814class RegexpILike(Func):
4815    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
4820class RegexpSplit(Func):
4821    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
4824class Repeat(Func):
4825    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
4828class Round(Func):
4829    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
4832class RowNumber(Func):
4833    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
4836class SafeDivide(Func):
4837    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SetAgg(AggFunc):
4840class SetAgg(AggFunc):
4841    pass
key = 'setagg'
class SHA(Func):
4844class SHA(Func):
4845    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
4848class SHA2(Func):
4849    _sql_names = ["SHA2"]
4850    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
4853class SortArray(Func):
4854    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
4857class Split(Func):
4858    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
4863class Substring(Func):
4864    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
4867class StandardHash(Func):
4868    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
4871class StartsWith(Func):
4872    _sql_names = ["STARTS_WITH", "STARTSWITH"]
4873    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
4876class StrPosition(Func):
4877    arg_types = {
4878        "this": True,
4879        "substr": True,
4880        "position": False,
4881        "instance": False,
4882    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
4885class StrToDate(Func):
4886    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
4889class StrToTime(Func):
4890    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
4895class StrToUnix(Func):
4896    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
4901class StrToMap(Func):
4902    arg_types = {
4903        "this": True,
4904        "pair_delim": False,
4905        "key_value_delim": False,
4906        "duplicate_resolution_callback": False,
4907    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
4910class NumberToStr(Func):
4911    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
4914class FromBase(Func):
4915    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
4918class Struct(Func):
4919    arg_types = {"expressions": True}
4920    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
4923class StructExtract(Func):
4924    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
4929class Stuff(Func):
4930    _sql_names = ["STUFF", "INSERT"]
4931    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):
4934class Sum(AggFunc):
4935    pass
key = 'sum'
class Sqrt(Func):
4938class Sqrt(Func):
4939    pass
key = 'sqrt'
class Stddev(AggFunc):
4942class Stddev(AggFunc):
4943    pass
key = 'stddev'
class StddevPop(AggFunc):
4946class StddevPop(AggFunc):
4947    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
4950class StddevSamp(AggFunc):
4951    pass
key = 'stddevsamp'
class TimeToStr(Func):
4954class TimeToStr(Func):
4955    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
4958class TimeToTimeStr(Func):
4959    pass
key = 'timetotimestr'
class TimeToUnix(Func):
4962class TimeToUnix(Func):
4963    pass
key = 'timetounix'
class TimeStrToDate(Func):
4966class TimeStrToDate(Func):
4967    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
4970class TimeStrToTime(Func):
4971    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
4974class TimeStrToUnix(Func):
4975    pass
key = 'timestrtounix'
class Trim(Func):
4978class Trim(Func):
4979    arg_types = {
4980        "this": True,
4981        "expression": False,
4982        "position": False,
4983        "collation": False,
4984    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
4987class TsOrDsAdd(Func, TimeUnit):
4988    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsadd'
class TsOrDsToDateStr(Func):
4991class TsOrDsToDateStr(Func):
4992    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
4995class TsOrDsToDate(Func):
4996    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDiToDi(Func):
4999class TsOrDiToDi(Func):
5000    pass
key = 'tsorditodi'
class Unhex(Func):
5003class Unhex(Func):
5004    pass
key = 'unhex'
class UnixToStr(Func):
5007class UnixToStr(Func):
5008    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5013class UnixToTime(Func):
5014    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5015
5016    SECONDS = Literal.string("seconds")
5017    MILLIS = Literal.string("millis")
5018    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):
5021class UnixToTimeStr(Func):
5022    pass
key = 'unixtotimestr'
class Upper(Func):
5025class Upper(Func):
5026    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5029class Variance(AggFunc):
5030    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5033class VariancePop(AggFunc):
5034    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5037class Week(Func):
5038    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5041class XMLTable(Func):
5042    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):
5045class Year(Func):
5046    pass
key = 'year'
class Use(Expression):
5049class Use(Expression):
5050    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5053class Merge(Expression):
5054    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):
5057class When(Func):
5058    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):
5063class NextValueFor(Func):
5064    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 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <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 'ToDays'>, <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:
5101def maybe_parse(
5102    sql_or_expression: ExpOrStr,
5103    *,
5104    into: t.Optional[IntoType] = None,
5105    dialect: DialectType = None,
5106    prefix: t.Optional[str] = None,
5107    copy: bool = False,
5108    **opts,
5109) -> Expression:
5110    """Gracefully handle a possible string or expression.
5111
5112    Example:
5113        >>> maybe_parse("1")
5114        (LITERAL this: 1, is_string: False)
5115        >>> maybe_parse(to_identifier("x"))
5116        (IDENTIFIER this: x, quoted: False)
5117
5118    Args:
5119        sql_or_expression: the SQL code string or an expression
5120        into: the SQLGlot Expression to parse into
5121        dialect: the dialect used to parse the input expressions (in the case that an
5122            input expression is a SQL string).
5123        prefix: a string to prefix the sql with before it gets parsed
5124            (automatically includes a space)
5125        copy: whether or not to copy the expression.
5126        **opts: other options to use to parse the input expressions (again, in the case
5127            that an input expression is a SQL string).
5128
5129    Returns:
5130        Expression: the parsed or given expression.
5131    """
5132    if isinstance(sql_or_expression, Expression):
5133        if copy:
5134            return sql_or_expression.copy()
5135        return sql_or_expression
5136
5137    if sql_or_expression is None:
5138        raise ParseError(f"SQL cannot be None")
5139
5140    import sqlglot
5141
5142    sql = str(sql_or_expression)
5143    if prefix:
5144        sql = f"{prefix} {sql}"
5145
5146    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):
5159def maybe_copy(instance, copy=True):
5160    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:
5341def union(
5342    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5343) -> Union:
5344    """
5345    Initializes a syntax tree from one UNION expression.
5346
5347    Example:
5348        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5349        'SELECT * FROM foo UNION SELECT * FROM bla'
5350
5351    Args:
5352        left: the SQL code string corresponding to the left-hand side.
5353            If an `Expression` instance is passed, it will be used as-is.
5354        right: the SQL code string corresponding to the right-hand side.
5355            If an `Expression` instance is passed, it will be used as-is.
5356        distinct: set the DISTINCT flag if and only if this is true.
5357        dialect: the dialect used to parse the input expression.
5358        opts: other options to use to parse the input expressions.
5359
5360    Returns:
5361        The new Union instance.
5362    """
5363    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5364    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5365
5366    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:
5369def intersect(
5370    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5371) -> Intersect:
5372    """
5373    Initializes a syntax tree from one INTERSECT expression.
5374
5375    Example:
5376        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5377        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5378
5379    Args:
5380        left: the SQL code string corresponding to the left-hand side.
5381            If an `Expression` instance is passed, it will be used as-is.
5382        right: the SQL code string corresponding to the right-hand side.
5383            If an `Expression` instance is passed, it will be used as-is.
5384        distinct: set the DISTINCT flag if and only if this is true.
5385        dialect: the dialect used to parse the input expression.
5386        opts: other options to use to parse the input expressions.
5387
5388    Returns:
5389        The new Intersect instance.
5390    """
5391    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5392    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5393
5394    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:
5397def except_(
5398    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5399) -> Except:
5400    """
5401    Initializes a syntax tree from one EXCEPT expression.
5402
5403    Example:
5404        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5405        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5406
5407    Args:
5408        left: the SQL code string corresponding to the left-hand side.
5409            If an `Expression` instance is passed, it will be used as-is.
5410        right: the SQL code string corresponding to the right-hand side.
5411            If an `Expression` instance is passed, it will be used as-is.
5412        distinct: set the DISTINCT flag if and only if this is true.
5413        dialect: the dialect used to parse the input expression.
5414        opts: other options to use to parse the input expressions.
5415
5416    Returns:
5417        The new Except instance.
5418    """
5419    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5420    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5421
5422    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:
5425def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5426    """
5427    Initializes a syntax tree from one or multiple SELECT expressions.
5428
5429    Example:
5430        >>> select("col1", "col2").from_("tbl").sql()
5431        'SELECT col1, col2 FROM tbl'
5432
5433    Args:
5434        *expressions: the SQL code string to parse as the expressions of a
5435            SELECT statement. If an Expression instance is passed, this is used as-is.
5436        dialect: the dialect used to parse the input expressions (in the case that an
5437            input expression is a SQL string).
5438        **opts: other options to use to parse the input expressions (again, in the case
5439            that an input expression is a SQL string).
5440
5441    Returns:
5442        Select: the syntax tree for the SELECT statement.
5443    """
5444    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:
5447def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5448    """
5449    Initializes a syntax tree from a FROM expression.
5450
5451    Example:
5452        >>> from_("tbl").select("col1", "col2").sql()
5453        'SELECT col1, col2 FROM tbl'
5454
5455    Args:
5456        *expression: the SQL code string to parse as the FROM expressions of a
5457            SELECT statement. If an Expression instance is passed, this is used as-is.
5458        dialect: the dialect used to parse the input expression (in the case that the
5459            input expression is a SQL string).
5460        **opts: other options to use to parse the input expressions (again, in the case
5461            that the input expression is a SQL string).
5462
5463    Returns:
5464        Select: the syntax tree for the SELECT statement.
5465    """
5466    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:
5469def update(
5470    table: str | Table,
5471    properties: dict,
5472    where: t.Optional[ExpOrStr] = None,
5473    from_: t.Optional[ExpOrStr] = None,
5474    dialect: DialectType = None,
5475    **opts,
5476) -> Update:
5477    """
5478    Creates an update statement.
5479
5480    Example:
5481        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5482        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5483
5484    Args:
5485        *properties: dictionary of properties to set which are
5486            auto converted to sql objects eg None -> NULL
5487        where: sql conditional parsed into a WHERE statement
5488        from_: sql statement parsed into a FROM statement
5489        dialect: the dialect used to parse the input expressions.
5490        **opts: other options to use to parse the input expressions.
5491
5492    Returns:
5493        Update: the syntax tree for the UPDATE statement.
5494    """
5495    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5496    update_expr.set(
5497        "expressions",
5498        [
5499            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5500            for k, v in properties.items()
5501        ],
5502    )
5503    if from_:
5504        update_expr.set(
5505            "from",
5506            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5507        )
5508    if isinstance(where, Condition):
5509        where = Where(this=where)
5510    if where:
5511        update_expr.set(
5512            "where",
5513            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5514        )
5515    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:
5518def delete(
5519    table: ExpOrStr,
5520    where: t.Optional[ExpOrStr] = None,
5521    returning: t.Optional[ExpOrStr] = None,
5522    dialect: DialectType = None,
5523    **opts,
5524) -> Delete:
5525    """
5526    Builds a delete statement.
5527
5528    Example:
5529        >>> delete("my_table", where="id > 1").sql()
5530        'DELETE FROM my_table WHERE id > 1'
5531
5532    Args:
5533        where: sql conditional parsed into a WHERE statement
5534        returning: sql conditional parsed into a RETURNING statement
5535        dialect: the dialect used to parse the input expressions.
5536        **opts: other options to use to parse the input expressions.
5537
5538    Returns:
5539        Delete: the syntax tree for the DELETE statement.
5540    """
5541    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5542    if where:
5543        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5544    if returning:
5545        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5546    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:
5549def insert(
5550    expression: ExpOrStr,
5551    into: ExpOrStr,
5552    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5553    overwrite: t.Optional[bool] = None,
5554    dialect: DialectType = None,
5555    copy: bool = True,
5556    **opts,
5557) -> Insert:
5558    """
5559    Builds an INSERT statement.
5560
5561    Example:
5562        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5563        'INSERT INTO tbl VALUES (1, 2, 3)'
5564
5565    Args:
5566        expression: the sql string or expression of the INSERT statement
5567        into: the tbl to insert data to.
5568        columns: optionally the table's column names.
5569        overwrite: whether to INSERT OVERWRITE or not.
5570        dialect: the dialect used to parse the input expressions.
5571        copy: whether or not to copy the expression.
5572        **opts: other options to use to parse the input expressions.
5573
5574    Returns:
5575        Insert: the syntax tree for the INSERT statement.
5576    """
5577    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5578    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5579
5580    if columns:
5581        this = _apply_list_builder(
5582            *columns,
5583            instance=Schema(this=this),
5584            arg="expressions",
5585            into=Identifier,
5586            copy=False,
5587            dialect=dialect,
5588            **opts,
5589        )
5590
5591    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:
5594def condition(
5595    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5596) -> Condition:
5597    """
5598    Initialize a logical condition expression.
5599
5600    Example:
5601        >>> condition("x=1").sql()
5602        'x = 1'
5603
5604        This is helpful for composing larger logical syntax trees:
5605        >>> where = condition("x=1")
5606        >>> where = where.and_("y=1")
5607        >>> Select().from_("tbl").select("*").where(where).sql()
5608        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5609
5610    Args:
5611        *expression: the SQL code string to parse.
5612            If an Expression instance is passed, this is used as-is.
5613        dialect: the dialect used to parse the input expression (in the case that the
5614            input expression is a SQL string).
5615        copy: Whether or not to copy `expression` (only applies to expressions).
5616        **opts: other options to use to parse the input expressions (again, in the case
5617            that the input expression is a SQL string).
5618
5619    Returns:
5620        The new Condition instance
5621    """
5622    return maybe_parse(
5623        expression,
5624        into=Condition,
5625        dialect=dialect,
5626        copy=copy,
5627        **opts,
5628    )

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:
5631def and_(
5632    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5633) -> Condition:
5634    """
5635    Combine multiple conditions with an AND logical operator.
5636
5637    Example:
5638        >>> and_("x=1", and_("y=1", "z=1")).sql()
5639        'x = 1 AND (y = 1 AND z = 1)'
5640
5641    Args:
5642        *expressions: the SQL code strings to parse.
5643            If an Expression instance is passed, this is used as-is.
5644        dialect: the dialect used to parse the input expression.
5645        copy: whether or not to copy `expressions` (only applies to Expressions).
5646        **opts: other options to use to parse the input expressions.
5647
5648    Returns:
5649        And: the new condition
5650    """
5651    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:
5654def or_(
5655    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5656) -> Condition:
5657    """
5658    Combine multiple conditions with an OR logical operator.
5659
5660    Example:
5661        >>> or_("x=1", or_("y=1", "z=1")).sql()
5662        'x = 1 OR (y = 1 OR z = 1)'
5663
5664    Args:
5665        *expressions: the SQL code strings 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 or not to copy `expressions` (only applies to Expressions).
5669        **opts: other options to use to parse the input expressions.
5670
5671    Returns:
5672        Or: the new condition
5673    """
5674    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:
5677def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
5678    """
5679    Wrap a condition with a NOT operator.
5680
5681    Example:
5682        >>> not_("this_suit='black'").sql()
5683        "NOT this_suit = 'black'"
5684
5685    Args:
5686        expression: the SQL code string to parse.
5687            If an Expression instance is passed, this is used as-is.
5688        dialect: the dialect used to parse the input expression.
5689        copy: whether to copy the expression or not.
5690        **opts: other options to use to parse the input expressions.
5691
5692    Returns:
5693        The new condition.
5694    """
5695    this = condition(
5696        expression,
5697        dialect=dialect,
5698        copy=copy,
5699        **opts,
5700    )
5701    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:
5704def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
5705    """
5706    Wrap an expression in parentheses.
5707
5708    Example:
5709        >>> paren("5 + 3").sql()
5710        '(5 + 3)'
5711
5712    Args:
5713        expression: the SQL code string to parse.
5714            If an Expression instance is passed, this is used as-is.
5715        copy: whether to copy the expression or not.
5716
5717    Returns:
5718        The wrapped expression.
5719    """
5720    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):
5738def to_identifier(name, quoted=None, copy=True):
5739    """Builds an identifier.
5740
5741    Args:
5742        name: The name to turn into an identifier.
5743        quoted: Whether or not force quote the identifier.
5744        copy: Whether or not to copy a passed in Identefier node.
5745
5746    Returns:
5747        The identifier ast node.
5748    """
5749
5750    if name is None:
5751        return None
5752
5753    if isinstance(name, Identifier):
5754        identifier = maybe_copy(name, copy)
5755    elif isinstance(name, str):
5756        identifier = Identifier(
5757            this=name,
5758            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
5759        )
5760    else:
5761        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
5762    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:
5768def to_interval(interval: str | Literal) -> Interval:
5769    """Builds an interval expression from a string like '1 day' or '5 months'."""
5770    if isinstance(interval, Literal):
5771        if not interval.is_string:
5772            raise ValueError("Invalid interval string.")
5773
5774        interval = interval.this
5775
5776    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
5777
5778    if not interval_parts:
5779        raise ValueError("Invalid interval string.")
5780
5781    return Interval(
5782        this=Literal.string(interval_parts.group(1)),
5783        unit=Var(this=interval_parts.group(2)),
5784    )

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

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:
5956def cast(expression: ExpOrStr, to: str | DataType | DataType.Type, **opts) -> Cast:
5957    """Cast an expression to a data type.
5958
5959    Example:
5960        >>> cast('x + 1', 'int').sql()
5961        'CAST(x + 1 AS INT)'
5962
5963    Args:
5964        expression: The expression to cast.
5965        to: The datatype to cast to.
5966
5967    Returns:
5968        The new Cast instance.
5969    """
5970    expression = maybe_parse(expression, **opts)
5971    data_type = DataType.build(to, **opts)
5972    expression = Cast(this=expression, to=data_type)
5973    expression.type = data_type
5974    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:
5977def table_(
5978    table: Identifier | str,
5979    db: t.Optional[Identifier | str] = None,
5980    catalog: t.Optional[Identifier | str] = None,
5981    quoted: t.Optional[bool] = None,
5982    alias: t.Optional[Identifier | str] = None,
5983) -> Table:
5984    """Build a Table.
5985
5986    Args:
5987        table: Table name.
5988        db: Database name.
5989        catalog: Catalog name.
5990        quote: Whether to force quotes on the table's identifiers.
5991        alias: Table's alias.
5992
5993    Returns:
5994        The new Table instance.
5995    """
5996    return Table(
5997        this=to_identifier(table, quoted=quoted) if table else None,
5998        db=to_identifier(db, quoted=quoted) if db else None,
5999        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6000        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6001    )

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:
6004def values(
6005    values: t.Iterable[t.Tuple[t.Any, ...]],
6006    alias: t.Optional[str] = None,
6007    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6008) -> Values:
6009    """Build VALUES statement.
6010
6011    Example:
6012        >>> values([(1, '2')]).sql()
6013        "VALUES (1, '2')"
6014
6015    Args:
6016        values: values statements that will be converted to SQL
6017        alias: optional alias
6018        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6019         If either are provided then an alias is also required.
6020
6021    Returns:
6022        Values: the Values expression object
6023    """
6024    if columns and not alias:
6025        raise ValueError("Alias is required when providing columns")
6026
6027    return Values(
6028        expressions=[convert(tup) for tup in values],
6029        alias=(
6030            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6031            if columns
6032            else (TableAlias(this=to_identifier(alias)) if alias else None)
6033        ),
6034    )

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:
6037def var(name: t.Optional[ExpOrStr]) -> Var:
6038    """Build a SQL variable.
6039
6040    Example:
6041        >>> repr(var('x'))
6042        '(VAR this: x)'
6043
6044        >>> repr(var(column('x', table='y')))
6045        '(VAR this: x)'
6046
6047    Args:
6048        name: The name of the var or an expression who's name will become the var.
6049
6050    Returns:
6051        The new variable node.
6052    """
6053    if not name:
6054        raise ValueError("Cannot convert empty name into var.")
6055
6056    if isinstance(name, Expression):
6057        name = name.name
6058    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:
6061def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6062    """Build ALTER TABLE... RENAME... expression
6063
6064    Args:
6065        old_name: The old name of the table
6066        new_name: The new name of the table
6067
6068    Returns:
6069        Alter table expression
6070    """
6071    old_table = to_table(old_name)
6072    new_table = to_table(new_name)
6073    return AlterTable(
6074        this=old_table,
6075        actions=[
6076            RenameTable(this=new_table),
6077        ],
6078    )

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

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:
6168def table_name(table: Table | str, dialect: DialectType = None) -> str:
6169    """Get the full name of a table as a string.
6170
6171    Args:
6172        table: Table expression node or string.
6173        dialect: The dialect to generate the table name for.
6174
6175    Examples:
6176        >>> from sqlglot import exp, parse_one
6177        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6178        'a.b.c'
6179
6180    Returns:
6181        The table name.
6182    """
6183
6184    table = maybe_parse(table, into=Table)
6185
6186    if not table:
6187        raise ValueError(f"Cannot parse {table}")
6188
6189    return ".".join(
6190        part.sql(dialect=dialect, identify=True)
6191        if not SAFE_IDENTIFIER_RE.match(part.name)
6192        else part.name
6193        for part in table.parts
6194    )

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:
6197def replace_tables(expression: E, mapping: t.Dict[str, str], copy: bool = True) -> E:
6198    """Replace all tables in expression according to the mapping.
6199
6200    Args:
6201        expression: expression node to be transformed and replaced.
6202        mapping: mapping of table names.
6203        copy: whether or not to copy the expression.
6204
6205    Examples:
6206        >>> from sqlglot import exp, parse_one
6207        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6208        'SELECT * FROM c'
6209
6210    Returns:
6211        The mapped expression.
6212    """
6213
6214    def _replace_tables(node: Expression) -> Expression:
6215        if isinstance(node, Table):
6216            new_name = mapping.get(table_name(node))
6217            if new_name:
6218                return to_table(
6219                    new_name,
6220                    **{k: v for k, v in node.args.items() if k not in ("this", "db", "catalog")},
6221                )
6222        return node
6223
6224    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:
6227def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6228    """Replace placeholders in an expression.
6229
6230    Args:
6231        expression: expression node to be transformed and replaced.
6232        args: positional names that will substitute unnamed placeholders in the given order.
6233        kwargs: keyword arguments that will substitute named placeholders.
6234
6235    Examples:
6236        >>> from sqlglot import exp, parse_one
6237        >>> replace_placeholders(
6238        ...     parse_one("select * from :tbl where ? = ?"),
6239        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6240        ... ).sql()
6241        "SELECT * FROM foo WHERE str_col = 'b'"
6242
6243    Returns:
6244        The mapped expression.
6245    """
6246
6247    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6248        if isinstance(node, Placeholder):
6249            if node.name:
6250                new_name = kwargs.get(node.name)
6251                if new_name:
6252                    return convert(new_name)
6253            else:
6254                try:
6255                    return convert(next(args))
6256                except StopIteration:
6257                    pass
6258        return node
6259
6260    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:
6263def expand(
6264    expression: Expression, sources: t.Dict[str, Subqueryable], copy: bool = True
6265) -> Expression:
6266    """Transforms an expression by expanding all referenced sources into subqueries.
6267
6268    Examples:
6269        >>> from sqlglot import parse_one
6270        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6271        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6272
6273        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6274        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6275
6276    Args:
6277        expression: The expression to expand.
6278        sources: A dictionary of name to Subqueryables.
6279        copy: Whether or not to copy the expression during transformation. Defaults to True.
6280
6281    Returns:
6282        The transformed expression.
6283    """
6284
6285    def _expand(node: Expression):
6286        if isinstance(node, Table):
6287            name = table_name(node)
6288            source = sources.get(name)
6289            if source:
6290                subquery = source.subquery(node.alias or name)
6291                subquery.comments = [f"source: {name}"]
6292                return subquery.transform(_expand, copy=False)
6293        return node
6294
6295    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:
6298def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func:
6299    """
6300    Returns a Func expression.
6301
6302    Examples:
6303        >>> func("abs", 5).sql()
6304        'ABS(5)'
6305
6306        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6307        'CAST(5 AS DOUBLE)'
6308
6309    Args:
6310        name: the name of the function to build.
6311        args: the args used to instantiate the function of interest.
6312        dialect: the source dialect.
6313        kwargs: the kwargs used to instantiate the function of interest.
6314
6315    Note:
6316        The arguments `args` and `kwargs` are mutually exclusive.
6317
6318    Returns:
6319        An instance of the function of interest, or an anonymous function, if `name` doesn't
6320        correspond to an existing `sqlglot.expressions.Func` class.
6321    """
6322    if args and kwargs:
6323        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6324
6325    from sqlglot.dialects.dialect import Dialect
6326
6327    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args]
6328    kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()}
6329
6330    parser = Dialect.get_or_raise(dialect)().parser()
6331    from_args_list = parser.FUNCTIONS.get(name.upper())
6332
6333    if from_args_list:
6334        function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs)  # type: ignore
6335    else:
6336        kwargs = kwargs or {"expressions": converted}
6337        function = Anonymous(this=name, **kwargs)
6338
6339    for error_message in function.error_messages(converted):
6340        raise ValueError(error_message)
6341
6342    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:
6345def true() -> Boolean:
6346    """
6347    Returns a true Boolean expression.
6348    """
6349    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
6352def false() -> Boolean:
6353    """
6354    Returns a false Boolean expression.
6355    """
6356    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6359def null() -> Null:
6360    """
6361    Returns a Null expression.
6362    """
6363    return Null()

Returns a Null expression.

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