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 WeekOfYear(Func):
4395    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
4396
4397
4398class MonthsBetween(Func):
4399    arg_types = {"this": True, "expression": True, "roundoff": False}
4400
4401
4402class LastDateOfMonth(Func):
4403    pass
4404
4405
4406class Extract(Func):
4407    arg_types = {"this": True, "expression": True}
4408
4409
4410class Timestamp(Func):
4411    arg_types = {"this": False, "expression": False}
4412
4413
4414class TimestampAdd(Func, TimeUnit):
4415    arg_types = {"this": True, "expression": True, "unit": False}
4416
4417
4418class TimestampSub(Func, TimeUnit):
4419    arg_types = {"this": True, "expression": True, "unit": False}
4420
4421
4422class TimestampDiff(Func, TimeUnit):
4423    arg_types = {"this": True, "expression": True, "unit": False}
4424
4425
4426class TimestampTrunc(Func, TimeUnit):
4427    arg_types = {"this": True, "unit": True, "zone": False}
4428
4429
4430class TimeAdd(Func, TimeUnit):
4431    arg_types = {"this": True, "expression": True, "unit": False}
4432
4433
4434class TimeSub(Func, TimeUnit):
4435    arg_types = {"this": True, "expression": True, "unit": False}
4436
4437
4438class TimeDiff(Func, TimeUnit):
4439    arg_types = {"this": True, "expression": True, "unit": False}
4440
4441
4442class TimeTrunc(Func, TimeUnit):
4443    arg_types = {"this": True, "unit": True, "zone": False}
4444
4445
4446class DateFromParts(Func):
4447    _sql_names = ["DATEFROMPARTS"]
4448    arg_types = {"year": True, "month": True, "day": True}
4449
4450
4451class DateStrToDate(Func):
4452    pass
4453
4454
4455class DateToDateStr(Func):
4456    pass
4457
4458
4459class DateToDi(Func):
4460    pass
4461
4462
4463# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
4464class Date(Func):
4465    arg_types = {"this": False, "zone": False, "expressions": False}
4466    is_var_len_args = True
4467
4468
4469class Day(Func):
4470    pass
4471
4472
4473class Decode(Func):
4474    arg_types = {"this": True, "charset": True, "replace": False}
4475
4476
4477class DiToDate(Func):
4478    pass
4479
4480
4481class Encode(Func):
4482    arg_types = {"this": True, "charset": True}
4483
4484
4485class Exp(Func):
4486    pass
4487
4488
4489class Explode(Func):
4490    pass
4491
4492
4493class Floor(Func):
4494    arg_types = {"this": True, "decimals": False}
4495
4496
4497class FromBase64(Func):
4498    pass
4499
4500
4501class ToBase64(Func):
4502    pass
4503
4504
4505class Greatest(Func):
4506    arg_types = {"this": True, "expressions": False}
4507    is_var_len_args = True
4508
4509
4510class GroupConcat(AggFunc):
4511    arg_types = {"this": True, "separator": False}
4512
4513
4514class Hex(Func):
4515    pass
4516
4517
4518class Xor(Connector, Func):
4519    arg_types = {"this": False, "expression": False, "expressions": False}
4520
4521
4522class If(Func):
4523    arg_types = {"this": True, "true": True, "false": False}
4524
4525
4526class Initcap(Func):
4527    arg_types = {"this": True, "expression": False}
4528
4529
4530class IsNan(Func):
4531    _sql_names = ["IS_NAN", "ISNAN"]
4532
4533
4534class FormatJson(Expression):
4535    pass
4536
4537
4538class JSONKeyValue(Expression):
4539    arg_types = {"this": True, "expression": True}
4540
4541
4542class JSONObject(Func):
4543    arg_types = {
4544        "expressions": False,
4545        "null_handling": False,
4546        "unique_keys": False,
4547        "return_type": False,
4548        "encoding": False,
4549    }
4550
4551
4552# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
4553class JSONArray(Func):
4554    arg_types = {
4555        "expressions": True,
4556        "null_handling": False,
4557        "return_type": False,
4558        "strict": False,
4559    }
4560
4561
4562# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
4563class JSONArrayAgg(Func):
4564    arg_types = {
4565        "this": True,
4566        "order": False,
4567        "null_handling": False,
4568        "return_type": False,
4569        "strict": False,
4570    }
4571
4572
4573# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4574# Note: parsing of JSON column definitions is currently incomplete.
4575class JSONColumnDef(Expression):
4576    arg_types = {"this": True, "kind": False, "path": False}
4577
4578
4579# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4580class JSONTable(Func):
4581    arg_types = {
4582        "this": True,
4583        "expressions": True,
4584        "path": False,
4585        "error_handling": False,
4586        "empty_handling": False,
4587    }
4588
4589
4590class OpenJSONColumnDef(Expression):
4591    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
4592
4593
4594class OpenJSON(Func):
4595    arg_types = {"this": True, "path": False, "expressions": False}
4596
4597
4598class JSONBContains(Binary):
4599    _sql_names = ["JSONB_CONTAINS"]
4600
4601
4602class JSONExtract(Binary, Func):
4603    _sql_names = ["JSON_EXTRACT"]
4604
4605
4606class JSONExtractScalar(JSONExtract):
4607    _sql_names = ["JSON_EXTRACT_SCALAR"]
4608
4609
4610class JSONBExtract(JSONExtract):
4611    _sql_names = ["JSONB_EXTRACT"]
4612
4613
4614class JSONBExtractScalar(JSONExtract):
4615    _sql_names = ["JSONB_EXTRACT_SCALAR"]
4616
4617
4618class JSONFormat(Func):
4619    arg_types = {"this": False, "options": False}
4620    _sql_names = ["JSON_FORMAT"]
4621
4622
4623# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
4624class JSONArrayContains(Binary, Predicate, Func):
4625    _sql_names = ["JSON_ARRAY_CONTAINS"]
4626
4627
4628class ParseJSON(Func):
4629    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4630    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4631
4632
4633class Least(Func):
4634    arg_types = {"this": True, "expressions": False}
4635    is_var_len_args = True
4636
4637
4638class Left(Func):
4639    arg_types = {"this": True, "expression": True}
4640
4641
4642class Right(Func):
4643    arg_types = {"this": True, "expression": True}
4644
4645
4646class Length(Func):
4647    _sql_names = ["LENGTH", "LEN"]
4648
4649
4650class Levenshtein(Func):
4651    arg_types = {
4652        "this": True,
4653        "expression": False,
4654        "ins_cost": False,
4655        "del_cost": False,
4656        "sub_cost": False,
4657    }
4658
4659
4660class Ln(Func):
4661    pass
4662
4663
4664class Log(Func):
4665    arg_types = {"this": True, "expression": False}
4666
4667
4668class Log2(Func):
4669    pass
4670
4671
4672class Log10(Func):
4673    pass
4674
4675
4676class LogicalOr(AggFunc):
4677    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
4678
4679
4680class LogicalAnd(AggFunc):
4681    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
4682
4683
4684class Lower(Func):
4685    _sql_names = ["LOWER", "LCASE"]
4686
4687
4688class Map(Func):
4689    arg_types = {"keys": False, "values": False}
4690
4691
4692class MapFromEntries(Func):
4693    pass
4694
4695
4696class StarMap(Func):
4697    pass
4698
4699
4700class VarMap(Func):
4701    arg_types = {"keys": True, "values": True}
4702    is_var_len_args = True
4703
4704    @property
4705    def keys(self) -> t.List[Expression]:
4706        return self.args["keys"].expressions
4707
4708    @property
4709    def values(self) -> t.List[Expression]:
4710        return self.args["values"].expressions
4711
4712
4713# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
4714class MatchAgainst(Func):
4715    arg_types = {"this": True, "expressions": True, "modifier": False}
4716
4717
4718class Max(AggFunc):
4719    arg_types = {"this": True, "expressions": False}
4720    is_var_len_args = True
4721
4722
4723class MD5(Func):
4724    _sql_names = ["MD5"]
4725
4726
4727# Represents the variant of the MD5 function that returns a binary value
4728class MD5Digest(Func):
4729    _sql_names = ["MD5_DIGEST"]
4730
4731
4732class Min(AggFunc):
4733    arg_types = {"this": True, "expressions": False}
4734    is_var_len_args = True
4735
4736
4737class Month(Func):
4738    pass
4739
4740
4741class Nvl2(Func):
4742    arg_types = {"this": True, "true": True, "false": False}
4743
4744
4745class Posexplode(Func):
4746    pass
4747
4748
4749class Pow(Binary, Func):
4750    _sql_names = ["POWER", "POW"]
4751
4752
4753class PercentileCont(AggFunc):
4754    arg_types = {"this": True, "expression": False}
4755
4756
4757class PercentileDisc(AggFunc):
4758    arg_types = {"this": True, "expression": False}
4759
4760
4761class Quantile(AggFunc):
4762    arg_types = {"this": True, "quantile": True}
4763
4764
4765class ApproxQuantile(Quantile):
4766    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
4767
4768
4769class RangeN(Func):
4770    arg_types = {"this": True, "expressions": True, "each": False}
4771
4772
4773class ReadCSV(Func):
4774    _sql_names = ["READ_CSV"]
4775    is_var_len_args = True
4776    arg_types = {"this": True, "expressions": False}
4777
4778
4779class Reduce(Func):
4780    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
4781
4782
4783class RegexpExtract(Func):
4784    arg_types = {
4785        "this": True,
4786        "expression": True,
4787        "position": False,
4788        "occurrence": False,
4789        "parameters": False,
4790        "group": False,
4791    }
4792
4793
4794class RegexpReplace(Func):
4795    arg_types = {
4796        "this": True,
4797        "expression": True,
4798        "replacement": True,
4799        "position": False,
4800        "occurrence": False,
4801        "parameters": False,
4802    }
4803
4804
4805class RegexpLike(Binary, Func):
4806    arg_types = {"this": True, "expression": True, "flag": False}
4807
4808
4809class RegexpILike(Func):
4810    arg_types = {"this": True, "expression": True, "flag": False}
4811
4812
4813# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
4814# limit is the number of times a pattern is applied
4815class RegexpSplit(Func):
4816    arg_types = {"this": True, "expression": True, "limit": False}
4817
4818
4819class Repeat(Func):
4820    arg_types = {"this": True, "times": True}
4821
4822
4823class Round(Func):
4824    arg_types = {"this": True, "decimals": False}
4825
4826
4827class RowNumber(Func):
4828    arg_types: t.Dict[str, t.Any] = {}
4829
4830
4831class SafeDivide(Func):
4832    arg_types = {"this": True, "expression": True}
4833
4834
4835class SetAgg(AggFunc):
4836    pass
4837
4838
4839class SHA(Func):
4840    _sql_names = ["SHA", "SHA1"]
4841
4842
4843class SHA2(Func):
4844    _sql_names = ["SHA2"]
4845    arg_types = {"this": True, "length": False}
4846
4847
4848class SortArray(Func):
4849    arg_types = {"this": True, "asc": False}
4850
4851
4852class Split(Func):
4853    arg_types = {"this": True, "expression": True, "limit": False}
4854
4855
4856# Start may be omitted in the case of postgres
4857# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
4858class Substring(Func):
4859    arg_types = {"this": True, "start": False, "length": False}
4860
4861
4862class StandardHash(Func):
4863    arg_types = {"this": True, "expression": False}
4864
4865
4866class StartsWith(Func):
4867    _sql_names = ["STARTS_WITH", "STARTSWITH"]
4868    arg_types = {"this": True, "expression": True}
4869
4870
4871class StrPosition(Func):
4872    arg_types = {
4873        "this": True,
4874        "substr": True,
4875        "position": False,
4876        "instance": False,
4877    }
4878
4879
4880class StrToDate(Func):
4881    arg_types = {"this": True, "format": True}
4882
4883
4884class StrToTime(Func):
4885    arg_types = {"this": True, "format": True, "zone": False}
4886
4887
4888# Spark allows unix_timestamp()
4889# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
4890class StrToUnix(Func):
4891    arg_types = {"this": False, "format": False}
4892
4893
4894# https://prestodb.io/docs/current/functions/string.html
4895# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
4896class StrToMap(Func):
4897    arg_types = {
4898        "this": True,
4899        "pair_delim": False,
4900        "key_value_delim": False,
4901        "duplicate_resolution_callback": False,
4902    }
4903
4904
4905class NumberToStr(Func):
4906    arg_types = {"this": True, "format": True, "culture": False}
4907
4908
4909class FromBase(Func):
4910    arg_types = {"this": True, "expression": True}
4911
4912
4913class Struct(Func):
4914    arg_types = {"expressions": True}
4915    is_var_len_args = True
4916
4917
4918class StructExtract(Func):
4919    arg_types = {"this": True, "expression": True}
4920
4921
4922# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
4923# https://docs.snowflake.com/en/sql-reference/functions/insert
4924class Stuff(Func):
4925    _sql_names = ["STUFF", "INSERT"]
4926    arg_types = {"this": True, "start": True, "length": True, "expression": True}
4927
4928
4929class Sum(AggFunc):
4930    pass
4931
4932
4933class Sqrt(Func):
4934    pass
4935
4936
4937class Stddev(AggFunc):
4938    pass
4939
4940
4941class StddevPop(AggFunc):
4942    pass
4943
4944
4945class StddevSamp(AggFunc):
4946    pass
4947
4948
4949class TimeToStr(Func):
4950    arg_types = {"this": True, "format": True, "culture": False}
4951
4952
4953class TimeToTimeStr(Func):
4954    pass
4955
4956
4957class TimeToUnix(Func):
4958    pass
4959
4960
4961class TimeStrToDate(Func):
4962    pass
4963
4964
4965class TimeStrToTime(Func):
4966    pass
4967
4968
4969class TimeStrToUnix(Func):
4970    pass
4971
4972
4973class Trim(Func):
4974    arg_types = {
4975        "this": True,
4976        "expression": False,
4977        "position": False,
4978        "collation": False,
4979    }
4980
4981
4982class TsOrDsAdd(Func, TimeUnit):
4983    arg_types = {"this": True, "expression": True, "unit": False}
4984
4985
4986class TsOrDsToDateStr(Func):
4987    pass
4988
4989
4990class TsOrDsToDate(Func):
4991    arg_types = {"this": True, "format": False}
4992
4993
4994class TsOrDiToDi(Func):
4995    pass
4996
4997
4998class Unhex(Func):
4999    pass
5000
5001
5002class UnixToStr(Func):
5003    arg_types = {"this": True, "format": False}
5004
5005
5006# https://prestodb.io/docs/current/functions/datetime.html
5007# presto has weird zone/hours/minutes
5008class UnixToTime(Func):
5009    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5010
5011    SECONDS = Literal.string("seconds")
5012    MILLIS = Literal.string("millis")
5013    MICROS = Literal.string("micros")
5014
5015
5016class UnixToTimeStr(Func):
5017    pass
5018
5019
5020class Upper(Func):
5021    _sql_names = ["UPPER", "UCASE"]
5022
5023
5024class Variance(AggFunc):
5025    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
5026
5027
5028class VariancePop(AggFunc):
5029    _sql_names = ["VARIANCE_POP", "VAR_POP"]
5030
5031
5032class Week(Func):
5033    arg_types = {"this": True, "mode": False}
5034
5035
5036class XMLTable(Func):
5037    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
5038
5039
5040class Year(Func):
5041    pass
5042
5043
5044class Use(Expression):
5045    arg_types = {"this": True, "kind": False}
5046
5047
5048class Merge(Expression):
5049    arg_types = {"this": True, "using": True, "on": True, "expressions": True}
5050
5051
5052class When(Func):
5053    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
5054
5055
5056# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
5057# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
5058class NextValueFor(Func):
5059    arg_types = {"this": True, "order": False}
5060
5061
5062def _norm_arg(arg):
5063    return arg.lower() if type(arg) is str else arg
5064
5065
5066ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
5067
5068
5069# Helpers
5070@t.overload
5071def maybe_parse(
5072    sql_or_expression: ExpOrStr,
5073    *,
5074    into: t.Type[E],
5075    dialect: DialectType = None,
5076    prefix: t.Optional[str] = None,
5077    copy: bool = False,
5078    **opts,
5079) -> E:
5080    ...
5081
5082
5083@t.overload
5084def maybe_parse(
5085    sql_or_expression: str | E,
5086    *,
5087    into: t.Optional[IntoType] = None,
5088    dialect: DialectType = None,
5089    prefix: t.Optional[str] = None,
5090    copy: bool = False,
5091    **opts,
5092) -> E:
5093    ...
5094
5095
5096def maybe_parse(
5097    sql_or_expression: ExpOrStr,
5098    *,
5099    into: t.Optional[IntoType] = None,
5100    dialect: DialectType = None,
5101    prefix: t.Optional[str] = None,
5102    copy: bool = False,
5103    **opts,
5104) -> Expression:
5105    """Gracefully handle a possible string or expression.
5106
5107    Example:
5108        >>> maybe_parse("1")
5109        (LITERAL this: 1, is_string: False)
5110        >>> maybe_parse(to_identifier("x"))
5111        (IDENTIFIER this: x, quoted: False)
5112
5113    Args:
5114        sql_or_expression: the SQL code string or an expression
5115        into: the SQLGlot Expression to parse into
5116        dialect: the dialect used to parse the input expressions (in the case that an
5117            input expression is a SQL string).
5118        prefix: a string to prefix the sql with before it gets parsed
5119            (automatically includes a space)
5120        copy: whether or not to copy the expression.
5121        **opts: other options to use to parse the input expressions (again, in the case
5122            that an input expression is a SQL string).
5123
5124    Returns:
5125        Expression: the parsed or given expression.
5126    """
5127    if isinstance(sql_or_expression, Expression):
5128        if copy:
5129            return sql_or_expression.copy()
5130        return sql_or_expression
5131
5132    if sql_or_expression is None:
5133        raise ParseError(f"SQL cannot be None")
5134
5135    import sqlglot
5136
5137    sql = str(sql_or_expression)
5138    if prefix:
5139        sql = f"{prefix} {sql}"
5140
5141    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
5142
5143
5144@t.overload
5145def maybe_copy(instance: None, copy: bool = True) -> None:
5146    ...
5147
5148
5149@t.overload
5150def maybe_copy(instance: E, copy: bool = True) -> E:
5151    ...
5152
5153
5154def maybe_copy(instance, copy=True):
5155    return instance.copy() if copy and instance else instance
5156
5157
5158def _is_wrong_expression(expression, into):
5159    return isinstance(expression, Expression) and not isinstance(expression, into)
5160
5161
5162def _apply_builder(
5163    expression,
5164    instance,
5165    arg,
5166    copy=True,
5167    prefix=None,
5168    into=None,
5169    dialect=None,
5170    into_arg="this",
5171    **opts,
5172):
5173    if _is_wrong_expression(expression, into):
5174        expression = into(**{into_arg: expression})
5175    instance = maybe_copy(instance, copy)
5176    expression = maybe_parse(
5177        sql_or_expression=expression,
5178        prefix=prefix,
5179        into=into,
5180        dialect=dialect,
5181        **opts,
5182    )
5183    instance.set(arg, expression)
5184    return instance
5185
5186
5187def _apply_child_list_builder(
5188    *expressions,
5189    instance,
5190    arg,
5191    append=True,
5192    copy=True,
5193    prefix=None,
5194    into=None,
5195    dialect=None,
5196    properties=None,
5197    **opts,
5198):
5199    instance = maybe_copy(instance, copy)
5200    parsed = []
5201    for expression in expressions:
5202        if expression is not None:
5203            if _is_wrong_expression(expression, into):
5204                expression = into(expressions=[expression])
5205
5206            expression = maybe_parse(
5207                expression,
5208                into=into,
5209                dialect=dialect,
5210                prefix=prefix,
5211                **opts,
5212            )
5213            parsed.extend(expression.expressions)
5214
5215    existing = instance.args.get(arg)
5216    if append and existing:
5217        parsed = existing.expressions + parsed
5218
5219    child = into(expressions=parsed)
5220    for k, v in (properties or {}).items():
5221        child.set(k, v)
5222    instance.set(arg, child)
5223
5224    return instance
5225
5226
5227def _apply_list_builder(
5228    *expressions,
5229    instance,
5230    arg,
5231    append=True,
5232    copy=True,
5233    prefix=None,
5234    into=None,
5235    dialect=None,
5236    **opts,
5237):
5238    inst = maybe_copy(instance, copy)
5239
5240    expressions = [
5241        maybe_parse(
5242            sql_or_expression=expression,
5243            into=into,
5244            prefix=prefix,
5245            dialect=dialect,
5246            **opts,
5247        )
5248        for expression in expressions
5249        if expression is not None
5250    ]
5251
5252    existing_expressions = inst.args.get(arg)
5253    if append and existing_expressions:
5254        expressions = existing_expressions + expressions
5255
5256    inst.set(arg, expressions)
5257    return inst
5258
5259
5260def _apply_conjunction_builder(
5261    *expressions,
5262    instance,
5263    arg,
5264    into=None,
5265    append=True,
5266    copy=True,
5267    dialect=None,
5268    **opts,
5269):
5270    expressions = [exp for exp in expressions if exp is not None and exp != ""]
5271    if not expressions:
5272        return instance
5273
5274    inst = maybe_copy(instance, copy)
5275
5276    existing = inst.args.get(arg)
5277    if append and existing is not None:
5278        expressions = [existing.this if into else existing] + list(expressions)
5279
5280    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
5281
5282    inst.set(arg, into(this=node) if into else node)
5283    return inst
5284
5285
5286def _apply_cte_builder(
5287    instance: E,
5288    alias: ExpOrStr,
5289    as_: ExpOrStr,
5290    recursive: t.Optional[bool] = None,
5291    append: bool = True,
5292    dialect: DialectType = None,
5293    copy: bool = True,
5294    **opts,
5295) -> E:
5296    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
5297    as_expression = maybe_parse(as_, dialect=dialect, **opts)
5298    cte = CTE(this=as_expression, alias=alias_expression)
5299    return _apply_child_list_builder(
5300        cte,
5301        instance=instance,
5302        arg="with",
5303        append=append,
5304        copy=copy,
5305        into=With,
5306        properties={"recursive": recursive or False},
5307    )
5308
5309
5310def _combine(
5311    expressions: t.Sequence[t.Optional[ExpOrStr]],
5312    operator: t.Type[Connector],
5313    dialect: DialectType = None,
5314    copy: bool = True,
5315    **opts,
5316) -> Expression:
5317    conditions = [
5318        condition(expression, dialect=dialect, copy=copy, **opts)
5319        for expression in expressions
5320        if expression is not None
5321    ]
5322
5323    this, *rest = conditions
5324    if rest:
5325        this = _wrap(this, Connector)
5326    for expression in rest:
5327        this = operator(this=this, expression=_wrap(expression, Connector))
5328
5329    return this
5330
5331
5332def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
5333    return Paren(this=expression) if isinstance(expression, kind) else expression
5334
5335
5336def union(
5337    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5338) -> Union:
5339    """
5340    Initializes a syntax tree from one UNION expression.
5341
5342    Example:
5343        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5344        'SELECT * FROM foo UNION SELECT * FROM bla'
5345
5346    Args:
5347        left: the SQL code string corresponding to the left-hand side.
5348            If an `Expression` instance is passed, it will be used as-is.
5349        right: the SQL code string corresponding to the right-hand side.
5350            If an `Expression` instance is passed, it will be used as-is.
5351        distinct: set the DISTINCT flag if and only if this is true.
5352        dialect: the dialect used to parse the input expression.
5353        opts: other options to use to parse the input expressions.
5354
5355    Returns:
5356        The new Union instance.
5357    """
5358    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5359    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5360
5361    return Union(this=left, expression=right, distinct=distinct)
5362
5363
5364def intersect(
5365    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5366) -> Intersect:
5367    """
5368    Initializes a syntax tree from one INTERSECT expression.
5369
5370    Example:
5371        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5372        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5373
5374    Args:
5375        left: the SQL code string corresponding to the left-hand side.
5376            If an `Expression` instance is passed, it will be used as-is.
5377        right: the SQL code string corresponding to the right-hand side.
5378            If an `Expression` instance is passed, it will be used as-is.
5379        distinct: set the DISTINCT flag if and only if this is true.
5380        dialect: the dialect used to parse the input expression.
5381        opts: other options to use to parse the input expressions.
5382
5383    Returns:
5384        The new Intersect instance.
5385    """
5386    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5387    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5388
5389    return Intersect(this=left, expression=right, distinct=distinct)
5390
5391
5392def except_(
5393    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5394) -> Except:
5395    """
5396    Initializes a syntax tree from one EXCEPT expression.
5397
5398    Example:
5399        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5400        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5401
5402    Args:
5403        left: the SQL code string corresponding to the left-hand side.
5404            If an `Expression` instance is passed, it will be used as-is.
5405        right: the SQL code string corresponding to the right-hand side.
5406            If an `Expression` instance is passed, it will be used as-is.
5407        distinct: set the DISTINCT flag if and only if this is true.
5408        dialect: the dialect used to parse the input expression.
5409        opts: other options to use to parse the input expressions.
5410
5411    Returns:
5412        The new Except instance.
5413    """
5414    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5415    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5416
5417    return Except(this=left, expression=right, distinct=distinct)
5418
5419
5420def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5421    """
5422    Initializes a syntax tree from one or multiple SELECT expressions.
5423
5424    Example:
5425        >>> select("col1", "col2").from_("tbl").sql()
5426        'SELECT col1, col2 FROM tbl'
5427
5428    Args:
5429        *expressions: the SQL code string to parse as the expressions of a
5430            SELECT statement. If an Expression instance is passed, this is used as-is.
5431        dialect: the dialect used to parse the input expressions (in the case that an
5432            input expression is a SQL string).
5433        **opts: other options to use to parse the input expressions (again, in the case
5434            that an input expression is a SQL string).
5435
5436    Returns:
5437        Select: the syntax tree for the SELECT statement.
5438    """
5439    return Select().select(*expressions, dialect=dialect, **opts)
5440
5441
5442def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5443    """
5444    Initializes a syntax tree from a FROM expression.
5445
5446    Example:
5447        >>> from_("tbl").select("col1", "col2").sql()
5448        'SELECT col1, col2 FROM tbl'
5449
5450    Args:
5451        *expression: the SQL code string to parse as the FROM expressions of a
5452            SELECT statement. If an Expression instance is passed, this is used as-is.
5453        dialect: the dialect used to parse the input expression (in the case that the
5454            input expression is a SQL string).
5455        **opts: other options to use to parse the input expressions (again, in the case
5456            that the input expression is a SQL string).
5457
5458    Returns:
5459        Select: the syntax tree for the SELECT statement.
5460    """
5461    return Select().from_(expression, dialect=dialect, **opts)
5462
5463
5464def update(
5465    table: str | Table,
5466    properties: dict,
5467    where: t.Optional[ExpOrStr] = None,
5468    from_: t.Optional[ExpOrStr] = None,
5469    dialect: DialectType = None,
5470    **opts,
5471) -> Update:
5472    """
5473    Creates an update statement.
5474
5475    Example:
5476        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5477        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5478
5479    Args:
5480        *properties: dictionary of properties to set which are
5481            auto converted to sql objects eg None -> NULL
5482        where: sql conditional parsed into a WHERE statement
5483        from_: sql statement parsed into a FROM statement
5484        dialect: the dialect used to parse the input expressions.
5485        **opts: other options to use to parse the input expressions.
5486
5487    Returns:
5488        Update: the syntax tree for the UPDATE statement.
5489    """
5490    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5491    update_expr.set(
5492        "expressions",
5493        [
5494            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5495            for k, v in properties.items()
5496        ],
5497    )
5498    if from_:
5499        update_expr.set(
5500            "from",
5501            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5502        )
5503    if isinstance(where, Condition):
5504        where = Where(this=where)
5505    if where:
5506        update_expr.set(
5507            "where",
5508            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5509        )
5510    return update_expr
5511
5512
5513def delete(
5514    table: ExpOrStr,
5515    where: t.Optional[ExpOrStr] = None,
5516    returning: t.Optional[ExpOrStr] = None,
5517    dialect: DialectType = None,
5518    **opts,
5519) -> Delete:
5520    """
5521    Builds a delete statement.
5522
5523    Example:
5524        >>> delete("my_table", where="id > 1").sql()
5525        'DELETE FROM my_table WHERE id > 1'
5526
5527    Args:
5528        where: sql conditional parsed into a WHERE statement
5529        returning: sql conditional parsed into a RETURNING statement
5530        dialect: the dialect used to parse the input expressions.
5531        **opts: other options to use to parse the input expressions.
5532
5533    Returns:
5534        Delete: the syntax tree for the DELETE statement.
5535    """
5536    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5537    if where:
5538        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5539    if returning:
5540        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5541    return delete_expr
5542
5543
5544def insert(
5545    expression: ExpOrStr,
5546    into: ExpOrStr,
5547    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5548    overwrite: t.Optional[bool] = None,
5549    dialect: DialectType = None,
5550    copy: bool = True,
5551    **opts,
5552) -> Insert:
5553    """
5554    Builds an INSERT statement.
5555
5556    Example:
5557        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5558        'INSERT INTO tbl VALUES (1, 2, 3)'
5559
5560    Args:
5561        expression: the sql string or expression of the INSERT statement
5562        into: the tbl to insert data to.
5563        columns: optionally the table's column names.
5564        overwrite: whether to INSERT OVERWRITE or not.
5565        dialect: the dialect used to parse the input expressions.
5566        copy: whether or not to copy the expression.
5567        **opts: other options to use to parse the input expressions.
5568
5569    Returns:
5570        Insert: the syntax tree for the INSERT statement.
5571    """
5572    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5573    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5574
5575    if columns:
5576        this = _apply_list_builder(
5577            *columns,
5578            instance=Schema(this=this),
5579            arg="expressions",
5580            into=Identifier,
5581            copy=False,
5582            dialect=dialect,
5583            **opts,
5584        )
5585
5586    return Insert(this=this, expression=expr, overwrite=overwrite)
5587
5588
5589def condition(
5590    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5591) -> Condition:
5592    """
5593    Initialize a logical condition expression.
5594
5595    Example:
5596        >>> condition("x=1").sql()
5597        'x = 1'
5598
5599        This is helpful for composing larger logical syntax trees:
5600        >>> where = condition("x=1")
5601        >>> where = where.and_("y=1")
5602        >>> Select().from_("tbl").select("*").where(where).sql()
5603        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5604
5605    Args:
5606        *expression: the SQL code string to parse.
5607            If an Expression instance is passed, this is used as-is.
5608        dialect: the dialect used to parse the input expression (in the case that the
5609            input expression is a SQL string).
5610        copy: Whether or not to copy `expression` (only applies to expressions).
5611        **opts: other options to use to parse the input expressions (again, in the case
5612            that the input expression is a SQL string).
5613
5614    Returns:
5615        The new Condition instance
5616    """
5617    return maybe_parse(
5618        expression,
5619        into=Condition,
5620        dialect=dialect,
5621        copy=copy,
5622        **opts,
5623    )
5624
5625
5626def and_(
5627    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5628) -> Condition:
5629    """
5630    Combine multiple conditions with an AND logical operator.
5631
5632    Example:
5633        >>> and_("x=1", and_("y=1", "z=1")).sql()
5634        'x = 1 AND (y = 1 AND z = 1)'
5635
5636    Args:
5637        *expressions: the SQL code strings to parse.
5638            If an Expression instance is passed, this is used as-is.
5639        dialect: the dialect used to parse the input expression.
5640        copy: whether or not to copy `expressions` (only applies to Expressions).
5641        **opts: other options to use to parse the input expressions.
5642
5643    Returns:
5644        And: the new condition
5645    """
5646    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
5647
5648
5649def or_(
5650    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5651) -> Condition:
5652    """
5653    Combine multiple conditions with an OR logical operator.
5654
5655    Example:
5656        >>> or_("x=1", or_("y=1", "z=1")).sql()
5657        'x = 1 OR (y = 1 OR z = 1)'
5658
5659    Args:
5660        *expressions: the SQL code strings to parse.
5661            If an Expression instance is passed, this is used as-is.
5662        dialect: the dialect used to parse the input expression.
5663        copy: whether or not to copy `expressions` (only applies to Expressions).
5664        **opts: other options to use to parse the input expressions.
5665
5666    Returns:
5667        Or: the new condition
5668    """
5669    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
5670
5671
5672def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
5673    """
5674    Wrap a condition with a NOT operator.
5675
5676    Example:
5677        >>> not_("this_suit='black'").sql()
5678        "NOT this_suit = 'black'"
5679
5680    Args:
5681        expression: the SQL code string to parse.
5682            If an Expression instance is passed, this is used as-is.
5683        dialect: the dialect used to parse the input expression.
5684        copy: whether to copy the expression or not.
5685        **opts: other options to use to parse the input expressions.
5686
5687    Returns:
5688        The new condition.
5689    """
5690    this = condition(
5691        expression,
5692        dialect=dialect,
5693        copy=copy,
5694        **opts,
5695    )
5696    return Not(this=_wrap(this, Connector))
5697
5698
5699def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
5700    """
5701    Wrap an expression in parentheses.
5702
5703    Example:
5704        >>> paren("5 + 3").sql()
5705        '(5 + 3)'
5706
5707    Args:
5708        expression: the SQL code string to parse.
5709            If an Expression instance is passed, this is used as-is.
5710        copy: whether to copy the expression or not.
5711
5712    Returns:
5713        The wrapped expression.
5714    """
5715    return Paren(this=maybe_parse(expression, copy=copy))
5716
5717
5718SAFE_IDENTIFIER_RE = re.compile(r"^[_a-zA-Z][\w]*$")
5719
5720
5721@t.overload
5722def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None:
5723    ...
5724
5725
5726@t.overload
5727def to_identifier(
5728    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
5729) -> Identifier:
5730    ...
5731
5732
5733def to_identifier(name, quoted=None, copy=True):
5734    """Builds an identifier.
5735
5736    Args:
5737        name: The name to turn into an identifier.
5738        quoted: Whether or not force quote the identifier.
5739        copy: Whether or not to copy a passed in Identefier node.
5740
5741    Returns:
5742        The identifier ast node.
5743    """
5744
5745    if name is None:
5746        return None
5747
5748    if isinstance(name, Identifier):
5749        identifier = maybe_copy(name, copy)
5750    elif isinstance(name, str):
5751        identifier = Identifier(
5752            this=name,
5753            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
5754        )
5755    else:
5756        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
5757    return identifier
5758
5759
5760INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
5761
5762
5763def to_interval(interval: str | Literal) -> Interval:
5764    """Builds an interval expression from a string like '1 day' or '5 months'."""
5765    if isinstance(interval, Literal):
5766        if not interval.is_string:
5767            raise ValueError("Invalid interval string.")
5768
5769        interval = interval.this
5770
5771    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
5772
5773    if not interval_parts:
5774        raise ValueError("Invalid interval string.")
5775
5776    return Interval(
5777        this=Literal.string(interval_parts.group(1)),
5778        unit=Var(this=interval_parts.group(2)),
5779    )
5780
5781
5782@t.overload
5783def to_table(sql_path: str | Table, **kwargs) -> Table:
5784    ...
5785
5786
5787@t.overload
5788def to_table(sql_path: None, **kwargs) -> None:
5789    ...
5790
5791
5792def to_table(
5793    sql_path: t.Optional[str | Table], dialect: DialectType = None, **kwargs
5794) -> t.Optional[Table]:
5795    """
5796    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
5797    If a table is passed in then that table is returned.
5798
5799    Args:
5800        sql_path: a `[catalog].[schema].[table]` string.
5801        dialect: the source dialect according to which the table name will be parsed.
5802        kwargs: the kwargs to instantiate the resulting `Table` expression with.
5803
5804    Returns:
5805        A table expression.
5806    """
5807    if sql_path is None or isinstance(sql_path, Table):
5808        return sql_path
5809    if not isinstance(sql_path, str):
5810        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
5811
5812    table = maybe_parse(sql_path, into=Table, dialect=dialect)
5813    if table:
5814        for k, v in kwargs.items():
5815            table.set(k, v)
5816
5817    return table
5818
5819
5820def to_column(sql_path: str | Column, **kwargs) -> Column:
5821    """
5822    Create a column from a `[table].[column]` sql path. Schema is optional.
5823
5824    If a column is passed in then that column is returned.
5825
5826    Args:
5827        sql_path: `[table].[column]` string
5828    Returns:
5829        Table: A column expression
5830    """
5831    if sql_path is None or isinstance(sql_path, Column):
5832        return sql_path
5833    if not isinstance(sql_path, str):
5834        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
5835    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore
5836
5837
5838def alias_(
5839    expression: ExpOrStr,
5840    alias: str | Identifier,
5841    table: bool | t.Sequence[str | Identifier] = False,
5842    quoted: t.Optional[bool] = None,
5843    dialect: DialectType = None,
5844    copy: bool = True,
5845    **opts,
5846):
5847    """Create an Alias expression.
5848
5849    Example:
5850        >>> alias_('foo', 'bar').sql()
5851        'foo AS bar'
5852
5853        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
5854        '(SELECT 1, 2) AS bar(a, b)'
5855
5856    Args:
5857        expression: the SQL code strings to parse.
5858            If an Expression instance is passed, this is used as-is.
5859        alias: the alias name to use. If the name has
5860            special characters it is quoted.
5861        table: Whether or not to create a table alias, can also be a list of columns.
5862        quoted: whether or not to quote the alias
5863        dialect: the dialect used to parse the input expression.
5864        copy: Whether or not to copy the expression.
5865        **opts: other options to use to parse the input expressions.
5866
5867    Returns:
5868        Alias: the aliased expression
5869    """
5870    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5871    alias = to_identifier(alias, quoted=quoted)
5872
5873    if table:
5874        table_alias = TableAlias(this=alias)
5875        exp.set("alias", table_alias)
5876
5877        if not isinstance(table, bool):
5878            for column in table:
5879                table_alias.append("columns", to_identifier(column, quoted=quoted))
5880
5881        return exp
5882
5883    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
5884    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
5885    # for the complete Window expression.
5886    #
5887    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
5888
5889    if "alias" in exp.arg_types and not isinstance(exp, Window):
5890        exp.set("alias", alias)
5891        return exp
5892    return Alias(this=exp, alias=alias)
5893
5894
5895def subquery(
5896    expression: ExpOrStr,
5897    alias: t.Optional[Identifier | str] = None,
5898    dialect: DialectType = None,
5899    **opts,
5900) -> Select:
5901    """
5902    Build a subquery expression.
5903
5904    Example:
5905        >>> subquery('select x from tbl', 'bar').select('x').sql()
5906        'SELECT x FROM (SELECT x FROM tbl) AS bar'
5907
5908    Args:
5909        expression: the SQL code strings to parse.
5910            If an Expression instance is passed, this is used as-is.
5911        alias: the alias name to use.
5912        dialect: the dialect used to parse the input expression.
5913        **opts: other options to use to parse the input expressions.
5914
5915    Returns:
5916        A new Select instance with the subquery expression included.
5917    """
5918
5919    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
5920    return Select().from_(expression, dialect=dialect, **opts)
5921
5922
5923def column(
5924    col: str | Identifier,
5925    table: t.Optional[str | Identifier] = None,
5926    db: t.Optional[str | Identifier] = None,
5927    catalog: t.Optional[str | Identifier] = None,
5928    quoted: t.Optional[bool] = None,
5929) -> Column:
5930    """
5931    Build a Column.
5932
5933    Args:
5934        col: Column name.
5935        table: Table name.
5936        db: Database name.
5937        catalog: Catalog name.
5938        quoted: Whether to force quotes on the column's identifiers.
5939
5940    Returns:
5941        The new Column instance.
5942    """
5943    return Column(
5944        this=to_identifier(col, quoted=quoted),
5945        table=to_identifier(table, quoted=quoted),
5946        db=to_identifier(db, quoted=quoted),
5947        catalog=to_identifier(catalog, quoted=quoted),
5948    )
5949
5950
5951def cast(expression: ExpOrStr, to: str | DataType | DataType.Type, **opts) -> Cast:
5952    """Cast an expression to a data type.
5953
5954    Example:
5955        >>> cast('x + 1', 'int').sql()
5956        'CAST(x + 1 AS INT)'
5957
5958    Args:
5959        expression: The expression to cast.
5960        to: The datatype to cast to.
5961
5962    Returns:
5963        The new Cast instance.
5964    """
5965    expression = maybe_parse(expression, **opts)
5966    data_type = DataType.build(to, **opts)
5967    expression = Cast(this=expression, to=data_type)
5968    expression.type = data_type
5969    return expression
5970
5971
5972def table_(
5973    table: Identifier | str,
5974    db: t.Optional[Identifier | str] = None,
5975    catalog: t.Optional[Identifier | str] = None,
5976    quoted: t.Optional[bool] = None,
5977    alias: t.Optional[Identifier | str] = None,
5978) -> Table:
5979    """Build a Table.
5980
5981    Args:
5982        table: Table name.
5983        db: Database name.
5984        catalog: Catalog name.
5985        quote: Whether to force quotes on the table's identifiers.
5986        alias: Table's alias.
5987
5988    Returns:
5989        The new Table instance.
5990    """
5991    return Table(
5992        this=to_identifier(table, quoted=quoted) if table else None,
5993        db=to_identifier(db, quoted=quoted) if db else None,
5994        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
5995        alias=TableAlias(this=to_identifier(alias)) if alias else None,
5996    )
5997
5998
5999def values(
6000    values: t.Iterable[t.Tuple[t.Any, ...]],
6001    alias: t.Optional[str] = None,
6002    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6003) -> Values:
6004    """Build VALUES statement.
6005
6006    Example:
6007        >>> values([(1, '2')]).sql()
6008        "VALUES (1, '2')"
6009
6010    Args:
6011        values: values statements that will be converted to SQL
6012        alias: optional alias
6013        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6014         If either are provided then an alias is also required.
6015
6016    Returns:
6017        Values: the Values expression object
6018    """
6019    if columns and not alias:
6020        raise ValueError("Alias is required when providing columns")
6021
6022    return Values(
6023        expressions=[convert(tup) for tup in values],
6024        alias=(
6025            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6026            if columns
6027            else (TableAlias(this=to_identifier(alias)) if alias else None)
6028        ),
6029    )
6030
6031
6032def var(name: t.Optional[ExpOrStr]) -> Var:
6033    """Build a SQL variable.
6034
6035    Example:
6036        >>> repr(var('x'))
6037        '(VAR this: x)'
6038
6039        >>> repr(var(column('x', table='y')))
6040        '(VAR this: x)'
6041
6042    Args:
6043        name: The name of the var or an expression who's name will become the var.
6044
6045    Returns:
6046        The new variable node.
6047    """
6048    if not name:
6049        raise ValueError("Cannot convert empty name into var.")
6050
6051    if isinstance(name, Expression):
6052        name = name.name
6053    return Var(this=name)
6054
6055
6056def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6057    """Build ALTER TABLE... RENAME... expression
6058
6059    Args:
6060        old_name: The old name of the table
6061        new_name: The new name of the table
6062
6063    Returns:
6064        Alter table expression
6065    """
6066    old_table = to_table(old_name)
6067    new_table = to_table(new_name)
6068    return AlterTable(
6069        this=old_table,
6070        actions=[
6071            RenameTable(this=new_table),
6072        ],
6073    )
6074
6075
6076def convert(value: t.Any, copy: bool = False) -> Expression:
6077    """Convert a python value into an expression object.
6078
6079    Raises an error if a conversion is not possible.
6080
6081    Args:
6082        value: A python object.
6083        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6084
6085    Returns:
6086        Expression: the equivalent expression object.
6087    """
6088    if isinstance(value, Expression):
6089        return maybe_copy(value, copy)
6090    if isinstance(value, str):
6091        return Literal.string(value)
6092    if isinstance(value, bool):
6093        return Boolean(this=value)
6094    if value is None or (isinstance(value, float) and math.isnan(value)):
6095        return NULL
6096    if isinstance(value, numbers.Number):
6097        return Literal.number(value)
6098    if isinstance(value, datetime.datetime):
6099        datetime_literal = Literal.string(
6100            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6101        )
6102        return TimeStrToTime(this=datetime_literal)
6103    if isinstance(value, datetime.date):
6104        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6105        return DateStrToDate(this=date_literal)
6106    if isinstance(value, tuple):
6107        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6108    if isinstance(value, list):
6109        return Array(expressions=[convert(v, copy=copy) for v in value])
6110    if isinstance(value, dict):
6111        return Map(
6112            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6113            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6114        )
6115    raise ValueError(f"Cannot convert {value}")
6116
6117
6118def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6119    """
6120    Replace children of an expression with the result of a lambda fun(child) -> exp.
6121    """
6122    for k, v in expression.args.items():
6123        is_list_arg = type(v) is list
6124
6125        child_nodes = v if is_list_arg else [v]
6126        new_child_nodes = []
6127
6128        for cn in child_nodes:
6129            if isinstance(cn, Expression):
6130                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6131                    new_child_nodes.append(child_node)
6132                    child_node.parent = expression
6133                    child_node.arg_key = k
6134            else:
6135                new_child_nodes.append(cn)
6136
6137        expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0)
6138
6139
6140def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6141    """
6142    Return all table names referenced through columns in an expression.
6143
6144    Example:
6145        >>> import sqlglot
6146        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6147        ['a', 'c']
6148
6149    Args:
6150        expression: expression to find table names.
6151        exclude: a table name to exclude
6152
6153    Returns:
6154        A list of unique names.
6155    """
6156    return {
6157        table
6158        for table in (column.table for column in expression.find_all(Column))
6159        if table and table != exclude
6160    }
6161
6162
6163def table_name(table: Table | str, dialect: DialectType = None) -> str:
6164    """Get the full name of a table as a string.
6165
6166    Args:
6167        table: Table expression node or string.
6168        dialect: The dialect to generate the table name for.
6169
6170    Examples:
6171        >>> from sqlglot import exp, parse_one
6172        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6173        'a.b.c'
6174
6175    Returns:
6176        The table name.
6177    """
6178
6179    table = maybe_parse(table, into=Table)
6180
6181    if not table:
6182        raise ValueError(f"Cannot parse {table}")
6183
6184    return ".".join(
6185        part.sql(dialect=dialect, identify=True)
6186        if not SAFE_IDENTIFIER_RE.match(part.name)
6187        else part.name
6188        for part in table.parts
6189    )
6190
6191
6192def replace_tables(expression: E, mapping: t.Dict[str, str], copy: bool = True) -> E:
6193    """Replace all tables in expression according to the mapping.
6194
6195    Args:
6196        expression: expression node to be transformed and replaced.
6197        mapping: mapping of table names.
6198        copy: whether or not to copy the expression.
6199
6200    Examples:
6201        >>> from sqlglot import exp, parse_one
6202        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6203        'SELECT * FROM c'
6204
6205    Returns:
6206        The mapped expression.
6207    """
6208
6209    def _replace_tables(node: Expression) -> Expression:
6210        if isinstance(node, Table):
6211            new_name = mapping.get(table_name(node))
6212            if new_name:
6213                return to_table(
6214                    new_name,
6215                    **{k: v for k, v in node.args.items() if k not in ("this", "db", "catalog")},
6216                )
6217        return node
6218
6219    return expression.transform(_replace_tables, copy=copy)
6220
6221
6222def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6223    """Replace placeholders in an expression.
6224
6225    Args:
6226        expression: expression node to be transformed and replaced.
6227        args: positional names that will substitute unnamed placeholders in the given order.
6228        kwargs: keyword arguments that will substitute named placeholders.
6229
6230    Examples:
6231        >>> from sqlglot import exp, parse_one
6232        >>> replace_placeholders(
6233        ...     parse_one("select * from :tbl where ? = ?"),
6234        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6235        ... ).sql()
6236        "SELECT * FROM foo WHERE str_col = 'b'"
6237
6238    Returns:
6239        The mapped expression.
6240    """
6241
6242    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6243        if isinstance(node, Placeholder):
6244            if node.name:
6245                new_name = kwargs.get(node.name)
6246                if new_name:
6247                    return convert(new_name)
6248            else:
6249                try:
6250                    return convert(next(args))
6251                except StopIteration:
6252                    pass
6253        return node
6254
6255    return expression.transform(_replace_placeholders, iter(args), **kwargs)
6256
6257
6258def expand(
6259    expression: Expression, sources: t.Dict[str, Subqueryable], copy: bool = True
6260) -> Expression:
6261    """Transforms an expression by expanding all referenced sources into subqueries.
6262
6263    Examples:
6264        >>> from sqlglot import parse_one
6265        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6266        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6267
6268        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6269        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6270
6271    Args:
6272        expression: The expression to expand.
6273        sources: A dictionary of name to Subqueryables.
6274        copy: Whether or not to copy the expression during transformation. Defaults to True.
6275
6276    Returns:
6277        The transformed expression.
6278    """
6279
6280    def _expand(node: Expression):
6281        if isinstance(node, Table):
6282            name = table_name(node)
6283            source = sources.get(name)
6284            if source:
6285                subquery = source.subquery(node.alias or name)
6286                subquery.comments = [f"source: {name}"]
6287                return subquery.transform(_expand, copy=False)
6288        return node
6289
6290    return expression.transform(_expand, copy=copy)
6291
6292
6293def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func:
6294    """
6295    Returns a Func expression.
6296
6297    Examples:
6298        >>> func("abs", 5).sql()
6299        'ABS(5)'
6300
6301        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6302        'CAST(5 AS DOUBLE)'
6303
6304    Args:
6305        name: the name of the function to build.
6306        args: the args used to instantiate the function of interest.
6307        dialect: the source dialect.
6308        kwargs: the kwargs used to instantiate the function of interest.
6309
6310    Note:
6311        The arguments `args` and `kwargs` are mutually exclusive.
6312
6313    Returns:
6314        An instance of the function of interest, or an anonymous function, if `name` doesn't
6315        correspond to an existing `sqlglot.expressions.Func` class.
6316    """
6317    if args and kwargs:
6318        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6319
6320    from sqlglot.dialects.dialect import Dialect
6321
6322    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args]
6323    kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()}
6324
6325    parser = Dialect.get_or_raise(dialect)().parser()
6326    from_args_list = parser.FUNCTIONS.get(name.upper())
6327
6328    if from_args_list:
6329        function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs)  # type: ignore
6330    else:
6331        kwargs = kwargs or {"expressions": converted}
6332        function = Anonymous(this=name, **kwargs)
6333
6334    for error_message in function.error_messages(converted):
6335        raise ValueError(error_message)
6336
6337    return function
6338
6339
6340def true() -> Boolean:
6341    """
6342    Returns a true Boolean expression.
6343    """
6344    return Boolean(this=True)
6345
6346
6347def false() -> Boolean:
6348    """
6349    Returns a false Boolean expression.
6350    """
6351    return Boolean(this=False)
6352
6353
6354def null() -> Null:
6355    """
6356    Returns a Null expression.
6357    """
6358    return Null()
6359
6360
6361# TODO: deprecate this
6362TRUE = Boolean(this=True)
6363FALSE = Boolean(this=False)
6364NULL = 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.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>}
INTEGER_TYPES = {<Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.BIGINT: 'BIGINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.INT128: 'INT128'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>, <Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.BIGINT: 'BIGINT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.DATE: 'DATE'>}
@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 WeekOfYear(Func):
4395class WeekOfYear(Func):
4396    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4399class MonthsBetween(Func):
4400    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDateOfMonth(Func):
4403class LastDateOfMonth(Func):
4404    pass
key = 'lastdateofmonth'
class Extract(Func):
4407class Extract(Func):
4408    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4411class Timestamp(Func):
4412    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4415class TimestampAdd(Func, TimeUnit):
4416    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4419class TimestampSub(Func, TimeUnit):
4420    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4423class TimestampDiff(Func, TimeUnit):
4424    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4427class TimestampTrunc(Func, TimeUnit):
4428    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4431class TimeAdd(Func, TimeUnit):
4432    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4435class TimeSub(Func, TimeUnit):
4436    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4439class TimeDiff(Func, TimeUnit):
4440    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4443class TimeTrunc(Func, TimeUnit):
4444    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4447class DateFromParts(Func):
4448    _sql_names = ["DATEFROMPARTS"]
4449    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class DateStrToDate(Func):
4452class DateStrToDate(Func):
4453    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4456class DateToDateStr(Func):
4457    pass
key = 'datetodatestr'
class DateToDi(Func):
4460class DateToDi(Func):
4461    pass
key = 'datetodi'
class Date(Func):
4465class Date(Func):
4466    arg_types = {"this": False, "zone": False, "expressions": False}
4467    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4470class Day(Func):
4471    pass
key = 'day'
class Decode(Func):
4474class Decode(Func):
4475    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4478class DiToDate(Func):
4479    pass
key = 'ditodate'
class Encode(Func):
4482class Encode(Func):
4483    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4486class Exp(Func):
4487    pass
key = 'exp'
class Explode(Func):
4490class Explode(Func):
4491    pass
key = 'explode'
class Floor(Func):
4494class Floor(Func):
4495    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4498class FromBase64(Func):
4499    pass
key = 'frombase64'
class ToBase64(Func):
4502class ToBase64(Func):
4503    pass
key = 'tobase64'
class Greatest(Func):
4506class Greatest(Func):
4507    arg_types = {"this": True, "expressions": False}
4508    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4511class GroupConcat(AggFunc):
4512    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4515class Hex(Func):
4516    pass
key = 'hex'
class Xor(Connector, Func):
4519class Xor(Connector, Func):
4520    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4523class If(Func):
4524    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Initcap(Func):
4527class Initcap(Func):
4528    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4531class IsNan(Func):
4532    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class FormatJson(Expression):
4535class FormatJson(Expression):
4536    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4539class JSONKeyValue(Expression):
4540    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4543class JSONObject(Func):
4544    arg_types = {
4545        "expressions": False,
4546        "null_handling": False,
4547        "unique_keys": False,
4548        "return_type": False,
4549        "encoding": False,
4550    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4554class JSONArray(Func):
4555    arg_types = {
4556        "expressions": True,
4557        "null_handling": False,
4558        "return_type": False,
4559        "strict": False,
4560    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4564class JSONArrayAgg(Func):
4565    arg_types = {
4566        "this": True,
4567        "order": False,
4568        "null_handling": False,
4569        "return_type": False,
4570        "strict": False,
4571    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4576class JSONColumnDef(Expression):
4577    arg_types = {"this": True, "kind": False, "path": False}
arg_types = {'this': True, 'kind': False, 'path': False}
key = 'jsoncolumndef'
class JSONTable(Func):
4581class JSONTable(Func):
4582    arg_types = {
4583        "this": True,
4584        "expressions": True,
4585        "path": False,
4586        "error_handling": False,
4587        "empty_handling": False,
4588    }
arg_types = {'this': True, 'expressions': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4591class OpenJSONColumnDef(Expression):
4592    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):
4595class OpenJSON(Func):
4596    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4599class JSONBContains(Binary):
4600    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4603class JSONExtract(Binary, Func):
4604    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4607class JSONExtractScalar(JSONExtract):
4608    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4611class JSONBExtract(JSONExtract):
4612    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4615class JSONBExtractScalar(JSONExtract):
4616    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4619class JSONFormat(Func):
4620    arg_types = {"this": False, "options": False}
4621    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4625class JSONArrayContains(Binary, Predicate, Func):
4626    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4629class ParseJSON(Func):
4630    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4631    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
key = 'parsejson'
class Least(Func):
4634class Least(Func):
4635    arg_types = {"this": True, "expressions": False}
4636    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4639class Left(Func):
4640    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4647class Length(Func):
4648    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4651class Levenshtein(Func):
4652    arg_types = {
4653        "this": True,
4654        "expression": False,
4655        "ins_cost": False,
4656        "del_cost": False,
4657        "sub_cost": False,
4658    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4661class Ln(Func):
4662    pass
key = 'ln'
class Log(Func):
4665class Log(Func):
4666    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4669class Log2(Func):
4670    pass
key = 'log2'
class Log10(Func):
4673class Log10(Func):
4674    pass
key = 'log10'
class LogicalOr(AggFunc):
4677class LogicalOr(AggFunc):
4678    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4681class LogicalAnd(AggFunc):
4682    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4685class Lower(Func):
4686    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4689class Map(Func):
4690    arg_types = {"keys": False, "values": False}
arg_types = {'keys': False, 'values': False}
key = 'map'
class MapFromEntries(Func):
4693class MapFromEntries(Func):
4694    pass
key = 'mapfromentries'
class StarMap(Func):
4697class StarMap(Func):
4698    pass
key = 'starmap'
class VarMap(Func):
4701class VarMap(Func):
4702    arg_types = {"keys": True, "values": True}
4703    is_var_len_args = True
4704
4705    @property
4706    def keys(self) -> t.List[Expression]:
4707        return self.args["keys"].expressions
4708
4709    @property
4710    def values(self) -> t.List[Expression]:
4711        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):
4715class MatchAgainst(Func):
4716    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4719class Max(AggFunc):
4720    arg_types = {"this": True, "expressions": False}
4721    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
4724class MD5(Func):
4725    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
4729class MD5Digest(Func):
4730    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
4733class Min(AggFunc):
4734    arg_types = {"this": True, "expressions": False}
4735    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
4738class Month(Func):
4739    pass
key = 'month'
class Nvl2(Func):
4742class Nvl2(Func):
4743    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Posexplode(Func):
4746class Posexplode(Func):
4747    pass
key = 'posexplode'
class Pow(Binary, Func):
4750class Pow(Binary, Func):
4751    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
4754class PercentileCont(AggFunc):
4755    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
4758class PercentileDisc(AggFunc):
4759    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
4762class Quantile(AggFunc):
4763    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
4766class ApproxQuantile(Quantile):
4767    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):
4770class RangeN(Func):
4771    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
4774class ReadCSV(Func):
4775    _sql_names = ["READ_CSV"]
4776    is_var_len_args = True
4777    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
4780class Reduce(Func):
4781    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):
4784class RegexpExtract(Func):
4785    arg_types = {
4786        "this": True,
4787        "expression": True,
4788        "position": False,
4789        "occurrence": False,
4790        "parameters": False,
4791        "group": False,
4792    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
4795class RegexpReplace(Func):
4796    arg_types = {
4797        "this": True,
4798        "expression": True,
4799        "replacement": True,
4800        "position": False,
4801        "occurrence": False,
4802        "parameters": False,
4803    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
4806class RegexpLike(Binary, Func):
4807    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Func):
4810class RegexpILike(Func):
4811    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
4816class RegexpSplit(Func):
4817    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
4820class Repeat(Func):
4821    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
4824class Round(Func):
4825    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
4828class RowNumber(Func):
4829    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
4832class SafeDivide(Func):
4833    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SetAgg(AggFunc):
4836class SetAgg(AggFunc):
4837    pass
key = 'setagg'
class SHA(Func):
4840class SHA(Func):
4841    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
4844class SHA2(Func):
4845    _sql_names = ["SHA2"]
4846    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
4849class SortArray(Func):
4850    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
4853class Split(Func):
4854    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
4859class Substring(Func):
4860    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
4863class StandardHash(Func):
4864    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
4867class StartsWith(Func):
4868    _sql_names = ["STARTS_WITH", "STARTSWITH"]
4869    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
4872class StrPosition(Func):
4873    arg_types = {
4874        "this": True,
4875        "substr": True,
4876        "position": False,
4877        "instance": False,
4878    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
4881class StrToDate(Func):
4882    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
4885class StrToTime(Func):
4886    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
4891class StrToUnix(Func):
4892    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
4897class StrToMap(Func):
4898    arg_types = {
4899        "this": True,
4900        "pair_delim": False,
4901        "key_value_delim": False,
4902        "duplicate_resolution_callback": False,
4903    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
4906class NumberToStr(Func):
4907    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
4910class FromBase(Func):
4911    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
4914class Struct(Func):
4915    arg_types = {"expressions": True}
4916    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
4919class StructExtract(Func):
4920    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
4925class Stuff(Func):
4926    _sql_names = ["STUFF", "INSERT"]
4927    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):
4930class Sum(AggFunc):
4931    pass
key = 'sum'
class Sqrt(Func):
4934class Sqrt(Func):
4935    pass
key = 'sqrt'
class Stddev(AggFunc):
4938class Stddev(AggFunc):
4939    pass
key = 'stddev'
class StddevPop(AggFunc):
4942class StddevPop(AggFunc):
4943    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
4946class StddevSamp(AggFunc):
4947    pass
key = 'stddevsamp'
class TimeToStr(Func):
4950class TimeToStr(Func):
4951    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
4954class TimeToTimeStr(Func):
4955    pass
key = 'timetotimestr'
class TimeToUnix(Func):
4958class TimeToUnix(Func):
4959    pass
key = 'timetounix'
class TimeStrToDate(Func):
4962class TimeStrToDate(Func):
4963    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
4966class TimeStrToTime(Func):
4967    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
4970class TimeStrToUnix(Func):
4971    pass
key = 'timestrtounix'
class Trim(Func):
4974class Trim(Func):
4975    arg_types = {
4976        "this": True,
4977        "expression": False,
4978        "position": False,
4979        "collation": False,
4980    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
4983class TsOrDsAdd(Func, TimeUnit):
4984    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsadd'
class TsOrDsToDateStr(Func):
4987class TsOrDsToDateStr(Func):
4988    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
4991class TsOrDsToDate(Func):
4992    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDiToDi(Func):
4995class TsOrDiToDi(Func):
4996    pass
key = 'tsorditodi'
class Unhex(Func):
4999class Unhex(Func):
5000    pass
key = 'unhex'
class UnixToStr(Func):
5003class UnixToStr(Func):
5004    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5009class UnixToTime(Func):
5010    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5011
5012    SECONDS = Literal.string("seconds")
5013    MILLIS = Literal.string("millis")
5014    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):
5017class UnixToTimeStr(Func):
5018    pass
key = 'unixtotimestr'
class Upper(Func):
5021class Upper(Func):
5022    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5025class Variance(AggFunc):
5026    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5029class VariancePop(AggFunc):
5030    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5033class Week(Func):
5034    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5037class XMLTable(Func):
5038    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):
5041class Year(Func):
5042    pass
key = 'year'
class Use(Expression):
5045class Use(Expression):
5046    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5049class Merge(Expression):
5050    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):
5053class When(Func):
5054    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):
5059class NextValueFor(Func):
5060    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 '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:
5097def maybe_parse(
5098    sql_or_expression: ExpOrStr,
5099    *,
5100    into: t.Optional[IntoType] = None,
5101    dialect: DialectType = None,
5102    prefix: t.Optional[str] = None,
5103    copy: bool = False,
5104    **opts,
5105) -> Expression:
5106    """Gracefully handle a possible string or expression.
5107
5108    Example:
5109        >>> maybe_parse("1")
5110        (LITERAL this: 1, is_string: False)
5111        >>> maybe_parse(to_identifier("x"))
5112        (IDENTIFIER this: x, quoted: False)
5113
5114    Args:
5115        sql_or_expression: the SQL code string or an expression
5116        into: the SQLGlot Expression to parse into
5117        dialect: the dialect used to parse the input expressions (in the case that an
5118            input expression is a SQL string).
5119        prefix: a string to prefix the sql with before it gets parsed
5120            (automatically includes a space)
5121        copy: whether or not to copy the expression.
5122        **opts: other options to use to parse the input expressions (again, in the case
5123            that an input expression is a SQL string).
5124
5125    Returns:
5126        Expression: the parsed or given expression.
5127    """
5128    if isinstance(sql_or_expression, Expression):
5129        if copy:
5130            return sql_or_expression.copy()
5131        return sql_or_expression
5132
5133    if sql_or_expression is None:
5134        raise ParseError(f"SQL cannot be None")
5135
5136    import sqlglot
5137
5138    sql = str(sql_or_expression)
5139    if prefix:
5140        sql = f"{prefix} {sql}"
5141
5142    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):
5155def maybe_copy(instance, copy=True):
5156    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:
5337def union(
5338    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5339) -> Union:
5340    """
5341    Initializes a syntax tree from one UNION expression.
5342
5343    Example:
5344        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5345        'SELECT * FROM foo UNION SELECT * FROM bla'
5346
5347    Args:
5348        left: the SQL code string corresponding to the left-hand side.
5349            If an `Expression` instance is passed, it will be used as-is.
5350        right: the SQL code string corresponding to the right-hand side.
5351            If an `Expression` instance is passed, it will be used as-is.
5352        distinct: set the DISTINCT flag if and only if this is true.
5353        dialect: the dialect used to parse the input expression.
5354        opts: other options to use to parse the input expressions.
5355
5356    Returns:
5357        The new Union instance.
5358    """
5359    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5360    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5361
5362    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:
5365def intersect(
5366    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5367) -> Intersect:
5368    """
5369    Initializes a syntax tree from one INTERSECT expression.
5370
5371    Example:
5372        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5373        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5374
5375    Args:
5376        left: the SQL code string corresponding to the left-hand side.
5377            If an `Expression` instance is passed, it will be used as-is.
5378        right: the SQL code string corresponding to the right-hand side.
5379            If an `Expression` instance is passed, it will be used as-is.
5380        distinct: set the DISTINCT flag if and only if this is true.
5381        dialect: the dialect used to parse the input expression.
5382        opts: other options to use to parse the input expressions.
5383
5384    Returns:
5385        The new Intersect instance.
5386    """
5387    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5388    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5389
5390    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:
5393def except_(
5394    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5395) -> Except:
5396    """
5397    Initializes a syntax tree from one EXCEPT expression.
5398
5399    Example:
5400        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5401        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5402
5403    Args:
5404        left: the SQL code string corresponding to the left-hand side.
5405            If an `Expression` instance is passed, it will be used as-is.
5406        right: the SQL code string corresponding to the right-hand side.
5407            If an `Expression` instance is passed, it will be used as-is.
5408        distinct: set the DISTINCT flag if and only if this is true.
5409        dialect: the dialect used to parse the input expression.
5410        opts: other options to use to parse the input expressions.
5411
5412    Returns:
5413        The new Except instance.
5414    """
5415    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5416    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5417
5418    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:
5421def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5422    """
5423    Initializes a syntax tree from one or multiple SELECT expressions.
5424
5425    Example:
5426        >>> select("col1", "col2").from_("tbl").sql()
5427        'SELECT col1, col2 FROM tbl'
5428
5429    Args:
5430        *expressions: the SQL code string to parse as the expressions of a
5431            SELECT statement. If an Expression instance is passed, this is used as-is.
5432        dialect: the dialect used to parse the input expressions (in the case that an
5433            input expression is a SQL string).
5434        **opts: other options to use to parse the input expressions (again, in the case
5435            that an input expression is a SQL string).
5436
5437    Returns:
5438        Select: the syntax tree for the SELECT statement.
5439    """
5440    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:
5443def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5444    """
5445    Initializes a syntax tree from a FROM expression.
5446
5447    Example:
5448        >>> from_("tbl").select("col1", "col2").sql()
5449        'SELECT col1, col2 FROM tbl'
5450
5451    Args:
5452        *expression: the SQL code string to parse as the FROM expressions of a
5453            SELECT statement. If an Expression instance is passed, this is used as-is.
5454        dialect: the dialect used to parse the input expression (in the case that the
5455            input expression is a SQL string).
5456        **opts: other options to use to parse the input expressions (again, in the case
5457            that the input expression is a SQL string).
5458
5459    Returns:
5460        Select: the syntax tree for the SELECT statement.
5461    """
5462    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:
5465def update(
5466    table: str | Table,
5467    properties: dict,
5468    where: t.Optional[ExpOrStr] = None,
5469    from_: t.Optional[ExpOrStr] = None,
5470    dialect: DialectType = None,
5471    **opts,
5472) -> Update:
5473    """
5474    Creates an update statement.
5475
5476    Example:
5477        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5478        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5479
5480    Args:
5481        *properties: dictionary of properties to set which are
5482            auto converted to sql objects eg None -> NULL
5483        where: sql conditional parsed into a WHERE statement
5484        from_: sql statement parsed into a FROM statement
5485        dialect: the dialect used to parse the input expressions.
5486        **opts: other options to use to parse the input expressions.
5487
5488    Returns:
5489        Update: the syntax tree for the UPDATE statement.
5490    """
5491    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5492    update_expr.set(
5493        "expressions",
5494        [
5495            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5496            for k, v in properties.items()
5497        ],
5498    )
5499    if from_:
5500        update_expr.set(
5501            "from",
5502            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5503        )
5504    if isinstance(where, Condition):
5505        where = Where(this=where)
5506    if where:
5507        update_expr.set(
5508            "where",
5509            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5510        )
5511    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:
5514def delete(
5515    table: ExpOrStr,
5516    where: t.Optional[ExpOrStr] = None,
5517    returning: t.Optional[ExpOrStr] = None,
5518    dialect: DialectType = None,
5519    **opts,
5520) -> Delete:
5521    """
5522    Builds a delete statement.
5523
5524    Example:
5525        >>> delete("my_table", where="id > 1").sql()
5526        'DELETE FROM my_table WHERE id > 1'
5527
5528    Args:
5529        where: sql conditional parsed into a WHERE statement
5530        returning: sql conditional parsed into a RETURNING statement
5531        dialect: the dialect used to parse the input expressions.
5532        **opts: other options to use to parse the input expressions.
5533
5534    Returns:
5535        Delete: the syntax tree for the DELETE statement.
5536    """
5537    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5538    if where:
5539        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5540    if returning:
5541        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5542    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:
5545def insert(
5546    expression: ExpOrStr,
5547    into: ExpOrStr,
5548    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5549    overwrite: t.Optional[bool] = None,
5550    dialect: DialectType = None,
5551    copy: bool = True,
5552    **opts,
5553) -> Insert:
5554    """
5555    Builds an INSERT statement.
5556
5557    Example:
5558        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5559        'INSERT INTO tbl VALUES (1, 2, 3)'
5560
5561    Args:
5562        expression: the sql string or expression of the INSERT statement
5563        into: the tbl to insert data to.
5564        columns: optionally the table's column names.
5565        overwrite: whether to INSERT OVERWRITE or not.
5566        dialect: the dialect used to parse the input expressions.
5567        copy: whether or not to copy the expression.
5568        **opts: other options to use to parse the input expressions.
5569
5570    Returns:
5571        Insert: the syntax tree for the INSERT statement.
5572    """
5573    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5574    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5575
5576    if columns:
5577        this = _apply_list_builder(
5578            *columns,
5579            instance=Schema(this=this),
5580            arg="expressions",
5581            into=Identifier,
5582            copy=False,
5583            dialect=dialect,
5584            **opts,
5585        )
5586
5587    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:
5590def condition(
5591    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5592) -> Condition:
5593    """
5594    Initialize a logical condition expression.
5595
5596    Example:
5597        >>> condition("x=1").sql()
5598        'x = 1'
5599
5600        This is helpful for composing larger logical syntax trees:
5601        >>> where = condition("x=1")
5602        >>> where = where.and_("y=1")
5603        >>> Select().from_("tbl").select("*").where(where).sql()
5604        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5605
5606    Args:
5607        *expression: the SQL code string to parse.
5608            If an Expression instance is passed, this is used as-is.
5609        dialect: the dialect used to parse the input expression (in the case that the
5610            input expression is a SQL string).
5611        copy: Whether or not to copy `expression` (only applies to expressions).
5612        **opts: other options to use to parse the input expressions (again, in the case
5613            that the input expression is a SQL string).
5614
5615    Returns:
5616        The new Condition instance
5617    """
5618    return maybe_parse(
5619        expression,
5620        into=Condition,
5621        dialect=dialect,
5622        copy=copy,
5623        **opts,
5624    )

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

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

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

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

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

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

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

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

Returns a true Boolean expression.

def false() -> Boolean:
6348def false() -> Boolean:
6349    """
6350    Returns a false Boolean expression.
6351    """
6352    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6355def null() -> Null:
6356    """
6357    Returns a Null expression.
6358    """
6359    return Null()

Returns a Null expression.

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