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        UNIQUEIDENTIFIER = auto()
3585        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3586        USERDEFINED = "USER-DEFINED"
3587        USMALLINT = auto()
3588        UTINYINT = auto()
3589        UUID = auto()
3590        VARBINARY = auto()
3591        VARCHAR = auto()
3592        VARIANT = auto()
3593        XML = auto()
3594        YEAR = auto()
3595
3596    TEXT_TYPES = {
3597        Type.CHAR,
3598        Type.NCHAR,
3599        Type.VARCHAR,
3600        Type.NVARCHAR,
3601        Type.TEXT,
3602    }
3603
3604    INTEGER_TYPES = {
3605        Type.INT,
3606        Type.TINYINT,
3607        Type.SMALLINT,
3608        Type.BIGINT,
3609        Type.INT128,
3610        Type.INT256,
3611    }
3612
3613    FLOAT_TYPES = {
3614        Type.FLOAT,
3615        Type.DOUBLE,
3616    }
3617
3618    NUMERIC_TYPES = {
3619        *INTEGER_TYPES,
3620        *FLOAT_TYPES,
3621    }
3622
3623    TEMPORAL_TYPES = {
3624        Type.TIME,
3625        Type.TIMETZ,
3626        Type.TIMESTAMP,
3627        Type.TIMESTAMPTZ,
3628        Type.TIMESTAMPLTZ,
3629        Type.DATE,
3630        Type.DATETIME,
3631        Type.DATETIME64,
3632    }
3633
3634    @classmethod
3635    def build(
3636        cls,
3637        dtype: str | DataType | DataType.Type,
3638        dialect: DialectType = None,
3639        udt: bool = False,
3640        **kwargs,
3641    ) -> DataType:
3642        """
3643        Constructs a DataType object.
3644
3645        Args:
3646            dtype: the data type of interest.
3647            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3648            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3649                DataType, thus creating a user-defined type.
3650            kawrgs: additional arguments to pass in the constructor of DataType.
3651
3652        Returns:
3653            The constructed DataType object.
3654        """
3655        from sqlglot import parse_one
3656
3657        if isinstance(dtype, str):
3658            if dtype.upper() == "UNKNOWN":
3659                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3660
3661            try:
3662                data_type_exp = parse_one(dtype, read=dialect, into=DataType)
3663            except ParseError:
3664                if udt:
3665                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3666                raise
3667        elif isinstance(dtype, DataType.Type):
3668            data_type_exp = DataType(this=dtype)
3669        elif isinstance(dtype, DataType):
3670            return dtype
3671        else:
3672            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3673
3674        return DataType(**{**data_type_exp.args, **kwargs})
3675
3676    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
3677        """
3678        Checks whether this DataType matches one of the provided data types. Nested types or precision
3679        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3680
3681        Args:
3682            dtypes: the data types to compare this DataType to.
3683
3684        Returns:
3685            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3686        """
3687        for dtype in dtypes:
3688            other = DataType.build(dtype, udt=True)
3689
3690            if (
3691                other.expressions
3692                or self.this == DataType.Type.USERDEFINED
3693                or other.this == DataType.Type.USERDEFINED
3694            ):
3695                matches = self == other
3696            else:
3697                matches = self.this == other.this
3698
3699            if matches:
3700                return True
3701        return False
3702
3703
3704# https://www.postgresql.org/docs/15/datatype-pseudo.html
3705class PseudoType(DataType):
3706    arg_types = {"this": True}
3707
3708
3709# https://www.postgresql.org/docs/15/datatype-oid.html
3710class ObjectIdentifier(DataType):
3711    arg_types = {"this": True}
3712
3713
3714# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
3715class SubqueryPredicate(Predicate):
3716    pass
3717
3718
3719class All(SubqueryPredicate):
3720    pass
3721
3722
3723class Any(SubqueryPredicate):
3724    pass
3725
3726
3727class Exists(SubqueryPredicate):
3728    pass
3729
3730
3731# Commands to interact with the databases or engines. For most of the command
3732# expressions we parse whatever comes after the command's name as a string.
3733class Command(Expression):
3734    arg_types = {"this": True, "expression": False}
3735
3736
3737class Transaction(Expression):
3738    arg_types = {"this": False, "modes": False, "mark": False}
3739
3740
3741class Commit(Expression):
3742    arg_types = {"chain": False, "this": False, "durability": False}
3743
3744
3745class Rollback(Expression):
3746    arg_types = {"savepoint": False, "this": False}
3747
3748
3749class AlterTable(Expression):
3750    arg_types = {"this": True, "actions": True, "exists": False, "only": False}
3751
3752
3753class AddConstraint(Expression):
3754    arg_types = {"this": False, "expression": False, "enforced": False}
3755
3756
3757class DropPartition(Expression):
3758    arg_types = {"expressions": True, "exists": False}
3759
3760
3761# Binary expressions like (ADD a b)
3762class Binary(Condition):
3763    arg_types = {"this": True, "expression": True}
3764
3765    @property
3766    def left(self):
3767        return self.this
3768
3769    @property
3770    def right(self):
3771        return self.expression
3772
3773
3774class Add(Binary):
3775    pass
3776
3777
3778class Connector(Binary):
3779    pass
3780
3781
3782class And(Connector):
3783    pass
3784
3785
3786class Or(Connector):
3787    pass
3788
3789
3790class BitwiseAnd(Binary):
3791    pass
3792
3793
3794class BitwiseLeftShift(Binary):
3795    pass
3796
3797
3798class BitwiseOr(Binary):
3799    pass
3800
3801
3802class BitwiseRightShift(Binary):
3803    pass
3804
3805
3806class BitwiseXor(Binary):
3807    pass
3808
3809
3810class Div(Binary):
3811    pass
3812
3813
3814class Overlaps(Binary):
3815    pass
3816
3817
3818class Dot(Binary):
3819    @property
3820    def name(self) -> str:
3821        return self.expression.name
3822
3823    @property
3824    def output_name(self) -> str:
3825        return self.name
3826
3827    @classmethod
3828    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3829        """Build a Dot object with a sequence of expressions."""
3830        if len(expressions) < 2:
3831            raise ValueError(f"Dot requires >= 2 expressions.")
3832
3833        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
3834
3835
3836class DPipe(Binary):
3837    pass
3838
3839
3840class SafeDPipe(DPipe):
3841    pass
3842
3843
3844class EQ(Binary, Predicate):
3845    pass
3846
3847
3848class NullSafeEQ(Binary, Predicate):
3849    pass
3850
3851
3852class NullSafeNEQ(Binary, Predicate):
3853    pass
3854
3855
3856class Distance(Binary):
3857    pass
3858
3859
3860class Escape(Binary):
3861    pass
3862
3863
3864class Glob(Binary, Predicate):
3865    pass
3866
3867
3868class GT(Binary, Predicate):
3869    pass
3870
3871
3872class GTE(Binary, Predicate):
3873    pass
3874
3875
3876class ILike(Binary, Predicate):
3877    pass
3878
3879
3880class ILikeAny(Binary, Predicate):
3881    pass
3882
3883
3884class IntDiv(Binary):
3885    pass
3886
3887
3888class Is(Binary, Predicate):
3889    pass
3890
3891
3892class Kwarg(Binary):
3893    """Kwarg in special functions like func(kwarg => y)."""
3894
3895
3896class Like(Binary, Predicate):
3897    pass
3898
3899
3900class LikeAny(Binary, Predicate):
3901    pass
3902
3903
3904class LT(Binary, Predicate):
3905    pass
3906
3907
3908class LTE(Binary, Predicate):
3909    pass
3910
3911
3912class Mod(Binary):
3913    pass
3914
3915
3916class Mul(Binary):
3917    pass
3918
3919
3920class NEQ(Binary, Predicate):
3921    pass
3922
3923
3924class SimilarTo(Binary, Predicate):
3925    pass
3926
3927
3928class Slice(Binary):
3929    arg_types = {"this": False, "expression": False}
3930
3931
3932class Sub(Binary):
3933    pass
3934
3935
3936class ArrayOverlaps(Binary):
3937    pass
3938
3939
3940# Unary Expressions
3941# (NOT a)
3942class Unary(Condition):
3943    pass
3944
3945
3946class BitwiseNot(Unary):
3947    pass
3948
3949
3950class Not(Unary):
3951    pass
3952
3953
3954class Paren(Unary):
3955    arg_types = {"this": True, "with": False}
3956
3957    @property
3958    def output_name(self) -> str:
3959        return self.this.name
3960
3961
3962class Neg(Unary):
3963    pass
3964
3965
3966class Alias(Expression):
3967    arg_types = {"this": True, "alias": False}
3968
3969    @property
3970    def output_name(self) -> str:
3971        return self.alias
3972
3973
3974class Aliases(Expression):
3975    arg_types = {"this": True, "expressions": True}
3976
3977    @property
3978    def aliases(self):
3979        return self.expressions
3980
3981
3982class AtTimeZone(Expression):
3983    arg_types = {"this": True, "zone": True}
3984
3985
3986class Between(Predicate):
3987    arg_types = {"this": True, "low": True, "high": True}
3988
3989
3990class Bracket(Condition):
3991    arg_types = {"this": True, "expressions": True}
3992
3993    @property
3994    def output_name(self) -> str:
3995        if len(self.expressions) == 1:
3996            return self.expressions[0].output_name
3997
3998        return super().output_name
3999
4000
4001class SafeBracket(Bracket):
4002    """Represents array lookup where OOB index yields NULL instead of causing a failure."""
4003
4004
4005class Distinct(Expression):
4006    arg_types = {"expressions": False, "on": False}
4007
4008
4009class In(Predicate):
4010    arg_types = {
4011        "this": True,
4012        "expressions": False,
4013        "query": False,
4014        "unnest": False,
4015        "field": False,
4016        "is_global": False,
4017    }
4018
4019
4020class TimeUnit(Expression):
4021    """Automatically converts unit arg into a var."""
4022
4023    arg_types = {"unit": False}
4024
4025    def __init__(self, **args):
4026        unit = args.get("unit")
4027        if isinstance(unit, (Column, Literal)):
4028            args["unit"] = Var(this=unit.name)
4029        elif isinstance(unit, Week):
4030            unit.set("this", Var(this=unit.this.name))
4031
4032        super().__init__(**args)
4033
4034    @property
4035    def unit(self) -> t.Optional[Var]:
4036        return self.args.get("unit")
4037
4038
4039# https://www.oracletutorial.com/oracle-basics/oracle-interval/
4040# https://trino.io/docs/current/language/types.html#interval-day-to-second
4041# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
4042class IntervalSpan(DataType):
4043    arg_types = {"this": True, "expression": True}
4044
4045
4046class Interval(TimeUnit):
4047    arg_types = {"this": False, "unit": False}
4048
4049
4050class IgnoreNulls(Expression):
4051    pass
4052
4053
4054class RespectNulls(Expression):
4055    pass
4056
4057
4058# Functions
4059class Func(Condition):
4060    """
4061    The base class for all function expressions.
4062
4063    Attributes:
4064        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4065            treated as a variable length argument and the argument's value will be stored as a list.
4066        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4067            for this function expression. These values are used to map this node to a name during parsing
4068            as well as to provide the function's name during SQL string generation. By default the SQL
4069            name is set to the expression's class name transformed to snake case.
4070    """
4071
4072    is_var_len_args = False
4073
4074    @classmethod
4075    def from_arg_list(cls, args):
4076        if cls.is_var_len_args:
4077            all_arg_keys = list(cls.arg_types)
4078            # If this function supports variable length argument treat the last argument as such.
4079            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4080            num_non_var = len(non_var_len_arg_keys)
4081
4082            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4083            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4084        else:
4085            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4086
4087        return cls(**args_dict)
4088
4089    @classmethod
4090    def sql_names(cls):
4091        if cls is Func:
4092            raise NotImplementedError(
4093                "SQL name is only supported by concrete function implementations"
4094            )
4095        if "_sql_names" not in cls.__dict__:
4096            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4097        return cls._sql_names
4098
4099    @classmethod
4100    def sql_name(cls):
4101        return cls.sql_names()[0]
4102
4103    @classmethod
4104    def default_parser_mappings(cls):
4105        return {name: cls.from_arg_list for name in cls.sql_names()}
4106
4107
4108class AggFunc(Func):
4109    pass
4110
4111
4112class ParameterizedAgg(AggFunc):
4113    arg_types = {"this": True, "expressions": True, "params": True}
4114
4115
4116class Abs(Func):
4117    pass
4118
4119
4120# https://spark.apache.org/docs/latest/api/sql/index.html#transform
4121class Transform(Func):
4122    arg_types = {"this": True, "expression": True}
4123
4124
4125class Anonymous(Func):
4126    arg_types = {"this": True, "expressions": False}
4127    is_var_len_args = True
4128
4129
4130# https://docs.snowflake.com/en/sql-reference/functions/hll
4131# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
4132class Hll(AggFunc):
4133    arg_types = {"this": True, "expressions": False}
4134    is_var_len_args = True
4135
4136
4137class ApproxDistinct(AggFunc):
4138    arg_types = {"this": True, "accuracy": False}
4139    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
4140
4141
4142class Array(Func):
4143    arg_types = {"expressions": False}
4144    is_var_len_args = True
4145
4146
4147# https://docs.snowflake.com/en/sql-reference/functions/to_char
4148class ToChar(Func):
4149    arg_types = {"this": True, "format": False}
4150
4151
4152class GenerateSeries(Func):
4153    arg_types = {"start": True, "end": True, "step": False}
4154
4155
4156class ArrayAgg(AggFunc):
4157    pass
4158
4159
4160class ArrayAll(Func):
4161    arg_types = {"this": True, "expression": True}
4162
4163
4164class ArrayAny(Func):
4165    arg_types = {"this": True, "expression": True}
4166
4167
4168class ArrayConcat(Func):
4169    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4170    arg_types = {"this": True, "expressions": False}
4171    is_var_len_args = True
4172
4173
4174class ArrayContains(Binary, Func):
4175    pass
4176
4177
4178class ArrayContained(Binary):
4179    pass
4180
4181
4182class ArrayFilter(Func):
4183    arg_types = {"this": True, "expression": True}
4184    _sql_names = ["FILTER", "ARRAY_FILTER"]
4185
4186
4187class ArrayJoin(Func):
4188    arg_types = {"this": True, "expression": True, "null": False}
4189
4190
4191class ArraySize(Func):
4192    arg_types = {"this": True, "expression": False}
4193
4194
4195class ArraySort(Func):
4196    arg_types = {"this": True, "expression": False}
4197
4198
4199class ArraySum(Func):
4200    pass
4201
4202
4203class ArrayUnionAgg(AggFunc):
4204    pass
4205
4206
4207class Avg(AggFunc):
4208    pass
4209
4210
4211class AnyValue(AggFunc):
4212    arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False}
4213
4214
4215class First(Func):
4216    arg_types = {"this": True, "ignore_nulls": False}
4217
4218
4219class Last(Func):
4220    arg_types = {"this": True, "ignore_nulls": False}
4221
4222
4223class Case(Func):
4224    arg_types = {"this": False, "ifs": True, "default": False}
4225
4226    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4227        instance = maybe_copy(self, copy)
4228        instance.append(
4229            "ifs",
4230            If(
4231                this=maybe_parse(condition, copy=copy, **opts),
4232                true=maybe_parse(then, copy=copy, **opts),
4233            ),
4234        )
4235        return instance
4236
4237    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4238        instance = maybe_copy(self, copy)
4239        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4240        return instance
4241
4242
4243class Cast(Func):
4244    arg_types = {"this": True, "to": True, "format": False}
4245
4246    @property
4247    def name(self) -> str:
4248        return self.this.name
4249
4250    @property
4251    def to(self) -> DataType:
4252        return self.args["to"]
4253
4254    @property
4255    def output_name(self) -> str:
4256        return self.name
4257
4258    def is_type(self, *dtypes: str | DataType | DataType.Type) -> bool:
4259        """
4260        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4261        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4262        array<int> != array<float>.
4263
4264        Args:
4265            dtypes: the data types to compare this Cast's DataType to.
4266
4267        Returns:
4268            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4269        """
4270        return self.to.is_type(*dtypes)
4271
4272
4273class TryCast(Cast):
4274    pass
4275
4276
4277class CastToStrType(Func):
4278    arg_types = {"this": True, "to": True}
4279
4280
4281class Collate(Binary):
4282    pass
4283
4284
4285class Ceil(Func):
4286    arg_types = {"this": True, "decimals": False}
4287    _sql_names = ["CEIL", "CEILING"]
4288
4289
4290class Coalesce(Func):
4291    arg_types = {"this": True, "expressions": False}
4292    is_var_len_args = True
4293    _sql_names = ["COALESCE", "IFNULL", "NVL"]
4294
4295
4296class Chr(Func):
4297    arg_types = {"this": True, "charset": False, "expressions": False}
4298    is_var_len_args = True
4299    _sql_names = ["CHR", "CHAR"]
4300
4301
4302class Concat(Func):
4303    arg_types = {"expressions": True}
4304    is_var_len_args = True
4305
4306
4307class SafeConcat(Concat):
4308    pass
4309
4310
4311class ConcatWs(Concat):
4312    _sql_names = ["CONCAT_WS"]
4313
4314
4315class Count(AggFunc):
4316    arg_types = {"this": False, "expressions": False}
4317    is_var_len_args = True
4318
4319
4320class CountIf(AggFunc):
4321    pass
4322
4323
4324class CurrentDate(Func):
4325    arg_types = {"this": False}
4326
4327
4328class CurrentDatetime(Func):
4329    arg_types = {"this": False}
4330
4331
4332class CurrentTime(Func):
4333    arg_types = {"this": False}
4334
4335
4336class CurrentTimestamp(Func):
4337    arg_types = {"this": False}
4338
4339
4340class CurrentUser(Func):
4341    arg_types = {"this": False}
4342
4343
4344class DateAdd(Func, TimeUnit):
4345    arg_types = {"this": True, "expression": True, "unit": False}
4346
4347
4348class DateSub(Func, TimeUnit):
4349    arg_types = {"this": True, "expression": True, "unit": False}
4350
4351
4352class DateDiff(Func, TimeUnit):
4353    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4354    arg_types = {"this": True, "expression": True, "unit": False}
4355
4356
4357class DateTrunc(Func):
4358    arg_types = {"unit": True, "this": True, "zone": False}
4359
4360    @property
4361    def unit(self) -> Expression:
4362        return self.args["unit"]
4363
4364
4365class DatetimeAdd(Func, TimeUnit):
4366    arg_types = {"this": True, "expression": True, "unit": False}
4367
4368
4369class DatetimeSub(Func, TimeUnit):
4370    arg_types = {"this": True, "expression": True, "unit": False}
4371
4372
4373class DatetimeDiff(Func, TimeUnit):
4374    arg_types = {"this": True, "expression": True, "unit": False}
4375
4376
4377class DatetimeTrunc(Func, TimeUnit):
4378    arg_types = {"this": True, "unit": True, "zone": False}
4379
4380
4381class DayOfWeek(Func):
4382    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
4383
4384
4385class DayOfMonth(Func):
4386    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
4387
4388
4389class DayOfYear(Func):
4390    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
4391
4392
4393class WeekOfYear(Func):
4394    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
4395
4396
4397class MonthsBetween(Func):
4398    arg_types = {"this": True, "expression": True, "roundoff": False}
4399
4400
4401class LastDateOfMonth(Func):
4402    pass
4403
4404
4405class Extract(Func):
4406    arg_types = {"this": True, "expression": True}
4407
4408
4409class Timestamp(Func):
4410    arg_types = {"this": False, "expression": False}
4411
4412
4413class TimestampAdd(Func, TimeUnit):
4414    arg_types = {"this": True, "expression": True, "unit": False}
4415
4416
4417class TimestampSub(Func, TimeUnit):
4418    arg_types = {"this": True, "expression": True, "unit": False}
4419
4420
4421class TimestampDiff(Func, TimeUnit):
4422    arg_types = {"this": True, "expression": True, "unit": False}
4423
4424
4425class TimestampTrunc(Func, TimeUnit):
4426    arg_types = {"this": True, "unit": True, "zone": False}
4427
4428
4429class TimeAdd(Func, TimeUnit):
4430    arg_types = {"this": True, "expression": True, "unit": False}
4431
4432
4433class TimeSub(Func, TimeUnit):
4434    arg_types = {"this": True, "expression": True, "unit": False}
4435
4436
4437class TimeDiff(Func, TimeUnit):
4438    arg_types = {"this": True, "expression": True, "unit": False}
4439
4440
4441class TimeTrunc(Func, TimeUnit):
4442    arg_types = {"this": True, "unit": True, "zone": False}
4443
4444
4445class DateFromParts(Func):
4446    _sql_names = ["DATEFROMPARTS"]
4447    arg_types = {"year": True, "month": True, "day": True}
4448
4449
4450class DateStrToDate(Func):
4451    pass
4452
4453
4454class DateToDateStr(Func):
4455    pass
4456
4457
4458class DateToDi(Func):
4459    pass
4460
4461
4462# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
4463class Date(Func):
4464    arg_types = {"this": False, "zone": False, "expressions": False}
4465    is_var_len_args = True
4466
4467
4468class Day(Func):
4469    pass
4470
4471
4472class Decode(Func):
4473    arg_types = {"this": True, "charset": True, "replace": False}
4474
4475
4476class DiToDate(Func):
4477    pass
4478
4479
4480class Encode(Func):
4481    arg_types = {"this": True, "charset": True}
4482
4483
4484class Exp(Func):
4485    pass
4486
4487
4488class Explode(Func):
4489    pass
4490
4491
4492class Floor(Func):
4493    arg_types = {"this": True, "decimals": False}
4494
4495
4496class FromBase64(Func):
4497    pass
4498
4499
4500class ToBase64(Func):
4501    pass
4502
4503
4504class Greatest(Func):
4505    arg_types = {"this": True, "expressions": False}
4506    is_var_len_args = True
4507
4508
4509class GroupConcat(AggFunc):
4510    arg_types = {"this": True, "separator": False}
4511
4512
4513class Hex(Func):
4514    pass
4515
4516
4517class Xor(Connector, Func):
4518    arg_types = {"this": False, "expression": False, "expressions": False}
4519
4520
4521class If(Func):
4522    arg_types = {"this": True, "true": True, "false": False}
4523
4524
4525class Initcap(Func):
4526    arg_types = {"this": True, "expression": False}
4527
4528
4529class IsNan(Func):
4530    _sql_names = ["IS_NAN", "ISNAN"]
4531
4532
4533class FormatJson(Expression):
4534    pass
4535
4536
4537class JSONKeyValue(Expression):
4538    arg_types = {"this": True, "expression": True}
4539
4540
4541class JSONObject(Func):
4542    arg_types = {
4543        "expressions": False,
4544        "null_handling": False,
4545        "unique_keys": False,
4546        "return_type": False,
4547        "encoding": False,
4548    }
4549
4550
4551# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
4552class JSONArray(Func):
4553    arg_types = {
4554        "expressions": True,
4555        "null_handling": False,
4556        "return_type": False,
4557        "strict": False,
4558    }
4559
4560
4561# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
4562class JSONArrayAgg(Func):
4563    arg_types = {
4564        "this": True,
4565        "order": False,
4566        "null_handling": False,
4567        "return_type": False,
4568        "strict": False,
4569    }
4570
4571
4572# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4573# Note: parsing of JSON column definitions is currently incomplete.
4574class JSONColumnDef(Expression):
4575    arg_types = {"this": True, "kind": False, "path": False}
4576
4577
4578# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4579class JSONTable(Func):
4580    arg_types = {
4581        "this": True,
4582        "expressions": True,
4583        "path": False,
4584        "error_handling": False,
4585        "empty_handling": False,
4586    }
4587
4588
4589class OpenJSONColumnDef(Expression):
4590    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
4591
4592
4593class OpenJSON(Func):
4594    arg_types = {"this": True, "path": False, "expressions": False}
4595
4596
4597class JSONBContains(Binary):
4598    _sql_names = ["JSONB_CONTAINS"]
4599
4600
4601class JSONExtract(Binary, Func):
4602    _sql_names = ["JSON_EXTRACT"]
4603
4604
4605class JSONExtractScalar(JSONExtract):
4606    _sql_names = ["JSON_EXTRACT_SCALAR"]
4607
4608
4609class JSONBExtract(JSONExtract):
4610    _sql_names = ["JSONB_EXTRACT"]
4611
4612
4613class JSONBExtractScalar(JSONExtract):
4614    _sql_names = ["JSONB_EXTRACT_SCALAR"]
4615
4616
4617class JSONFormat(Func):
4618    arg_types = {"this": False, "options": False}
4619    _sql_names = ["JSON_FORMAT"]
4620
4621
4622# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
4623class JSONArrayContains(Binary, Predicate, Func):
4624    _sql_names = ["JSON_ARRAY_CONTAINS"]
4625
4626
4627class ParseJSON(Func):
4628    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4629    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4630
4631
4632class Least(Func):
4633    arg_types = {"this": True, "expressions": False}
4634    is_var_len_args = True
4635
4636
4637class Left(Func):
4638    arg_types = {"this": True, "expression": True}
4639
4640
4641class Right(Func):
4642    arg_types = {"this": True, "expression": True}
4643
4644
4645class Length(Func):
4646    _sql_names = ["LENGTH", "LEN"]
4647
4648
4649class Levenshtein(Func):
4650    arg_types = {
4651        "this": True,
4652        "expression": False,
4653        "ins_cost": False,
4654        "del_cost": False,
4655        "sub_cost": False,
4656    }
4657
4658
4659class Ln(Func):
4660    pass
4661
4662
4663class Log(Func):
4664    arg_types = {"this": True, "expression": False}
4665
4666
4667class Log2(Func):
4668    pass
4669
4670
4671class Log10(Func):
4672    pass
4673
4674
4675class LogicalOr(AggFunc):
4676    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
4677
4678
4679class LogicalAnd(AggFunc):
4680    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
4681
4682
4683class Lower(Func):
4684    _sql_names = ["LOWER", "LCASE"]
4685
4686
4687class Map(Func):
4688    arg_types = {"keys": False, "values": False}
4689
4690
4691class MapFromEntries(Func):
4692    pass
4693
4694
4695class StarMap(Func):
4696    pass
4697
4698
4699class VarMap(Func):
4700    arg_types = {"keys": True, "values": True}
4701    is_var_len_args = True
4702
4703    @property
4704    def keys(self) -> t.List[Expression]:
4705        return self.args["keys"].expressions
4706
4707    @property
4708    def values(self) -> t.List[Expression]:
4709        return self.args["values"].expressions
4710
4711
4712# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
4713class MatchAgainst(Func):
4714    arg_types = {"this": True, "expressions": True, "modifier": False}
4715
4716
4717class Max(AggFunc):
4718    arg_types = {"this": True, "expressions": False}
4719    is_var_len_args = True
4720
4721
4722class MD5(Func):
4723    _sql_names = ["MD5"]
4724
4725
4726# Represents the variant of the MD5 function that returns a binary value
4727class MD5Digest(Func):
4728    _sql_names = ["MD5_DIGEST"]
4729
4730
4731class Min(AggFunc):
4732    arg_types = {"this": True, "expressions": False}
4733    is_var_len_args = True
4734
4735
4736class Month(Func):
4737    pass
4738
4739
4740class Nvl2(Func):
4741    arg_types = {"this": True, "true": True, "false": False}
4742
4743
4744class Posexplode(Func):
4745    pass
4746
4747
4748class Pow(Binary, Func):
4749    _sql_names = ["POWER", "POW"]
4750
4751
4752class PercentileCont(AggFunc):
4753    arg_types = {"this": True, "expression": False}
4754
4755
4756class PercentileDisc(AggFunc):
4757    arg_types = {"this": True, "expression": False}
4758
4759
4760class Quantile(AggFunc):
4761    arg_types = {"this": True, "quantile": True}
4762
4763
4764class ApproxQuantile(Quantile):
4765    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
4766
4767
4768class RangeN(Func):
4769    arg_types = {"this": True, "expressions": True, "each": False}
4770
4771
4772class ReadCSV(Func):
4773    _sql_names = ["READ_CSV"]
4774    is_var_len_args = True
4775    arg_types = {"this": True, "expressions": False}
4776
4777
4778class Reduce(Func):
4779    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
4780
4781
4782class RegexpExtract(Func):
4783    arg_types = {
4784        "this": True,
4785        "expression": True,
4786        "position": False,
4787        "occurrence": False,
4788        "parameters": False,
4789        "group": False,
4790    }
4791
4792
4793class RegexpReplace(Func):
4794    arg_types = {
4795        "this": True,
4796        "expression": True,
4797        "replacement": True,
4798        "position": False,
4799        "occurrence": False,
4800        "parameters": False,
4801    }
4802
4803
4804class RegexpLike(Binary, Func):
4805    arg_types = {"this": True, "expression": True, "flag": False}
4806
4807
4808class RegexpILike(Func):
4809    arg_types = {"this": True, "expression": True, "flag": False}
4810
4811
4812# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
4813# limit is the number of times a pattern is applied
4814class RegexpSplit(Func):
4815    arg_types = {"this": True, "expression": True, "limit": False}
4816
4817
4818class Repeat(Func):
4819    arg_types = {"this": True, "times": True}
4820
4821
4822class Round(Func):
4823    arg_types = {"this": True, "decimals": False}
4824
4825
4826class RowNumber(Func):
4827    arg_types: t.Dict[str, t.Any] = {}
4828
4829
4830class SafeDivide(Func):
4831    arg_types = {"this": True, "expression": True}
4832
4833
4834class SetAgg(AggFunc):
4835    pass
4836
4837
4838class SHA(Func):
4839    _sql_names = ["SHA", "SHA1"]
4840
4841
4842class SHA2(Func):
4843    _sql_names = ["SHA2"]
4844    arg_types = {"this": True, "length": False}
4845
4846
4847class SortArray(Func):
4848    arg_types = {"this": True, "asc": False}
4849
4850
4851class Split(Func):
4852    arg_types = {"this": True, "expression": True, "limit": False}
4853
4854
4855# Start may be omitted in the case of postgres
4856# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
4857class Substring(Func):
4858    arg_types = {"this": True, "start": False, "length": False}
4859
4860
4861class StandardHash(Func):
4862    arg_types = {"this": True, "expression": False}
4863
4864
4865class StartsWith(Func):
4866    _sql_names = ["STARTS_WITH", "STARTSWITH"]
4867    arg_types = {"this": True, "expression": True}
4868
4869
4870class StrPosition(Func):
4871    arg_types = {
4872        "this": True,
4873        "substr": True,
4874        "position": False,
4875        "instance": False,
4876    }
4877
4878
4879class StrToDate(Func):
4880    arg_types = {"this": True, "format": True}
4881
4882
4883class StrToTime(Func):
4884    arg_types = {"this": True, "format": True, "zone": False}
4885
4886
4887# Spark allows unix_timestamp()
4888# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
4889class StrToUnix(Func):
4890    arg_types = {"this": False, "format": False}
4891
4892
4893# https://prestodb.io/docs/current/functions/string.html
4894# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
4895class StrToMap(Func):
4896    arg_types = {
4897        "this": True,
4898        "pair_delim": False,
4899        "key_value_delim": False,
4900        "duplicate_resolution_callback": False,
4901    }
4902
4903
4904class NumberToStr(Func):
4905    arg_types = {"this": True, "format": True, "culture": False}
4906
4907
4908class FromBase(Func):
4909    arg_types = {"this": True, "expression": True}
4910
4911
4912class Struct(Func):
4913    arg_types = {"expressions": True}
4914    is_var_len_args = True
4915
4916
4917class StructExtract(Func):
4918    arg_types = {"this": True, "expression": True}
4919
4920
4921# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
4922# https://docs.snowflake.com/en/sql-reference/functions/insert
4923class Stuff(Func):
4924    _sql_names = ["STUFF", "INSERT"]
4925    arg_types = {"this": True, "start": True, "length": True, "expression": True}
4926
4927
4928class Sum(AggFunc):
4929    pass
4930
4931
4932class Sqrt(Func):
4933    pass
4934
4935
4936class Stddev(AggFunc):
4937    pass
4938
4939
4940class StddevPop(AggFunc):
4941    pass
4942
4943
4944class StddevSamp(AggFunc):
4945    pass
4946
4947
4948class TimeToStr(Func):
4949    arg_types = {"this": True, "format": True, "culture": False}
4950
4951
4952class TimeToTimeStr(Func):
4953    pass
4954
4955
4956class TimeToUnix(Func):
4957    pass
4958
4959
4960class TimeStrToDate(Func):
4961    pass
4962
4963
4964class TimeStrToTime(Func):
4965    pass
4966
4967
4968class TimeStrToUnix(Func):
4969    pass
4970
4971
4972class Trim(Func):
4973    arg_types = {
4974        "this": True,
4975        "expression": False,
4976        "position": False,
4977        "collation": False,
4978    }
4979
4980
4981class TsOrDsAdd(Func, TimeUnit):
4982    arg_types = {"this": True, "expression": True, "unit": False}
4983
4984
4985class TsOrDsToDateStr(Func):
4986    pass
4987
4988
4989class TsOrDsToDate(Func):
4990    arg_types = {"this": True, "format": False}
4991
4992
4993class TsOrDiToDi(Func):
4994    pass
4995
4996
4997class Unhex(Func):
4998    pass
4999
5000
5001class UnixToStr(Func):
5002    arg_types = {"this": True, "format": False}
5003
5004
5005# https://prestodb.io/docs/current/functions/datetime.html
5006# presto has weird zone/hours/minutes
5007class UnixToTime(Func):
5008    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5009
5010    SECONDS = Literal.string("seconds")
5011    MILLIS = Literal.string("millis")
5012    MICROS = Literal.string("micros")
5013
5014
5015class UnixToTimeStr(Func):
5016    pass
5017
5018
5019class Upper(Func):
5020    _sql_names = ["UPPER", "UCASE"]
5021
5022
5023class Variance(AggFunc):
5024    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
5025
5026
5027class VariancePop(AggFunc):
5028    _sql_names = ["VARIANCE_POP", "VAR_POP"]
5029
5030
5031class Week(Func):
5032    arg_types = {"this": True, "mode": False}
5033
5034
5035class XMLTable(Func):
5036    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
5037
5038
5039class Year(Func):
5040    pass
5041
5042
5043class Use(Expression):
5044    arg_types = {"this": True, "kind": False}
5045
5046
5047class Merge(Expression):
5048    arg_types = {"this": True, "using": True, "on": True, "expressions": True}
5049
5050
5051class When(Func):
5052    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
5053
5054
5055# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
5056# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
5057class NextValueFor(Func):
5058    arg_types = {"this": True, "order": False}
5059
5060
5061def _norm_arg(arg):
5062    return arg.lower() if type(arg) is str else arg
5063
5064
5065ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
5066
5067
5068# Helpers
5069@t.overload
5070def maybe_parse(
5071    sql_or_expression: ExpOrStr,
5072    *,
5073    into: t.Type[E],
5074    dialect: DialectType = None,
5075    prefix: t.Optional[str] = None,
5076    copy: bool = False,
5077    **opts,
5078) -> E:
5079    ...
5080
5081
5082@t.overload
5083def maybe_parse(
5084    sql_or_expression: str | E,
5085    *,
5086    into: t.Optional[IntoType] = None,
5087    dialect: DialectType = None,
5088    prefix: t.Optional[str] = None,
5089    copy: bool = False,
5090    **opts,
5091) -> E:
5092    ...
5093
5094
5095def maybe_parse(
5096    sql_or_expression: ExpOrStr,
5097    *,
5098    into: t.Optional[IntoType] = None,
5099    dialect: DialectType = None,
5100    prefix: t.Optional[str] = None,
5101    copy: bool = False,
5102    **opts,
5103) -> Expression:
5104    """Gracefully handle a possible string or expression.
5105
5106    Example:
5107        >>> maybe_parse("1")
5108        (LITERAL this: 1, is_string: False)
5109        >>> maybe_parse(to_identifier("x"))
5110        (IDENTIFIER this: x, quoted: False)
5111
5112    Args:
5113        sql_or_expression: the SQL code string or an expression
5114        into: the SQLGlot Expression to parse into
5115        dialect: the dialect used to parse the input expressions (in the case that an
5116            input expression is a SQL string).
5117        prefix: a string to prefix the sql with before it gets parsed
5118            (automatically includes a space)
5119        copy: whether or not to copy the expression.
5120        **opts: other options to use to parse the input expressions (again, in the case
5121            that an input expression is a SQL string).
5122
5123    Returns:
5124        Expression: the parsed or given expression.
5125    """
5126    if isinstance(sql_or_expression, Expression):
5127        if copy:
5128            return sql_or_expression.copy()
5129        return sql_or_expression
5130
5131    if sql_or_expression is None:
5132        raise ParseError(f"SQL cannot be None")
5133
5134    import sqlglot
5135
5136    sql = str(sql_or_expression)
5137    if prefix:
5138        sql = f"{prefix} {sql}"
5139
5140    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
5141
5142
5143@t.overload
5144def maybe_copy(instance: None, copy: bool = True) -> None:
5145    ...
5146
5147
5148@t.overload
5149def maybe_copy(instance: E, copy: bool = True) -> E:
5150    ...
5151
5152
5153def maybe_copy(instance, copy=True):
5154    return instance.copy() if copy and instance else instance
5155
5156
5157def _is_wrong_expression(expression, into):
5158    return isinstance(expression, Expression) and not isinstance(expression, into)
5159
5160
5161def _apply_builder(
5162    expression,
5163    instance,
5164    arg,
5165    copy=True,
5166    prefix=None,
5167    into=None,
5168    dialect=None,
5169    into_arg="this",
5170    **opts,
5171):
5172    if _is_wrong_expression(expression, into):
5173        expression = into(**{into_arg: expression})
5174    instance = maybe_copy(instance, copy)
5175    expression = maybe_parse(
5176        sql_or_expression=expression,
5177        prefix=prefix,
5178        into=into,
5179        dialect=dialect,
5180        **opts,
5181    )
5182    instance.set(arg, expression)
5183    return instance
5184
5185
5186def _apply_child_list_builder(
5187    *expressions,
5188    instance,
5189    arg,
5190    append=True,
5191    copy=True,
5192    prefix=None,
5193    into=None,
5194    dialect=None,
5195    properties=None,
5196    **opts,
5197):
5198    instance = maybe_copy(instance, copy)
5199    parsed = []
5200    for expression in expressions:
5201        if expression is not None:
5202            if _is_wrong_expression(expression, into):
5203                expression = into(expressions=[expression])
5204
5205            expression = maybe_parse(
5206                expression,
5207                into=into,
5208                dialect=dialect,
5209                prefix=prefix,
5210                **opts,
5211            )
5212            parsed.extend(expression.expressions)
5213
5214    existing = instance.args.get(arg)
5215    if append and existing:
5216        parsed = existing.expressions + parsed
5217
5218    child = into(expressions=parsed)
5219    for k, v in (properties or {}).items():
5220        child.set(k, v)
5221    instance.set(arg, child)
5222
5223    return instance
5224
5225
5226def _apply_list_builder(
5227    *expressions,
5228    instance,
5229    arg,
5230    append=True,
5231    copy=True,
5232    prefix=None,
5233    into=None,
5234    dialect=None,
5235    **opts,
5236):
5237    inst = maybe_copy(instance, copy)
5238
5239    expressions = [
5240        maybe_parse(
5241            sql_or_expression=expression,
5242            into=into,
5243            prefix=prefix,
5244            dialect=dialect,
5245            **opts,
5246        )
5247        for expression in expressions
5248        if expression is not None
5249    ]
5250
5251    existing_expressions = inst.args.get(arg)
5252    if append and existing_expressions:
5253        expressions = existing_expressions + expressions
5254
5255    inst.set(arg, expressions)
5256    return inst
5257
5258
5259def _apply_conjunction_builder(
5260    *expressions,
5261    instance,
5262    arg,
5263    into=None,
5264    append=True,
5265    copy=True,
5266    dialect=None,
5267    **opts,
5268):
5269    expressions = [exp for exp in expressions if exp is not None and exp != ""]
5270    if not expressions:
5271        return instance
5272
5273    inst = maybe_copy(instance, copy)
5274
5275    existing = inst.args.get(arg)
5276    if append and existing is not None:
5277        expressions = [existing.this if into else existing] + list(expressions)
5278
5279    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
5280
5281    inst.set(arg, into(this=node) if into else node)
5282    return inst
5283
5284
5285def _apply_cte_builder(
5286    instance: E,
5287    alias: ExpOrStr,
5288    as_: ExpOrStr,
5289    recursive: t.Optional[bool] = None,
5290    append: bool = True,
5291    dialect: DialectType = None,
5292    copy: bool = True,
5293    **opts,
5294) -> E:
5295    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
5296    as_expression = maybe_parse(as_, dialect=dialect, **opts)
5297    cte = CTE(this=as_expression, alias=alias_expression)
5298    return _apply_child_list_builder(
5299        cte,
5300        instance=instance,
5301        arg="with",
5302        append=append,
5303        copy=copy,
5304        into=With,
5305        properties={"recursive": recursive or False},
5306    )
5307
5308
5309def _combine(
5310    expressions: t.Sequence[t.Optional[ExpOrStr]],
5311    operator: t.Type[Connector],
5312    dialect: DialectType = None,
5313    copy: bool = True,
5314    **opts,
5315) -> Expression:
5316    conditions = [
5317        condition(expression, dialect=dialect, copy=copy, **opts)
5318        for expression in expressions
5319        if expression is not None
5320    ]
5321
5322    this, *rest = conditions
5323    if rest:
5324        this = _wrap(this, Connector)
5325    for expression in rest:
5326        this = operator(this=this, expression=_wrap(expression, Connector))
5327
5328    return this
5329
5330
5331def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
5332    return Paren(this=expression) if isinstance(expression, kind) else expression
5333
5334
5335def union(
5336    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5337) -> Union:
5338    """
5339    Initializes a syntax tree from one UNION expression.
5340
5341    Example:
5342        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5343        'SELECT * FROM foo UNION SELECT * FROM bla'
5344
5345    Args:
5346        left: the SQL code string corresponding to the left-hand side.
5347            If an `Expression` instance is passed, it will be used as-is.
5348        right: the SQL code string corresponding to the right-hand side.
5349            If an `Expression` instance is passed, it will be used as-is.
5350        distinct: set the DISTINCT flag if and only if this is true.
5351        dialect: the dialect used to parse the input expression.
5352        opts: other options to use to parse the input expressions.
5353
5354    Returns:
5355        The new Union instance.
5356    """
5357    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5358    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5359
5360    return Union(this=left, expression=right, distinct=distinct)
5361
5362
5363def intersect(
5364    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5365) -> Intersect:
5366    """
5367    Initializes a syntax tree from one INTERSECT expression.
5368
5369    Example:
5370        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5371        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5372
5373    Args:
5374        left: the SQL code string corresponding to the left-hand side.
5375            If an `Expression` instance is passed, it will be used as-is.
5376        right: the SQL code string corresponding to the right-hand side.
5377            If an `Expression` instance is passed, it will be used as-is.
5378        distinct: set the DISTINCT flag if and only if this is true.
5379        dialect: the dialect used to parse the input expression.
5380        opts: other options to use to parse the input expressions.
5381
5382    Returns:
5383        The new Intersect instance.
5384    """
5385    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5386    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5387
5388    return Intersect(this=left, expression=right, distinct=distinct)
5389
5390
5391def except_(
5392    left: ExpOrStr, right: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
5393) -> Except:
5394    """
5395    Initializes a syntax tree from one EXCEPT expression.
5396
5397    Example:
5398        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5399        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5400
5401    Args:
5402        left: the SQL code string corresponding to the left-hand side.
5403            If an `Expression` instance is passed, it will be used as-is.
5404        right: the SQL code string corresponding to the right-hand side.
5405            If an `Expression` instance is passed, it will be used as-is.
5406        distinct: set the DISTINCT flag if and only if this is true.
5407        dialect: the dialect used to parse the input expression.
5408        opts: other options to use to parse the input expressions.
5409
5410    Returns:
5411        The new Except instance.
5412    """
5413    left = maybe_parse(sql_or_expression=left, dialect=dialect, **opts)
5414    right = maybe_parse(sql_or_expression=right, dialect=dialect, **opts)
5415
5416    return Except(this=left, expression=right, distinct=distinct)
5417
5418
5419def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5420    """
5421    Initializes a syntax tree from one or multiple SELECT expressions.
5422
5423    Example:
5424        >>> select("col1", "col2").from_("tbl").sql()
5425        'SELECT col1, col2 FROM tbl'
5426
5427    Args:
5428        *expressions: the SQL code string to parse as the expressions of a
5429            SELECT statement. If an Expression instance is passed, this is used as-is.
5430        dialect: the dialect used to parse the input expressions (in the case that an
5431            input expression is a SQL string).
5432        **opts: other options to use to parse the input expressions (again, in the case
5433            that an input expression is a SQL string).
5434
5435    Returns:
5436        Select: the syntax tree for the SELECT statement.
5437    """
5438    return Select().select(*expressions, dialect=dialect, **opts)
5439
5440
5441def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5442    """
5443    Initializes a syntax tree from a FROM expression.
5444
5445    Example:
5446        >>> from_("tbl").select("col1", "col2").sql()
5447        'SELECT col1, col2 FROM tbl'
5448
5449    Args:
5450        *expression: the SQL code string to parse as the FROM expressions of a
5451            SELECT statement. If an Expression instance is passed, this is used as-is.
5452        dialect: the dialect used to parse the input expression (in the case that the
5453            input expression is a SQL string).
5454        **opts: other options to use to parse the input expressions (again, in the case
5455            that the input expression is a SQL string).
5456
5457    Returns:
5458        Select: the syntax tree for the SELECT statement.
5459    """
5460    return Select().from_(expression, dialect=dialect, **opts)
5461
5462
5463def update(
5464    table: str | Table,
5465    properties: dict,
5466    where: t.Optional[ExpOrStr] = None,
5467    from_: t.Optional[ExpOrStr] = None,
5468    dialect: DialectType = None,
5469    **opts,
5470) -> Update:
5471    """
5472    Creates an update statement.
5473
5474    Example:
5475        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5476        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5477
5478    Args:
5479        *properties: dictionary of properties to set which are
5480            auto converted to sql objects eg None -> NULL
5481        where: sql conditional parsed into a WHERE statement
5482        from_: sql statement parsed into a FROM statement
5483        dialect: the dialect used to parse the input expressions.
5484        **opts: other options to use to parse the input expressions.
5485
5486    Returns:
5487        Update: the syntax tree for the UPDATE statement.
5488    """
5489    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5490    update_expr.set(
5491        "expressions",
5492        [
5493            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5494            for k, v in properties.items()
5495        ],
5496    )
5497    if from_:
5498        update_expr.set(
5499            "from",
5500            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5501        )
5502    if isinstance(where, Condition):
5503        where = Where(this=where)
5504    if where:
5505        update_expr.set(
5506            "where",
5507            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5508        )
5509    return update_expr
5510
5511
5512def delete(
5513    table: ExpOrStr,
5514    where: t.Optional[ExpOrStr] = None,
5515    returning: t.Optional[ExpOrStr] = None,
5516    dialect: DialectType = None,
5517    **opts,
5518) -> Delete:
5519    """
5520    Builds a delete statement.
5521
5522    Example:
5523        >>> delete("my_table", where="id > 1").sql()
5524        'DELETE FROM my_table WHERE id > 1'
5525
5526    Args:
5527        where: sql conditional parsed into a WHERE statement
5528        returning: sql conditional parsed into a RETURNING statement
5529        dialect: the dialect used to parse the input expressions.
5530        **opts: other options to use to parse the input expressions.
5531
5532    Returns:
5533        Delete: the syntax tree for the DELETE statement.
5534    """
5535    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5536    if where:
5537        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5538    if returning:
5539        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5540    return delete_expr
5541
5542
5543def insert(
5544    expression: ExpOrStr,
5545    into: ExpOrStr,
5546    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5547    overwrite: t.Optional[bool] = None,
5548    dialect: DialectType = None,
5549    copy: bool = True,
5550    **opts,
5551) -> Insert:
5552    """
5553    Builds an INSERT statement.
5554
5555    Example:
5556        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5557        'INSERT INTO tbl VALUES (1, 2, 3)'
5558
5559    Args:
5560        expression: the sql string or expression of the INSERT statement
5561        into: the tbl to insert data to.
5562        columns: optionally the table's column names.
5563        overwrite: whether to INSERT OVERWRITE or not.
5564        dialect: the dialect used to parse the input expressions.
5565        copy: whether or not to copy the expression.
5566        **opts: other options to use to parse the input expressions.
5567
5568    Returns:
5569        Insert: the syntax tree for the INSERT statement.
5570    """
5571    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5572    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5573
5574    if columns:
5575        this = _apply_list_builder(
5576            *columns,
5577            instance=Schema(this=this),
5578            arg="expressions",
5579            into=Identifier,
5580            copy=False,
5581            dialect=dialect,
5582            **opts,
5583        )
5584
5585    return Insert(this=this, expression=expr, overwrite=overwrite)
5586
5587
5588def condition(
5589    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5590) -> Condition:
5591    """
5592    Initialize a logical condition expression.
5593
5594    Example:
5595        >>> condition("x=1").sql()
5596        'x = 1'
5597
5598        This is helpful for composing larger logical syntax trees:
5599        >>> where = condition("x=1")
5600        >>> where = where.and_("y=1")
5601        >>> Select().from_("tbl").select("*").where(where).sql()
5602        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5603
5604    Args:
5605        *expression: the SQL code string to parse.
5606            If an Expression instance is passed, this is used as-is.
5607        dialect: the dialect used to parse the input expression (in the case that the
5608            input expression is a SQL string).
5609        copy: Whether or not to copy `expression` (only applies to expressions).
5610        **opts: other options to use to parse the input expressions (again, in the case
5611            that the input expression is a SQL string).
5612
5613    Returns:
5614        The new Condition instance
5615    """
5616    return maybe_parse(
5617        expression,
5618        into=Condition,
5619        dialect=dialect,
5620        copy=copy,
5621        **opts,
5622    )
5623
5624
5625def and_(
5626    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5627) -> Condition:
5628    """
5629    Combine multiple conditions with an AND logical operator.
5630
5631    Example:
5632        >>> and_("x=1", and_("y=1", "z=1")).sql()
5633        'x = 1 AND (y = 1 AND z = 1)'
5634
5635    Args:
5636        *expressions: the SQL code strings to parse.
5637            If an Expression instance is passed, this is used as-is.
5638        dialect: the dialect used to parse the input expression.
5639        copy: whether or not to copy `expressions` (only applies to Expressions).
5640        **opts: other options to use to parse the input expressions.
5641
5642    Returns:
5643        And: the new condition
5644    """
5645    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
5646
5647
5648def or_(
5649    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
5650) -> Condition:
5651    """
5652    Combine multiple conditions with an OR logical operator.
5653
5654    Example:
5655        >>> or_("x=1", or_("y=1", "z=1")).sql()
5656        'x = 1 OR (y = 1 OR z = 1)'
5657
5658    Args:
5659        *expressions: the SQL code strings to parse.
5660            If an Expression instance is passed, this is used as-is.
5661        dialect: the dialect used to parse the input expression.
5662        copy: whether or not to copy `expressions` (only applies to Expressions).
5663        **opts: other options to use to parse the input expressions.
5664
5665    Returns:
5666        Or: the new condition
5667    """
5668    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
5669
5670
5671def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
5672    """
5673    Wrap a condition with a NOT operator.
5674
5675    Example:
5676        >>> not_("this_suit='black'").sql()
5677        "NOT this_suit = 'black'"
5678
5679    Args:
5680        expression: the SQL code string to parse.
5681            If an Expression instance is passed, this is used as-is.
5682        dialect: the dialect used to parse the input expression.
5683        copy: whether to copy the expression or not.
5684        **opts: other options to use to parse the input expressions.
5685
5686    Returns:
5687        The new condition.
5688    """
5689    this = condition(
5690        expression,
5691        dialect=dialect,
5692        copy=copy,
5693        **opts,
5694    )
5695    return Not(this=_wrap(this, Connector))
5696
5697
5698def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
5699    """
5700    Wrap an expression in parentheses.
5701
5702    Example:
5703        >>> paren("5 + 3").sql()
5704        '(5 + 3)'
5705
5706    Args:
5707        expression: the SQL code string to parse.
5708            If an Expression instance is passed, this is used as-is.
5709        copy: whether to copy the expression or not.
5710
5711    Returns:
5712        The wrapped expression.
5713    """
5714    return Paren(this=maybe_parse(expression, copy=copy))
5715
5716
5717SAFE_IDENTIFIER_RE = re.compile(r"^[_a-zA-Z][\w]*$")
5718
5719
5720@t.overload
5721def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None:
5722    ...
5723
5724
5725@t.overload
5726def to_identifier(
5727    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
5728) -> Identifier:
5729    ...
5730
5731
5732def to_identifier(name, quoted=None, copy=True):
5733    """Builds an identifier.
5734
5735    Args:
5736        name: The name to turn into an identifier.
5737        quoted: Whether or not force quote the identifier.
5738        copy: Whether or not to copy a passed in Identefier node.
5739
5740    Returns:
5741        The identifier ast node.
5742    """
5743
5744    if name is None:
5745        return None
5746
5747    if isinstance(name, Identifier):
5748        identifier = maybe_copy(name, copy)
5749    elif isinstance(name, str):
5750        identifier = Identifier(
5751            this=name,
5752            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
5753        )
5754    else:
5755        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
5756    return identifier
5757
5758
5759INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
5760
5761
5762def to_interval(interval: str | Literal) -> Interval:
5763    """Builds an interval expression from a string like '1 day' or '5 months'."""
5764    if isinstance(interval, Literal):
5765        if not interval.is_string:
5766            raise ValueError("Invalid interval string.")
5767
5768        interval = interval.this
5769
5770    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
5771
5772    if not interval_parts:
5773        raise ValueError("Invalid interval string.")
5774
5775    return Interval(
5776        this=Literal.string(interval_parts.group(1)),
5777        unit=Var(this=interval_parts.group(2)),
5778    )
5779
5780
5781@t.overload
5782def to_table(sql_path: str | Table, **kwargs) -> Table:
5783    ...
5784
5785
5786@t.overload
5787def to_table(sql_path: None, **kwargs) -> None:
5788    ...
5789
5790
5791def to_table(
5792    sql_path: t.Optional[str | Table], dialect: DialectType = None, **kwargs
5793) -> t.Optional[Table]:
5794    """
5795    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
5796    If a table is passed in then that table is returned.
5797
5798    Args:
5799        sql_path: a `[catalog].[schema].[table]` string.
5800        dialect: the source dialect according to which the table name will be parsed.
5801        kwargs: the kwargs to instantiate the resulting `Table` expression with.
5802
5803    Returns:
5804        A table expression.
5805    """
5806    if sql_path is None or isinstance(sql_path, Table):
5807        return sql_path
5808    if not isinstance(sql_path, str):
5809        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
5810
5811    table = maybe_parse(sql_path, into=Table, dialect=dialect)
5812    if table:
5813        for k, v in kwargs.items():
5814            table.set(k, v)
5815
5816    return table
5817
5818
5819def to_column(sql_path: str | Column, **kwargs) -> Column:
5820    """
5821    Create a column from a `[table].[column]` sql path. Schema is optional.
5822
5823    If a column is passed in then that column is returned.
5824
5825    Args:
5826        sql_path: `[table].[column]` string
5827    Returns:
5828        Table: A column expression
5829    """
5830    if sql_path is None or isinstance(sql_path, Column):
5831        return sql_path
5832    if not isinstance(sql_path, str):
5833        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
5834    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore
5835
5836
5837def alias_(
5838    expression: ExpOrStr,
5839    alias: str | Identifier,
5840    table: bool | t.Sequence[str | Identifier] = False,
5841    quoted: t.Optional[bool] = None,
5842    dialect: DialectType = None,
5843    copy: bool = True,
5844    **opts,
5845):
5846    """Create an Alias expression.
5847
5848    Example:
5849        >>> alias_('foo', 'bar').sql()
5850        'foo AS bar'
5851
5852        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
5853        '(SELECT 1, 2) AS bar(a, b)'
5854
5855    Args:
5856        expression: the SQL code strings to parse.
5857            If an Expression instance is passed, this is used as-is.
5858        alias: the alias name to use. If the name has
5859            special characters it is quoted.
5860        table: Whether or not to create a table alias, can also be a list of columns.
5861        quoted: whether or not to quote the alias
5862        dialect: the dialect used to parse the input expression.
5863        copy: Whether or not to copy the expression.
5864        **opts: other options to use to parse the input expressions.
5865
5866    Returns:
5867        Alias: the aliased expression
5868    """
5869    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5870    alias = to_identifier(alias, quoted=quoted)
5871
5872    if table:
5873        table_alias = TableAlias(this=alias)
5874        exp.set("alias", table_alias)
5875
5876        if not isinstance(table, bool):
5877            for column in table:
5878                table_alias.append("columns", to_identifier(column, quoted=quoted))
5879
5880        return exp
5881
5882    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
5883    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
5884    # for the complete Window expression.
5885    #
5886    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
5887
5888    if "alias" in exp.arg_types and not isinstance(exp, Window):
5889        exp.set("alias", alias)
5890        return exp
5891    return Alias(this=exp, alias=alias)
5892
5893
5894def subquery(
5895    expression: ExpOrStr,
5896    alias: t.Optional[Identifier | str] = None,
5897    dialect: DialectType = None,
5898    **opts,
5899) -> Select:
5900    """
5901    Build a subquery expression.
5902
5903    Example:
5904        >>> subquery('select x from tbl', 'bar').select('x').sql()
5905        'SELECT x FROM (SELECT x FROM tbl) AS bar'
5906
5907    Args:
5908        expression: the SQL code strings to parse.
5909            If an Expression instance is passed, this is used as-is.
5910        alias: the alias name to use.
5911        dialect: the dialect used to parse the input expression.
5912        **opts: other options to use to parse the input expressions.
5913
5914    Returns:
5915        A new Select instance with the subquery expression included.
5916    """
5917
5918    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
5919    return Select().from_(expression, dialect=dialect, **opts)
5920
5921
5922def column(
5923    col: str | Identifier,
5924    table: t.Optional[str | Identifier] = None,
5925    db: t.Optional[str | Identifier] = None,
5926    catalog: t.Optional[str | Identifier] = None,
5927    quoted: t.Optional[bool] = None,
5928) -> Column:
5929    """
5930    Build a Column.
5931
5932    Args:
5933        col: Column name.
5934        table: Table name.
5935        db: Database name.
5936        catalog: Catalog name.
5937        quoted: Whether to force quotes on the column's identifiers.
5938
5939    Returns:
5940        The new Column instance.
5941    """
5942    return Column(
5943        this=to_identifier(col, quoted=quoted),
5944        table=to_identifier(table, quoted=quoted),
5945        db=to_identifier(db, quoted=quoted),
5946        catalog=to_identifier(catalog, quoted=quoted),
5947    )
5948
5949
5950def cast(expression: ExpOrStr, to: str | DataType | DataType.Type, **opts) -> Cast:
5951    """Cast an expression to a data type.
5952
5953    Example:
5954        >>> cast('x + 1', 'int').sql()
5955        'CAST(x + 1 AS INT)'
5956
5957    Args:
5958        expression: The expression to cast.
5959        to: The datatype to cast to.
5960
5961    Returns:
5962        The new Cast instance.
5963    """
5964    expression = maybe_parse(expression, **opts)
5965    data_type = DataType.build(to, **opts)
5966    expression = Cast(this=expression, to=data_type)
5967    expression.type = data_type
5968    return expression
5969
5970
5971def table_(
5972    table: Identifier | str,
5973    db: t.Optional[Identifier | str] = None,
5974    catalog: t.Optional[Identifier | str] = None,
5975    quoted: t.Optional[bool] = None,
5976    alias: t.Optional[Identifier | str] = None,
5977) -> Table:
5978    """Build a Table.
5979
5980    Args:
5981        table: Table name.
5982        db: Database name.
5983        catalog: Catalog name.
5984        quote: Whether to force quotes on the table's identifiers.
5985        alias: Table's alias.
5986
5987    Returns:
5988        The new Table instance.
5989    """
5990    return Table(
5991        this=to_identifier(table, quoted=quoted) if table else None,
5992        db=to_identifier(db, quoted=quoted) if db else None,
5993        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
5994        alias=TableAlias(this=to_identifier(alias)) if alias else None,
5995    )
5996
5997
5998def values(
5999    values: t.Iterable[t.Tuple[t.Any, ...]],
6000    alias: t.Optional[str] = None,
6001    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6002) -> Values:
6003    """Build VALUES statement.
6004
6005    Example:
6006        >>> values([(1, '2')]).sql()
6007        "VALUES (1, '2')"
6008
6009    Args:
6010        values: values statements that will be converted to SQL
6011        alias: optional alias
6012        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6013         If either are provided then an alias is also required.
6014
6015    Returns:
6016        Values: the Values expression object
6017    """
6018    if columns and not alias:
6019        raise ValueError("Alias is required when providing columns")
6020
6021    return Values(
6022        expressions=[convert(tup) for tup in values],
6023        alias=(
6024            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6025            if columns
6026            else (TableAlias(this=to_identifier(alias)) if alias else None)
6027        ),
6028    )
6029
6030
6031def var(name: t.Optional[ExpOrStr]) -> Var:
6032    """Build a SQL variable.
6033
6034    Example:
6035        >>> repr(var('x'))
6036        '(VAR this: x)'
6037
6038        >>> repr(var(column('x', table='y')))
6039        '(VAR this: x)'
6040
6041    Args:
6042        name: The name of the var or an expression who's name will become the var.
6043
6044    Returns:
6045        The new variable node.
6046    """
6047    if not name:
6048        raise ValueError("Cannot convert empty name into var.")
6049
6050    if isinstance(name, Expression):
6051        name = name.name
6052    return Var(this=name)
6053
6054
6055def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6056    """Build ALTER TABLE... RENAME... expression
6057
6058    Args:
6059        old_name: The old name of the table
6060        new_name: The new name of the table
6061
6062    Returns:
6063        Alter table expression
6064    """
6065    old_table = to_table(old_name)
6066    new_table = to_table(new_name)
6067    return AlterTable(
6068        this=old_table,
6069        actions=[
6070            RenameTable(this=new_table),
6071        ],
6072    )
6073
6074
6075def convert(value: t.Any, copy: bool = False) -> Expression:
6076    """Convert a python value into an expression object.
6077
6078    Raises an error if a conversion is not possible.
6079
6080    Args:
6081        value: A python object.
6082        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6083
6084    Returns:
6085        Expression: the equivalent expression object.
6086    """
6087    if isinstance(value, Expression):
6088        return maybe_copy(value, copy)
6089    if isinstance(value, str):
6090        return Literal.string(value)
6091    if isinstance(value, bool):
6092        return Boolean(this=value)
6093    if value is None or (isinstance(value, float) and math.isnan(value)):
6094        return NULL
6095    if isinstance(value, numbers.Number):
6096        return Literal.number(value)
6097    if isinstance(value, datetime.datetime):
6098        datetime_literal = Literal.string(
6099            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6100        )
6101        return TimeStrToTime(this=datetime_literal)
6102    if isinstance(value, datetime.date):
6103        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6104        return DateStrToDate(this=date_literal)
6105    if isinstance(value, tuple):
6106        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6107    if isinstance(value, list):
6108        return Array(expressions=[convert(v, copy=copy) for v in value])
6109    if isinstance(value, dict):
6110        return Map(
6111            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6112            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6113        )
6114    raise ValueError(f"Cannot convert {value}")
6115
6116
6117def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6118    """
6119    Replace children of an expression with the result of a lambda fun(child) -> exp.
6120    """
6121    for k, v in expression.args.items():
6122        is_list_arg = type(v) is list
6123
6124        child_nodes = v if is_list_arg else [v]
6125        new_child_nodes = []
6126
6127        for cn in child_nodes:
6128            if isinstance(cn, Expression):
6129                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6130                    new_child_nodes.append(child_node)
6131                    child_node.parent = expression
6132                    child_node.arg_key = k
6133            else:
6134                new_child_nodes.append(cn)
6135
6136        expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0)
6137
6138
6139def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6140    """
6141    Return all table names referenced through columns in an expression.
6142
6143    Example:
6144        >>> import sqlglot
6145        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6146        ['a', 'c']
6147
6148    Args:
6149        expression: expression to find table names.
6150        exclude: a table name to exclude
6151
6152    Returns:
6153        A list of unique names.
6154    """
6155    return {
6156        table
6157        for table in (column.table for column in expression.find_all(Column))
6158        if table and table != exclude
6159    }
6160
6161
6162def table_name(table: Table | str, dialect: DialectType = None) -> str:
6163    """Get the full name of a table as a string.
6164
6165    Args:
6166        table: Table expression node or string.
6167        dialect: The dialect to generate the table name for.
6168
6169    Examples:
6170        >>> from sqlglot import exp, parse_one
6171        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6172        'a.b.c'
6173
6174    Returns:
6175        The table name.
6176    """
6177
6178    table = maybe_parse(table, into=Table)
6179
6180    if not table:
6181        raise ValueError(f"Cannot parse {table}")
6182
6183    return ".".join(
6184        part.sql(dialect=dialect, identify=True)
6185        if not SAFE_IDENTIFIER_RE.match(part.name)
6186        else part.name
6187        for part in table.parts
6188    )
6189
6190
6191def replace_tables(expression: E, mapping: t.Dict[str, str], copy: bool = True) -> E:
6192    """Replace all tables in expression according to the mapping.
6193
6194    Args:
6195        expression: expression node to be transformed and replaced.
6196        mapping: mapping of table names.
6197        copy: whether or not to copy the expression.
6198
6199    Examples:
6200        >>> from sqlglot import exp, parse_one
6201        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6202        'SELECT * FROM c'
6203
6204    Returns:
6205        The mapped expression.
6206    """
6207
6208    def _replace_tables(node: Expression) -> Expression:
6209        if isinstance(node, Table):
6210            new_name = mapping.get(table_name(node))
6211            if new_name:
6212                return to_table(
6213                    new_name,
6214                    **{k: v for k, v in node.args.items() if k not in ("this", "db", "catalog")},
6215                )
6216        return node
6217
6218    return expression.transform(_replace_tables, copy=copy)
6219
6220
6221def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6222    """Replace placeholders in an expression.
6223
6224    Args:
6225        expression: expression node to be transformed and replaced.
6226        args: positional names that will substitute unnamed placeholders in the given order.
6227        kwargs: keyword arguments that will substitute named placeholders.
6228
6229    Examples:
6230        >>> from sqlglot import exp, parse_one
6231        >>> replace_placeholders(
6232        ...     parse_one("select * from :tbl where ? = ?"),
6233        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6234        ... ).sql()
6235        "SELECT * FROM foo WHERE str_col = 'b'"
6236
6237    Returns:
6238        The mapped expression.
6239    """
6240
6241    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6242        if isinstance(node, Placeholder):
6243            if node.name:
6244                new_name = kwargs.get(node.name)
6245                if new_name:
6246                    return convert(new_name)
6247            else:
6248                try:
6249                    return convert(next(args))
6250                except StopIteration:
6251                    pass
6252        return node
6253
6254    return expression.transform(_replace_placeholders, iter(args), **kwargs)
6255
6256
6257def expand(
6258    expression: Expression, sources: t.Dict[str, Subqueryable], copy: bool = True
6259) -> Expression:
6260    """Transforms an expression by expanding all referenced sources into subqueries.
6261
6262    Examples:
6263        >>> from sqlglot import parse_one
6264        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6265        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6266
6267        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6268        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6269
6270    Args:
6271        expression: The expression to expand.
6272        sources: A dictionary of name to Subqueryables.
6273        copy: Whether or not to copy the expression during transformation. Defaults to True.
6274
6275    Returns:
6276        The transformed expression.
6277    """
6278
6279    def _expand(node: Expression):
6280        if isinstance(node, Table):
6281            name = table_name(node)
6282            source = sources.get(name)
6283            if source:
6284                subquery = source.subquery(node.alias or name)
6285                subquery.comments = [f"source: {name}"]
6286                return subquery.transform(_expand, copy=False)
6287        return node
6288
6289    return expression.transform(_expand, copy=copy)
6290
6291
6292def func(name: str, *args, dialect: DialectType = None, **kwargs) -> Func:
6293    """
6294    Returns a Func expression.
6295
6296    Examples:
6297        >>> func("abs", 5).sql()
6298        'ABS(5)'
6299
6300        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6301        'CAST(5 AS DOUBLE)'
6302
6303    Args:
6304        name: the name of the function to build.
6305        args: the args used to instantiate the function of interest.
6306        dialect: the source dialect.
6307        kwargs: the kwargs used to instantiate the function of interest.
6308
6309    Note:
6310        The arguments `args` and `kwargs` are mutually exclusive.
6311
6312    Returns:
6313        An instance of the function of interest, or an anonymous function, if `name` doesn't
6314        correspond to an existing `sqlglot.expressions.Func` class.
6315    """
6316    if args and kwargs:
6317        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6318
6319    from sqlglot.dialects.dialect import Dialect
6320
6321    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect) for arg in args]
6322    kwargs = {key: maybe_parse(value, dialect=dialect) for key, value in kwargs.items()}
6323
6324    parser = Dialect.get_or_raise(dialect)().parser()
6325    from_args_list = parser.FUNCTIONS.get(name.upper())
6326
6327    if from_args_list:
6328        function = from_args_list(converted) if converted else from_args_list.__self__(**kwargs)  # type: ignore
6329    else:
6330        kwargs = kwargs or {"expressions": converted}
6331        function = Anonymous(this=name, **kwargs)
6332
6333    for error_message in function.error_messages(converted):
6334        raise ValueError(error_message)
6335
6336    return function
6337
6338
6339def true() -> Boolean:
6340    """
6341    Returns a true Boolean expression.
6342    """
6343    return Boolean(this=True)
6344
6345
6346def false() -> Boolean:
6347    """
6348    Returns a false Boolean expression.
6349    """
6350    return Boolean(this=False)
6351
6352
6353def null() -> Null:
6354    """
6355    Returns a Null expression.
6356    """
6357    return Null()
6358
6359
6360# TODO: deprecate this
6361TRUE = Boolean(this=True)
6362FALSE = Boolean(this=False)
6363NULL = 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        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
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.VARCHAR: 'VARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>}
INTEGER_TYPES = {<Type.INT: 'INT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT128: 'INT128'>, <Type.INT256: 'INT256'>}
TEMPORAL_TYPES = {<Type.DATETIME64: 'DATETIME64'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATETIME: 'DATETIME'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <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:
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})

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:
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

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        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()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
HLLSKETCH = <Type.HLLSKETCH: 'HLLSKETCH'>
HSTORE = <Type.HSTORE: 'HSTORE'>
IMAGE = <Type.IMAGE: 'IMAGE'>
INET = <Type.INET: 'INET'>
INT = <Type.INT: 'INT'>
INT128 = <Type.INT128: 'INT128'>
INT256 = <Type.INT256: 'INT256'>
INT4MULTIRANGE = <Type.INT4MULTIRANGE: 'INT4MULTIRANGE'>
INT4RANGE = <Type.INT4RANGE: 'INT4RANGE'>
INT8MULTIRANGE = <Type.INT8MULTIRANGE: 'INT8MULTIRANGE'>
INT8RANGE = <Type.INT8RANGE: 'INT8RANGE'>
INTERVAL = <Type.INTERVAL: 'INTERVAL'>
IPADDRESS = <Type.IPADDRESS: 'IPADDRESS'>
IPPREFIX = <Type.IPPREFIX: 'IPPREFIX'>
JSON = <Type.JSON: 'JSON'>
JSONB = <Type.JSONB: 'JSONB'>
LONGBLOB = <Type.LONGBLOB: 'LONGBLOB'>
LONGTEXT = <Type.LONGTEXT: 'LONGTEXT'>
LOWCARDINALITY = <Type.LOWCARDINALITY: 'LOWCARDINALITY'>
MAP = <Type.MAP: 'MAP'>
MEDIUMBLOB = <Type.MEDIUMBLOB: 'MEDIUMBLOB'>
MEDIUMINT = <Type.MEDIUMINT: 'MEDIUMINT'>
MEDIUMTEXT = <Type.MEDIUMTEXT: 'MEDIUMTEXT'>
MONEY = <Type.MONEY: 'MONEY'>
NCHAR = <Type.NCHAR: 'NCHAR'>
NESTED = <Type.NESTED: 'NESTED'>
NULL = <Type.NULL: 'NULL'>
NULLABLE = <Type.NULLABLE: 'NULLABLE'>
NUMMULTIRANGE = <Type.NUMMULTIRANGE: 'NUMMULTIRANGE'>
NUMRANGE = <Type.NUMRANGE: 'NUMRANGE'>
NVARCHAR = <Type.NVARCHAR: 'NVARCHAR'>
OBJECT = <Type.OBJECT: 'OBJECT'>
ROWVERSION = <Type.ROWVERSION: 'ROWVERSION'>
SERIAL = <Type.SERIAL: 'SERIAL'>
SET = <Type.SET: 'SET'>
SMALLINT = <Type.SMALLINT: 'SMALLINT'>
SMALLMONEY = <Type.SMALLMONEY: 'SMALLMONEY'>
SMALLSERIAL = <Type.SMALLSERIAL: 'SMALLSERIAL'>
STRUCT = <Type.STRUCT: 'STRUCT'>
SUPER = <Type.SUPER: 'SUPER'>
TEXT = <Type.TEXT: 'TEXT'>
TINYBLOB = <Type.TINYBLOB: 'TINYBLOB'>
TINYTEXT = <Type.TINYTEXT: 'TINYTEXT'>
TIME = <Type.TIME: 'TIME'>
TIMETZ = <Type.TIMETZ: 'TIMETZ'>
TIMESTAMP = <Type.TIMESTAMP: 'TIMESTAMP'>
TIMESTAMPLTZ = <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>
TIMESTAMPTZ = <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
Inherited Members
enum.Enum
name
value
class PseudoType(DataType):
3706class PseudoType(DataType):
3707    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3711class ObjectIdentifier(DataType):
3712    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3716class SubqueryPredicate(Predicate):
3717    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3720class All(SubqueryPredicate):
3721    pass
key = 'all'
class Any(SubqueryPredicate):
3724class Any(SubqueryPredicate):
3725    pass
key = 'any'
class Exists(SubqueryPredicate):
3728class Exists(SubqueryPredicate):
3729    pass
key = 'exists'
class Command(Expression):
3734class Command(Expression):
3735    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3738class Transaction(Expression):
3739    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3742class Commit(Expression):
3743    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3746class Rollback(Expression):
3747    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3750class AlterTable(Expression):
3751    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):
3754class AddConstraint(Expression):
3755    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3758class DropPartition(Expression):
3759    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
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
arg_types = {'this': True, 'expression': True}
left
right
key = 'binary'
class Add(Binary):
3775class Add(Binary):
3776    pass
key = 'add'
class Connector(Binary):
3779class Connector(Binary):
3780    pass
key = 'connector'
class And(Connector):
3783class And(Connector):
3784    pass
key = 'and'
class Or(Connector):
3787class Or(Connector):
3788    pass
key = 'or'
class BitwiseAnd(Binary):
3791class BitwiseAnd(Binary):
3792    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3795class BitwiseLeftShift(Binary):
3796    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3799class BitwiseOr(Binary):
3800    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3803class BitwiseRightShift(Binary):
3804    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3807class BitwiseXor(Binary):
3808    pass
key = 'bitwisexor'
class Div(Binary):
3811class Div(Binary):
3812    pass
key = 'div'
class Overlaps(Binary):
3815class Overlaps(Binary):
3816    pass
key = 'overlaps'
class Dot(Binary):
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))
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:
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))

Build a Dot object with a sequence of expressions.

key = 'dot'
class DPipe(Binary):
3837class DPipe(Binary):
3838    pass
key = 'dpipe'
class SafeDPipe(DPipe):
3841class SafeDPipe(DPipe):
3842    pass
key = 'safedpipe'
class EQ(Binary, Predicate):
3845class EQ(Binary, Predicate):
3846    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
3849class NullSafeEQ(Binary, Predicate):
3850    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
3853class NullSafeNEQ(Binary, Predicate):
3854    pass
key = 'nullsafeneq'
class Distance(Binary):
3857class Distance(Binary):
3858    pass
key = 'distance'
class Escape(Binary):
3861class Escape(Binary):
3862    pass
key = 'escape'
class Glob(Binary, Predicate):
3865class Glob(Binary, Predicate):
3866    pass
key = 'glob'
class GT(Binary, Predicate):
3869class GT(Binary, Predicate):
3870    pass
key = 'gt'
class GTE(Binary, Predicate):
3873class GTE(Binary, Predicate):
3874    pass
key = 'gte'
class ILike(Binary, Predicate):
3877class ILike(Binary, Predicate):
3878    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
3881class ILikeAny(Binary, Predicate):
3882    pass
key = 'ilikeany'
class IntDiv(Binary):
3885class IntDiv(Binary):
3886    pass
key = 'intdiv'
class Is(Binary, Predicate):
3889class Is(Binary, Predicate):
3890    pass
key = 'is'
class Kwarg(Binary):
3893class Kwarg(Binary):
3894    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
3897class Like(Binary, Predicate):
3898    pass
key = 'like'
class LikeAny(Binary, Predicate):
3901class LikeAny(Binary, Predicate):
3902    pass
key = 'likeany'
class LT(Binary, Predicate):
3905class LT(Binary, Predicate):
3906    pass
key = 'lt'
class LTE(Binary, Predicate):
3909class LTE(Binary, Predicate):
3910    pass
key = 'lte'
class Mod(Binary):
3913class Mod(Binary):
3914    pass
key = 'mod'
class Mul(Binary):
3917class Mul(Binary):
3918    pass
key = 'mul'
class NEQ(Binary, Predicate):
3921class NEQ(Binary, Predicate):
3922    pass
key = 'neq'
class SimilarTo(Binary, Predicate):
3925class SimilarTo(Binary, Predicate):
3926    pass
key = 'similarto'
class Slice(Binary):
3929class Slice(Binary):
3930    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
3933class Sub(Binary):
3934    pass
key = 'sub'
class ArrayOverlaps(Binary):
3937class ArrayOverlaps(Binary):
3938    pass
key = 'arrayoverlaps'
class Unary(Condition):
3943class Unary(Condition):
3944    pass
key = 'unary'
class BitwiseNot(Unary):
3947class BitwiseNot(Unary):
3948    pass
key = 'bitwisenot'
class Not(Unary):
3951class Not(Unary):
3952    pass
key = 'not'
class Paren(Unary):
3955class Paren(Unary):
3956    arg_types = {"this": True, "with": False}
3957
3958    @property
3959    def output_name(self) -> str:
3960        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):
3963class Neg(Unary):
3964    pass
key = 'neg'
class Alias(Expression):
3967class Alias(Expression):
3968    arg_types = {"this": True, "alias": False}
3969
3970    @property
3971    def output_name(self) -> str:
3972        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):
3975class Aliases(Expression):
3976    arg_types = {"this": True, "expressions": True}
3977
3978    @property
3979    def aliases(self):
3980        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
key = 'aliases'
class AtTimeZone(Expression):
3983class AtTimeZone(Expression):
3984    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
3987class Between(Predicate):
3988    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
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
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):
4002class SafeBracket(Bracket):
4003    """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):
4006class Distinct(Expression):
4007    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
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    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class TimeUnit(Expression):
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")

Automatically converts unit arg into a var.

TimeUnit(**args)
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)
arg_types = {'unit': False}
unit: Optional[Var]
key = 'timeunit'
class IntervalSpan(DataType):
4043class IntervalSpan(DataType):
4044    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4047class Interval(TimeUnit):
4048    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4051class IgnoreNulls(Expression):
4052    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4055class RespectNulls(Expression):
4056    pass
key = 'respectnulls'
class Func(Condition):
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()}

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):
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)
@classmethod
def sql_names(cls):
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
@classmethod
def sql_name(cls):
4100    @classmethod
4101    def sql_name(cls):
4102        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4104    @classmethod
4105    def default_parser_mappings(cls):
4106        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4109class AggFunc(Func):
4110    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4113class ParameterizedAgg(AggFunc):
4114    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4117class Abs(Func):
4118    pass
key = 'abs'
class Transform(Func):
4122class Transform(Func):
4123    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4126class Anonymous(Func):
4127    arg_types = {"this": True, "expressions": False}
4128    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class Hll(AggFunc):
4133class Hll(AggFunc):
4134    arg_types = {"this": True, "expressions": False}
4135    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4138class ApproxDistinct(AggFunc):
4139    arg_types = {"this": True, "accuracy": False}
4140    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4143class Array(Func):
4144    arg_types = {"expressions": False}
4145    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToChar(Func):
4149class ToChar(Func):
4150    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tochar'
class GenerateSeries(Func):
4153class GenerateSeries(Func):
4154    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4157class ArrayAgg(AggFunc):
4158    pass
key = 'arrayagg'
class ArrayAll(Func):
4161class ArrayAll(Func):
4162    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4165class ArrayAny(Func):
4166    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4169class ArrayConcat(Func):
4170    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4171    arg_types = {"this": True, "expressions": False}
4172    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4175class ArrayContains(Binary, Func):
4176    pass
key = 'arraycontains'
class ArrayContained(Binary):
4179class ArrayContained(Binary):
4180    pass
key = 'arraycontained'
class ArrayFilter(Func):
4183class ArrayFilter(Func):
4184    arg_types = {"this": True, "expression": True}
4185    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4188class ArrayJoin(Func):
4189    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4192class ArraySize(Func):
4193    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4196class ArraySort(Func):
4197    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4200class ArraySum(Func):
4201    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4204class ArrayUnionAgg(AggFunc):
4205    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4208class Avg(AggFunc):
4209    pass
key = 'avg'
class AnyValue(AggFunc):
4212class AnyValue(AggFunc):
4213    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):
4216class First(Func):
4217    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4220class Last(Func):
4221    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
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
arg_types = {'this': False, 'ifs': True, 'default': False}
def when( self, condition: Union[str, Expression], then: Union[str, Expression], copy: bool = True, **opts) -> Case:
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
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
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
key = 'case'
class Cast(Func):
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)
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:
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)

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):
4274class TryCast(Cast):
4275    pass
key = 'trycast'
class CastToStrType(Func):
4278class CastToStrType(Func):
4279    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary):
4282class Collate(Binary):
4283    pass
key = 'collate'
class Ceil(Func):
4286class Ceil(Func):
4287    arg_types = {"this": True, "decimals": False}
4288    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4291class Coalesce(Func):
4292    arg_types = {"this": True, "expressions": False}
4293    is_var_len_args = True
4294    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4297class Chr(Func):
4298    arg_types = {"this": True, "charset": False, "expressions": False}
4299    is_var_len_args = True
4300    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4303class Concat(Func):
4304    arg_types = {"expressions": True}
4305    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'concat'
class SafeConcat(Concat):
4308class SafeConcat(Concat):
4309    pass
key = 'safeconcat'
class ConcatWs(Concat):
4312class ConcatWs(Concat):
4313    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4316class Count(AggFunc):
4317    arg_types = {"this": False, "expressions": False}
4318    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4321class CountIf(AggFunc):
4322    pass
key = 'countif'
class CurrentDate(Func):
4325class CurrentDate(Func):
4326    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4329class CurrentDatetime(Func):
4330    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4333class CurrentTime(Func):
4334    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4337class CurrentTimestamp(Func):
4338    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4341class CurrentUser(Func):
4342    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, TimeUnit):
4345class DateAdd(Func, TimeUnit):
4346    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, TimeUnit):
4349class DateSub(Func, TimeUnit):
4350    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4353class DateDiff(Func, TimeUnit):
4354    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4355    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
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"]
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
key = 'datetrunc'
class DatetimeAdd(Func, TimeUnit):
4366class DatetimeAdd(Func, TimeUnit):
4367    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, TimeUnit):
4370class DatetimeSub(Func, TimeUnit):
4371    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4374class DatetimeDiff(Func, TimeUnit):
4375    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4378class DatetimeTrunc(Func, TimeUnit):
4379    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4382class DayOfWeek(Func):
4383    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4386class DayOfMonth(Func):
4387    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4390class DayOfYear(Func):
4391    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class WeekOfYear(Func):
4394class WeekOfYear(Func):
4395    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4398class MonthsBetween(Func):
4399    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDateOfMonth(Func):
4402class LastDateOfMonth(Func):
4403    pass
key = 'lastdateofmonth'
class Extract(Func):
4406class Extract(Func):
4407    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4410class Timestamp(Func):
4411    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4414class TimestampAdd(Func, TimeUnit):
4415    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4418class TimestampSub(Func, TimeUnit):
4419    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4422class TimestampDiff(Func, TimeUnit):
4423    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4426class TimestampTrunc(Func, TimeUnit):
4427    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4430class TimeAdd(Func, TimeUnit):
4431    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4434class TimeSub(Func, TimeUnit):
4435    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4438class TimeDiff(Func, TimeUnit):
4439    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4442class TimeTrunc(Func, TimeUnit):
4443    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4446class DateFromParts(Func):
4447    _sql_names = ["DATEFROMPARTS"]
4448    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class DateStrToDate(Func):
4451class DateStrToDate(Func):
4452    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4455class DateToDateStr(Func):
4456    pass
key = 'datetodatestr'
class DateToDi(Func):
4459class DateToDi(Func):
4460    pass
key = 'datetodi'
class Date(Func):
4464class Date(Func):
4465    arg_types = {"this": False, "zone": False, "expressions": False}
4466    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4469class Day(Func):
4470    pass
key = 'day'
class Decode(Func):
4473class Decode(Func):
4474    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4477class DiToDate(Func):
4478    pass
key = 'ditodate'
class Encode(Func):
4481class Encode(Func):
4482    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4485class Exp(Func):
4486    pass
key = 'exp'
class Explode(Func):
4489class Explode(Func):
4490    pass
key = 'explode'
class Floor(Func):
4493class Floor(Func):
4494    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4497class FromBase64(Func):
4498    pass
key = 'frombase64'
class ToBase64(Func):
4501class ToBase64(Func):
4502    pass
key = 'tobase64'
class Greatest(Func):
4505class Greatest(Func):
4506    arg_types = {"this": True, "expressions": False}
4507    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4510class GroupConcat(AggFunc):
4511    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4514class Hex(Func):
4515    pass
key = 'hex'
class Xor(Connector, Func):
4518class Xor(Connector, Func):
4519    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4522class If(Func):
4523    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Initcap(Func):
4526class Initcap(Func):
4527    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4530class IsNan(Func):
4531    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class FormatJson(Expression):
4534class FormatJson(Expression):
4535    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4538class JSONKeyValue(Expression):
4539    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
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    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4553class JSONArray(Func):
4554    arg_types = {
4555        "expressions": True,
4556        "null_handling": False,
4557        "return_type": False,
4558        "strict": False,
4559    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4563class JSONArrayAgg(Func):
4564    arg_types = {
4565        "this": True,
4566        "order": False,
4567        "null_handling": False,
4568        "return_type": False,
4569        "strict": False,
4570    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4575class JSONColumnDef(Expression):
4576    arg_types = {"this": True, "kind": False, "path": False}
arg_types = {'this': True, 'kind': False, 'path': False}
key = 'jsoncolumndef'
class JSONTable(Func):
4580class JSONTable(Func):
4581    arg_types = {
4582        "this": True,
4583        "expressions": True,
4584        "path": False,
4585        "error_handling": False,
4586        "empty_handling": False,
4587    }
arg_types = {'this': True, 'expressions': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4590class OpenJSONColumnDef(Expression):
4591    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):
4594class OpenJSON(Func):
4595    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4598class JSONBContains(Binary):
4599    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4602class JSONExtract(Binary, Func):
4603    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4606class JSONExtractScalar(JSONExtract):
4607    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4610class JSONBExtract(JSONExtract):
4611    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4614class JSONBExtractScalar(JSONExtract):
4615    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4618class JSONFormat(Func):
4619    arg_types = {"this": False, "options": False}
4620    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4624class JSONArrayContains(Binary, Predicate, Func):
4625    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4628class ParseJSON(Func):
4629    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4630    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
key = 'parsejson'
class Least(Func):
4633class Least(Func):
4634    arg_types = {"this": True, "expressions": False}
4635    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4638class Left(Func):
4639    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4646class Length(Func):
4647    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
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    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4660class Ln(Func):
4661    pass
key = 'ln'
class Log(Func):
4664class Log(Func):
4665    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4668class Log2(Func):
4669    pass
key = 'log2'
class Log10(Func):
4672class Log10(Func):
4673    pass
key = 'log10'
class LogicalOr(AggFunc):
4676class LogicalOr(AggFunc):
4677    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4680class LogicalAnd(AggFunc):
4681    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4684class Lower(Func):
4685    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4688class Map(Func):
4689    arg_types = {"keys": False, "values": False}
arg_types = {'keys': False, 'values': False}
key = 'map'
class MapFromEntries(Func):
4692class MapFromEntries(Func):
4693    pass
key = 'mapfromentries'
class StarMap(Func):
4696class StarMap(Func):
4697    pass
key = 'starmap'
class VarMap(Func):
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
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
values: List[Expression]
key = 'varmap'
class MatchAgainst(Func):
4714class MatchAgainst(Func):
4715    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4718class Max(AggFunc):
4719    arg_types = {"this": True, "expressions": False}
4720    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
4723class MD5(Func):
4724    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
4728class MD5Digest(Func):
4729    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
4732class Min(AggFunc):
4733    arg_types = {"this": True, "expressions": False}
4734    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
4737class Month(Func):
4738    pass
key = 'month'
class Nvl2(Func):
4741class Nvl2(Func):
4742    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Posexplode(Func):
4745class Posexplode(Func):
4746    pass
key = 'posexplode'
class Pow(Binary, Func):
4749class Pow(Binary, Func):
4750    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
4753class PercentileCont(AggFunc):
4754    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
4757class PercentileDisc(AggFunc):
4758    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
4761class Quantile(AggFunc):
4762    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
4765class ApproxQuantile(Quantile):
4766    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):
4769class RangeN(Func):
4770    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
4773class ReadCSV(Func):
4774    _sql_names = ["READ_CSV"]
4775    is_var_len_args = True
4776    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
4779class Reduce(Func):
4780    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):
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    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
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    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
4805class RegexpLike(Binary, Func):
4806    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Func):
4809class RegexpILike(Func):
4810    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
4815class RegexpSplit(Func):
4816    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
4819class Repeat(Func):
4820    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
4823class Round(Func):
4824    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
4827class RowNumber(Func):
4828    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
4831class SafeDivide(Func):
4832    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SetAgg(AggFunc):
4835class SetAgg(AggFunc):
4836    pass
key = 'setagg'
class SHA(Func):
4839class SHA(Func):
4840    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
4843class SHA2(Func):
4844    _sql_names = ["SHA2"]
4845    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
4848class SortArray(Func):
4849    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
4852class Split(Func):
4853    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
4858class Substring(Func):
4859    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
4862class StandardHash(Func):
4863    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
4866class StartsWith(Func):
4867    _sql_names = ["STARTS_WITH", "STARTSWITH"]
4868    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
4871class StrPosition(Func):
4872    arg_types = {
4873        "this": True,
4874        "substr": True,
4875        "position": False,
4876        "instance": False,
4877    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
4880class StrToDate(Func):
4881    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
4884class StrToTime(Func):
4885    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
4890class StrToUnix(Func):
4891    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
4896class StrToMap(Func):
4897    arg_types = {
4898        "this": True,
4899        "pair_delim": False,
4900        "key_value_delim": False,
4901        "duplicate_resolution_callback": False,
4902    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
4905class NumberToStr(Func):
4906    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
4909class FromBase(Func):
4910    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
4913class Struct(Func):
4914    arg_types = {"expressions": True}
4915    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
4918class StructExtract(Func):
4919    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
4924class Stuff(Func):
4925    _sql_names = ["STUFF", "INSERT"]
4926    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):
4929class Sum(AggFunc):
4930    pass
key = 'sum'
class Sqrt(Func):
4933class Sqrt(Func):
4934    pass
key = 'sqrt'
class Stddev(AggFunc):
4937class Stddev(AggFunc):
4938    pass
key = 'stddev'
class StddevPop(AggFunc):
4941class StddevPop(AggFunc):
4942    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
4945class StddevSamp(AggFunc):
4946    pass
key = 'stddevsamp'
class TimeToStr(Func):
4949class TimeToStr(Func):
4950    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
4953class TimeToTimeStr(Func):
4954    pass
key = 'timetotimestr'
class TimeToUnix(Func):
4957class TimeToUnix(Func):
4958    pass
key = 'timetounix'
class TimeStrToDate(Func):
4961class TimeStrToDate(Func):
4962    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
4965class TimeStrToTime(Func):
4966    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
4969class TimeStrToUnix(Func):
4970    pass
key = 'timestrtounix'
class Trim(Func):
4973class Trim(Func):
4974    arg_types = {
4975        "this": True,
4976        "expression": False,
4977        "position": False,
4978        "collation": False,
4979    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
4982class TsOrDsAdd(Func, TimeUnit):
4983    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsadd'
class TsOrDsToDateStr(Func):
4986class TsOrDsToDateStr(Func):
4987    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
4990class TsOrDsToDate(Func):
4991    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDiToDi(Func):
4994class TsOrDiToDi(Func):
4995    pass
key = 'tsorditodi'
class Unhex(Func):
4998class Unhex(Func):
4999    pass
key = 'unhex'
class UnixToStr(Func):
5002class UnixToStr(Func):
5003    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
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")
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):
5016class UnixToTimeStr(Func):
5017    pass
key = 'unixtotimestr'
class Upper(Func):
5020class Upper(Func):
5021    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5024class Variance(AggFunc):
5025    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5028class VariancePop(AggFunc):
5029    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5032class Week(Func):
5033    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5036class XMLTable(Func):
5037    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):
5040class Year(Func):
5041    pass
key = 'year'
class Use(Expression):
5044class Use(Expression):
5045    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5048class Merge(Expression):
5049    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):
5052class When(Func):
5053    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):
5058class NextValueFor(Func):
5059    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 '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:
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)

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):
5154def maybe_copy(instance, copy=True):
5155    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:
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)

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:
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)

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:
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)

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:
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)

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:
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)

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:
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

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:
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

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:
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)

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:
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    )

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:
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))

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:
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))

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:
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))

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:
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))

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):
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

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:
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    )

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]:
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

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:
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

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):
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)

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:
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)

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:
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    )

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:
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

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:
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    )

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:
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    )

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:
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)

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:
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    )

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:
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}")

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:
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)

Replace children of an expression with the result of a lambda fun(child) -> exp.

def column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
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    }

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:
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    )

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:
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)

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:
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)

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:
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)

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:
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

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:
6340def true() -> Boolean:
6341    """
6342    Returns a true Boolean expression.
6343    """
6344    return Boolean(this=True)

Returns a true Boolean expression.

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

Returns a false Boolean expression.

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

Returns a Null expression.

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