Edit on GitHub

Expressions

Every AST node in SQLGlot is represented by a subclass of Expression.

This module contains the implementation of all supported Expression types. Additionally, it exposes a number of helper functions, which are mainly used to programmatically build SQL expressions, such as select.


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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

def text(self, key) -> str:
146    def text(self, key) -> str:
147        """
148        Returns a textual representation of the argument corresponding to "key". This can only be used
149        for args that are strings or leaf Expression instances, such as identifiers and literals.
150        """
151        field = self.args.get(key)
152        if isinstance(field, str):
153            return field
154        if isinstance(field, (Identifier, Literal, Var)):
155            return field.this
156        if isinstance(field, (Star, Null)):
157            return field.name
158        return ""

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
160    @property
161    def is_string(self) -> bool:
162        """
163        Checks whether a Literal expression is a string.
164        """
165        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Checks whether a Literal expression is an integer.

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

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
201    @property
202    def alias_column_names(self) -> t.List[str]:
203        table_alias = self.args.get("alias")
204        if not table_alias:
205            return []
206        return [c.name for c in table_alias.args.get("columns") or []]
name: str
208    @property
209    def name(self) -> str:
210        return self.text("this")
alias_or_name: str
212    @property
213    def alias_or_name(self) -> str:
214        return self.alias or self.name
output_name: str
216    @property
217    def output_name(self) -> str:
218        """
219        Name of the output column if this expression is a selection.
220
221        If the Expression has no output name, an empty string is returned.
222
223        Example:
224            >>> from sqlglot import parse_one
225            >>> parse_one("SELECT a").expressions[0].output_name
226            'a'
227            >>> parse_one("SELECT b AS c").expressions[0].output_name
228            'c'
229            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
230            ''
231        """
232        return ""

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]
234    @property
235    def type(self) -> t.Optional[DataType]:
236        return self._type
def is_type(self, *dtypes) -> bool:
244    def is_type(self, *dtypes) -> bool:
245        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
247    def is_leaf(self) -> bool:
248        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
250    @property
251    def meta(self) -> t.Dict[str, t.Any]:
252        if self._meta is None:
253            self._meta = {}
254        return self._meta
def copy(self):
269    def copy(self):
270        """
271        Returns a deep copy of the expression.
272        """
273        new = deepcopy(self)
274        new.parent = self.parent
275        return new

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
277    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
278        if self.comments is None:
279            self.comments = []
280        if comments:
281            for comment in comments:
282                _, *meta = comment.split(SQLGLOT_META)
283                if meta:
284                    for kv in "".join(meta).split(","):
285                        k, *v = kv.split("=")
286                        value = v[0].strip() if v else True
287                        self.meta[k.strip()] = value
288                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
290    def append(self, arg_key: str, value: t.Any) -> None:
291        """
292        Appends value to arg_key if it's a list or sets it as a new list.
293
294        Args:
295            arg_key (str): name of the list expression arg
296            value (Any): value to append to the list
297        """
298        if not isinstance(self.args.get(arg_key), list):
299            self.args[arg_key] = []
300        self.args[arg_key].append(value)
301        self._set_parent(arg_key, value)

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:
303    def set(self, arg_key: str, value: t.Any) -> None:
304        """
305        Sets arg_key to value.
306
307        Args:
308            arg_key: name of the expression arg.
309            value: value to set the arg to.
310        """
311        if value is None:
312            self.args.pop(arg_key, None)
313            return
314
315        self.args[arg_key] = value
316        self._set_parent(arg_key, value)

Sets arg_key to value.

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

Returns the depth of this tree.

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

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

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
348    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
349        """
350        Returns the first node in this tree which matches at least one of
351        the specified types.
352
353        Args:
354            expression_types: the expression type(s) to match.
355            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
356
357        Returns:
358            The node which matches the criteria or None if no such node was found.
359        """
360        return next(self.find_all(*expression_types, bfs=bfs), None)

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]:
362    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
363        """
364        Returns a generator object which visits all nodes in this tree and only
365        yields those that match at least one of the specified expression types.
366
367        Args:
368            expression_types: the expression type(s) to match.
369            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
370
371        Returns:
372            The generator object.
373        """
374        for expression, *_ in self.walk(bfs=bfs):
375            if isinstance(expression, expression_types):
376                yield expression

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]:
378    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
379        """
380        Returns a nearest parent matching expression_types.
381
382        Args:
383            expression_types: the expression type(s) to match.
384
385        Returns:
386            The parent node.
387        """
388        ancestor = self.parent
389        while ancestor and not isinstance(ancestor, expression_types):
390            ancestor = ancestor.parent
391        return t.cast(E, ancestor)

Returns a nearest parent matching expression_types.

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

The parent node.

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

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

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

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

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

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

Returns:

The generator object.

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

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
491    def flatten(self, unnest=True):
492        """
493        Returns a generator which yields child nodes whose parents are the same class.
494
495        A AND B AND C -> [A, B, C]
496        """
497        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and not type(n) is self.__class__):
498            if not type(node) is self.__class__:
499                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

Returns a generator which yields child nodes whose parents are the same class.

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

def to_s(self) -> str:
507    def to_s(self) -> str:
508        """
509        Same as __repr__, but includes additional information which can be useful
510        for debugging, like empty or missing args and the AST nodes' object IDs.
511        """
512        return _to_s(self, verbose=True)

Same as __repr__, but includes additional information which can be useful for debugging, like empty or missing args and the AST nodes' object IDs.

def sql( self, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> str:
514    def sql(self, dialect: DialectType = None, **opts) -> str:
515        """
516        Returns SQL string representation of this tree.
517
518        Args:
519            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
520            opts: other `sqlglot.generator.Generator` options.
521
522        Returns:
523            The SQL string.
524        """
525        from sqlglot.dialects import Dialect
526
527        return Dialect.get_or_raise(dialect).generate(self, **opts)

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):
529    def transform(self, fun, *args, copy=True, **kwargs):
530        """
531        Recursively visits all tree nodes (excluding already transformed ones)
532        and applies the given transformation function to each node.
533
534        Args:
535            fun (function): a function which takes a node as an argument and returns a
536                new transformed node or the same node without modifications. If the function
537                returns None, then the corresponding node will be removed from the syntax tree.
538            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
539                modified in place.
540
541        Returns:
542            The transformed tree.
543        """
544        node = self.copy() if copy else self
545        new_node = fun(node, *args, **kwargs)
546
547        if new_node is None or not isinstance(new_node, Expression):
548            return new_node
549        if new_node is not node:
550            new_node.parent = node.parent
551            return new_node
552
553        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
554        return new_node

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):
564    def replace(self, expression):
565        """
566        Swap out this expression with a new expression.
567
568        For example::
569
570            >>> tree = Select().select("x").from_("tbl")
571            >>> tree.find(Column).replace(column("y"))
572            Column(
573              this=Identifier(this=y, quoted=False))
574            >>> tree.sql()
575            'SELECT y FROM tbl'
576
577        Args:
578            expression: new node
579
580        Returns:
581            The new expression or expressions.
582        """
583        if not self.parent:
584            return expression
585
586        parent = self.parent
587        self.parent = None
588
589        replace_children(parent, lambda child: expression if child is self else child)
590        return expression

Swap out this expression with a new expression.

For example::

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

The new expression or expressions.

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

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
602    def assert_is(self, type_: t.Type[E]) -> E:
603        """
604        Assert that this `Expression` is an instance of `type_`.
605
606        If it is NOT an instance of `type_`, this raises an assertion error.
607        Otherwise, this returns this expression.
608
609        Examples:
610            This is useful for type security in chained expressions:
611
612            >>> import sqlglot
613            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
614            'SELECT x, z FROM y'
615        """
616        assert isinstance(self, type_)
617        return self

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]:
619    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
620        """
621        Checks if this expression is valid (e.g. all mandatory args are set).
622
623        Args:
624            args: a sequence of values that were used to instantiate a Func expression. This is used
625                to check that the provided arguments don't exceed the function argument limit.
626
627        Returns:
628            A list of error messages for all possible errors that were found.
629        """
630        errors: t.List[str] = []
631
632        for k in self.args:
633            if k not in self.arg_types:
634                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
635        for k, mandatory in self.arg_types.items():
636            v = self.args.get(k)
637            if mandatory and (v is None or (isinstance(v, list) and not v)):
638                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
639
640        if (
641            args
642            and isinstance(self, Func)
643            and len(args) > len(self.arg_types)
644            and not self.is_var_len_args
645        ):
646            errors.append(
647                f"The number of provided arguments ({len(args)}) is greater than "
648                f"the maximum number of supported arguments ({len(self.arg_types)})"
649            )
650
651        return errors

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):
653    def dump(self):
654        """
655        Dump this Expression to a JSON-serializable dict.
656        """
657        from sqlglot.serde import dump
658
659        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
661    @classmethod
662    def load(cls, obj):
663        """
664        Load a dict (as returned by `Expression.dump`) into an Expression instance.
665        """
666        from sqlglot.serde import load
667
668        return load(obj)

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:
670    def and_(
671        self,
672        *expressions: t.Optional[ExpOrStr],
673        dialect: DialectType = None,
674        copy: bool = True,
675        **opts,
676    ) -> Condition:
677        """
678        AND this condition with one or multiple expressions.
679
680        Example:
681            >>> condition("x=1").and_("y=1").sql()
682            'x = 1 AND y = 1'
683
684        Args:
685            *expressions: the SQL code strings to parse.
686                If an `Expression` instance is passed, it will be used as-is.
687            dialect: the dialect used to parse the input expression.
688            copy: whether or not to copy the involved expressions (only applies to Expressions).
689            opts: other options to use to parse the input expressions.
690
691        Returns:
692            The new And condition.
693        """
694        return and_(self, *expressions, dialect=dialect, copy=copy, **opts)

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:
696    def or_(
697        self,
698        *expressions: t.Optional[ExpOrStr],
699        dialect: DialectType = None,
700        copy: bool = True,
701        **opts,
702    ) -> Condition:
703        """
704        OR this condition with one or multiple expressions.
705
706        Example:
707            >>> condition("x=1").or_("y=1").sql()
708            'x = 1 OR y = 1'
709
710        Args:
711            *expressions: the SQL code strings to parse.
712                If an `Expression` instance is passed, it will be used as-is.
713            dialect: the dialect used to parse the input expression.
714            copy: whether or not to copy the involved expressions (only applies to Expressions).
715            opts: other options to use to parse the input expressions.
716
717        Returns:
718            The new Or condition.
719        """
720        return or_(self, *expressions, dialect=dialect, copy=copy, **opts)

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):
722    def not_(self, copy: bool = True):
723        """
724        Wrap this condition with NOT.
725
726        Example:
727            >>> condition("x=1").not_().sql()
728            'NOT x = 1'
729
730        Args:
731            copy: whether or not to copy this object.
732
733        Returns:
734            The new Not instance.
735        """
736        return not_(self, copy=copy)

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:
738    def as_(
739        self,
740        alias: str | Identifier,
741        quoted: t.Optional[bool] = None,
742        dialect: DialectType = None,
743        copy: bool = True,
744        **opts,
745    ) -> Alias:
746        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
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:
771    def isin(
772        self,
773        *expressions: t.Any,
774        query: t.Optional[ExpOrStr] = None,
775        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
776        copy: bool = True,
777        **opts,
778    ) -> In:
779        return In(
780            this=maybe_copy(self, copy),
781            expressions=[convert(e, copy=copy) for e in expressions],
782            query=maybe_parse(query, copy=copy, **opts) if query else None,
783            unnest=Unnest(
784                expressions=[
785                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
786                ]
787            )
788            if unnest
789            else None,
790        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
792    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
793        return Between(
794            this=maybe_copy(self, copy),
795            low=convert(low, copy=copy, **opts),
796            high=convert(high, copy=copy, **opts),
797        )
def is_( self, other: Union[str, Expression]) -> Is:
799    def is_(self, other: ExpOrStr) -> Is:
800        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
802    def like(self, other: ExpOrStr) -> Like:
803        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
805    def ilike(self, other: ExpOrStr) -> ILike:
806        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
808    def eq(self, other: t.Any) -> EQ:
809        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
811    def neq(self, other: t.Any) -> NEQ:
812        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
814    def rlike(self, other: ExpOrStr) -> RegexpLike:
815        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
817    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
818        div = self._binop(Div, other)
819        div.args["typed"] = typed
820        div.args["safe"] = safe
821        return div
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
904class Condition(Expression):
905    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

Set the RETURNING expression. Not supported by all dialects.

Example:
>>> delete("tbl").returning("*", dialect="postgres").sql()
'DELETE FROM tbl RETURNING *'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

key = 'dml'
class Create(DDL):
1075class Create(DDL):
1076    arg_types = {
1077        "with": False,
1078        "this": True,
1079        "kind": True,
1080        "expression": False,
1081        "exists": False,
1082        "properties": False,
1083        "replace": False,
1084        "unique": False,
1085        "indexes": False,
1086        "no_schema_binding": False,
1087        "begin": False,
1088        "end": False,
1089        "clone": False,
1090    }
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False}
key = 'create'
class Clone(Expression):
1096class Clone(Expression):
1097    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1100class Describe(Expression):
1101    arg_types = {"this": True, "kind": False, "expressions": False}
arg_types = {'this': True, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1104class Kill(Expression):
1105    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1108class Pragma(Expression):
1109    pass
key = 'pragma'
class Set(Expression):
1112class Set(Expression):
1113    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class SetItem(Expression):
1116class SetItem(Expression):
1117    arg_types = {
1118        "this": False,
1119        "expressions": False,
1120        "kind": False,
1121        "collate": False,  # MySQL SET NAMES statement
1122        "global": False,
1123    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1126class Show(Expression):
1127    arg_types = {
1128        "this": True,
1129        "target": False,
1130        "offset": False,
1131        "limit": False,
1132        "like": False,
1133        "where": False,
1134        "db": False,
1135        "scope": False,
1136        "scope_kind": False,
1137        "full": False,
1138        "mutex": False,
1139        "query": False,
1140        "channel": False,
1141        "global": False,
1142        "log": False,
1143        "position": False,
1144        "types": False,
1145    }
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):
1148class UserDefinedFunction(Expression):
1149    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1152class CharacterSet(Expression):
1153    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1156class With(Expression):
1157    arg_types = {"expressions": True, "recursive": False}
1158
1159    @property
1160    def recursive(self) -> bool:
1161        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1159    @property
1160    def recursive(self) -> bool:
1161        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1164class WithinGroup(Expression):
1165    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1170class CTE(DerivedTable):
1171    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1174class TableAlias(Expression):
1175    arg_types = {"this": False, "columns": False}
1176
1177    @property
1178    def columns(self):
1179        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1177    @property
1178    def columns(self):
1179        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1182class BitString(Condition):
1183    pass
key = 'bitstring'
class HexString(Condition):
1186class HexString(Condition):
1187    pass
key = 'hexstring'
class ByteString(Condition):
1190class ByteString(Condition):
1191    pass
key = 'bytestring'
class RawString(Condition):
1194class RawString(Condition):
1195    pass
key = 'rawstring'
class UnicodeString(Condition):
1198class UnicodeString(Condition):
1199    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1202class Column(Condition):
1203    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1204
1205    @property
1206    def table(self) -> str:
1207        return self.text("table")
1208
1209    @property
1210    def db(self) -> str:
1211        return self.text("db")
1212
1213    @property
1214    def catalog(self) -> str:
1215        return self.text("catalog")
1216
1217    @property
1218    def output_name(self) -> str:
1219        return self.name
1220
1221    @property
1222    def parts(self) -> t.List[Identifier]:
1223        """Return the parts of a column in order catalog, db, table, name."""
1224        return [
1225            t.cast(Identifier, self.args[part])
1226            for part in ("catalog", "db", "table", "this")
1227            if self.args.get(part)
1228        ]
1229
1230    def to_dot(self) -> Dot | Identifier:
1231        """Converts the column into a dot expression."""
1232        parts = self.parts
1233        parent = self.parent
1234
1235        while parent:
1236            if isinstance(parent, Dot):
1237                parts.append(parent.expression)
1238            parent = parent.parent
1239
1240        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
1205    @property
1206    def table(self) -> str:
1207        return self.text("table")
db: str
1209    @property
1210    def db(self) -> str:
1211        return self.text("db")
catalog: str
1213    @property
1214    def catalog(self) -> str:
1215        return self.text("catalog")
output_name: str
1217    @property
1218    def output_name(self) -> str:
1219        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
parts: List[Identifier]
1221    @property
1222    def parts(self) -> t.List[Identifier]:
1223        """Return the parts of a column in order catalog, db, table, name."""
1224        return [
1225            t.cast(Identifier, self.args[part])
1226            for part in ("catalog", "db", "table", "this")
1227            if self.args.get(part)
1228        ]

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

def to_dot(self) -> Dot | Identifier:
1230    def to_dot(self) -> Dot | Identifier:
1231        """Converts the column into a dot expression."""
1232        parts = self.parts
1233        parent = self.parent
1234
1235        while parent:
1236            if isinstance(parent, Dot):
1237                parts.append(parent.expression)
1238            parent = parent.parent
1239
1240        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1243class ColumnPosition(Expression):
1244    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1247class ColumnDef(Expression):
1248    arg_types = {
1249        "this": True,
1250        "kind": False,
1251        "constraints": False,
1252        "exists": False,
1253        "position": False,
1254    }
1255
1256    @property
1257    def constraints(self) -> t.List[ColumnConstraint]:
1258        return self.args.get("constraints") or []
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1256    @property
1257    def constraints(self) -> t.List[ColumnConstraint]:
1258        return self.args.get("constraints") or []
key = 'columndef'
class AlterColumn(Expression):
1261class AlterColumn(Expression):
1262    arg_types = {
1263        "this": True,
1264        "dtype": False,
1265        "collate": False,
1266        "using": False,
1267        "default": False,
1268        "drop": False,
1269    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False}
key = 'altercolumn'
class RenameTable(Expression):
1272class RenameTable(Expression):
1273    pass
key = 'renametable'
class SwapTable(Expression):
1276class SwapTable(Expression):
1277    pass
key = 'swaptable'
class Comment(Expression):
1280class Comment(Expression):
1281    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):
1284class Comprehension(Expression):
1285    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):
1289class MergeTreeTTLAction(Expression):
1290    arg_types = {
1291        "this": True,
1292        "delete": False,
1293        "recompress": False,
1294        "to_disk": False,
1295        "to_volume": False,
1296    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1300class MergeTreeTTL(Expression):
1301    arg_types = {
1302        "expressions": True,
1303        "where": False,
1304        "group": False,
1305        "aggregates": False,
1306    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1310class IndexConstraintOption(Expression):
1311    arg_types = {
1312        "key_block_size": False,
1313        "using": False,
1314        "parser": False,
1315        "comment": False,
1316        "visible": False,
1317        "engine_attr": False,
1318        "secondary_engine_attr": False,
1319    }
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):
1322class ColumnConstraint(Expression):
1323    arg_types = {"this": False, "kind": True}
1324
1325    @property
1326    def kind(self) -> ColumnConstraintKind:
1327        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1325    @property
1326    def kind(self) -> ColumnConstraintKind:
1327        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1330class ColumnConstraintKind(Expression):
1331    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1334class AutoIncrementColumnConstraint(ColumnConstraintKind):
1335    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1338class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1339    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1342class CaseSpecificColumnConstraint(ColumnConstraintKind):
1343    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1346class CharacterSetColumnConstraint(ColumnConstraintKind):
1347    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1350class CheckColumnConstraint(ColumnConstraintKind):
1351    pass
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1354class ClusteredColumnConstraint(ColumnConstraintKind):
1355    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1358class CollateColumnConstraint(ColumnConstraintKind):
1359    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1362class CommentColumnConstraint(ColumnConstraintKind):
1363    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1366class CompressColumnConstraint(ColumnConstraintKind):
1367    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1370class DateFormatColumnConstraint(ColumnConstraintKind):
1371    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1374class DefaultColumnConstraint(ColumnConstraintKind):
1375    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1378class EncodeColumnConstraint(ColumnConstraintKind):
1379    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1382class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1383    # this: True -> ALWAYS, this: False -> BY DEFAULT
1384    arg_types = {
1385        "this": False,
1386        "expression": False,
1387        "on_null": False,
1388        "start": False,
1389        "increment": False,
1390        "minvalue": False,
1391        "maxvalue": False,
1392        "cycle": False,
1393    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1396class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1397    arg_types = {"start": True, "hidden": False}
arg_types = {'start': True, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1401class IndexColumnConstraint(ColumnConstraintKind):
1402    arg_types = {
1403        "this": False,
1404        "schema": True,
1405        "kind": False,
1406        "index_type": False,
1407        "options": False,
1408    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1411class InlineLengthColumnConstraint(ColumnConstraintKind):
1412    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1415class NonClusteredColumnConstraint(ColumnConstraintKind):
1416    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1419class NotForReplicationColumnConstraint(ColumnConstraintKind):
1420    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1423class NotNullColumnConstraint(ColumnConstraintKind):
1424    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1428class OnUpdateColumnConstraint(ColumnConstraintKind):
1429    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1433class TransformColumnConstraint(ColumnConstraintKind):
1434    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1437class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1438    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1441class TitleColumnConstraint(ColumnConstraintKind):
1442    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1445class UniqueColumnConstraint(ColumnConstraintKind):
1446    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1449class UppercaseColumnConstraint(ColumnConstraintKind):
1450    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1453class PathColumnConstraint(ColumnConstraintKind):
1454    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1459class ComputedColumnConstraint(ColumnConstraintKind):
1460    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1463class Constraint(Expression):
1464    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1467class Delete(DML):
1468    arg_types = {
1469        "with": False,
1470        "this": False,
1471        "using": False,
1472        "where": False,
1473        "returning": False,
1474        "limit": False,
1475        "tables": False,  # Multiple-Table Syntax (MySQL)
1476    }
1477
1478    def delete(
1479        self,
1480        table: ExpOrStr,
1481        dialect: DialectType = None,
1482        copy: bool = True,
1483        **opts,
1484    ) -> Delete:
1485        """
1486        Create a DELETE expression or replace the table on an existing DELETE expression.
1487
1488        Example:
1489            >>> delete("tbl").sql()
1490            'DELETE FROM tbl'
1491
1492        Args:
1493            table: the table from which to delete.
1494            dialect: the dialect used to parse the input expression.
1495            copy: if `False`, modify this expression instance in-place.
1496            opts: other options to use to parse the input expressions.
1497
1498        Returns:
1499            Delete: the modified expression.
1500        """
1501        return _apply_builder(
1502            expression=table,
1503            instance=self,
1504            arg="this",
1505            dialect=dialect,
1506            into=Table,
1507            copy=copy,
1508            **opts,
1509        )
1510
1511    def where(
1512        self,
1513        *expressions: t.Optional[ExpOrStr],
1514        append: bool = True,
1515        dialect: DialectType = None,
1516        copy: bool = True,
1517        **opts,
1518    ) -> Delete:
1519        """
1520        Append to or set the WHERE expressions.
1521
1522        Example:
1523            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1524            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1525
1526        Args:
1527            *expressions: the SQL code strings to parse.
1528                If an `Expression` instance is passed, it will be used as-is.
1529                Multiple expressions are combined with an AND operator.
1530            append: if `True`, AND the new expressions to any existing expression.
1531                Otherwise, this resets the expression.
1532            dialect: the dialect used to parse the input expressions.
1533            copy: if `False`, modify this expression instance in-place.
1534            opts: other options to use to parse the input expressions.
1535
1536        Returns:
1537            Delete: the modified expression.
1538        """
1539        return _apply_conjunction_builder(
1540            *expressions,
1541            instance=self,
1542            arg="where",
1543            append=append,
1544            into=Where,
1545            dialect=dialect,
1546            copy=copy,
1547            **opts,
1548        )
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:
1478    def delete(
1479        self,
1480        table: ExpOrStr,
1481        dialect: DialectType = None,
1482        copy: bool = True,
1483        **opts,
1484    ) -> Delete:
1485        """
1486        Create a DELETE expression or replace the table on an existing DELETE expression.
1487
1488        Example:
1489            >>> delete("tbl").sql()
1490            'DELETE FROM tbl'
1491
1492        Args:
1493            table: the table from which to delete.
1494            dialect: the dialect used to parse the input expression.
1495            copy: if `False`, modify this expression instance in-place.
1496            opts: other options to use to parse the input expressions.
1497
1498        Returns:
1499            Delete: the modified expression.
1500        """
1501        return _apply_builder(
1502            expression=table,
1503            instance=self,
1504            arg="this",
1505            dialect=dialect,
1506            into=Table,
1507            copy=copy,
1508            **opts,
1509        )

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

Append to or set the WHERE expressions.

Example:
>>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
"DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

key = 'delete'
class Drop(Expression):
1551class Drop(Expression):
1552    arg_types = {
1553        "this": False,
1554        "kind": False,
1555        "exists": False,
1556        "temporary": False,
1557        "materialized": False,
1558        "cascade": False,
1559        "constraints": False,
1560        "purge": False,
1561    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1564class Filter(Expression):
1565    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1568class Check(Expression):
1569    pass
key = 'check'
class Connect(Expression):
1573class Connect(Expression):
1574    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1577class Prior(Expression):
1578    pass
key = 'prior'
class Directory(Expression):
1581class Directory(Expression):
1582    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1583    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1586class ForeignKey(Expression):
1587    arg_types = {
1588        "expressions": True,
1589        "reference": False,
1590        "delete": False,
1591        "update": False,
1592    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1595class ColumnPrefix(Expression):
1596    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1599class PrimaryKey(Expression):
1600    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1605class Into(Expression):
1606    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1609class From(Expression):
1610    @property
1611    def name(self) -> str:
1612        return self.this.name
1613
1614    @property
1615    def alias_or_name(self) -> str:
1616        return self.this.alias_or_name
name: str
1610    @property
1611    def name(self) -> str:
1612        return self.this.name
alias_or_name: str
1614    @property
1615    def alias_or_name(self) -> str:
1616        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1619class Having(Expression):
1620    pass
key = 'having'
class Hint(Expression):
1623class Hint(Expression):
1624    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1627class JoinHint(Expression):
1628    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1631class Identifier(Expression):
1632    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1633
1634    @property
1635    def quoted(self) -> bool:
1636        return bool(self.args.get("quoted"))
1637
1638    @property
1639    def hashable_args(self) -> t.Any:
1640        return (self.this, self.quoted)
1641
1642    @property
1643    def output_name(self) -> str:
1644        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1634    @property
1635    def quoted(self) -> bool:
1636        return bool(self.args.get("quoted"))
hashable_args: Any
1638    @property
1639    def hashable_args(self) -> t.Any:
1640        return (self.this, self.quoted)
output_name: str
1642    @property
1643    def output_name(self) -> str:
1644        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'identifier'
class Opclass(Expression):
1648class Opclass(Expression):
1649    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1652class Index(Expression):
1653    arg_types = {
1654        "this": False,
1655        "table": False,
1656        "using": False,
1657        "where": False,
1658        "columns": False,
1659        "unique": False,
1660        "primary": False,
1661        "amp": False,  # teradata
1662        "partition_by": False,  # teradata
1663        "where": False,  # postgres partial indexes
1664    }
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, DML):
1667class Insert(DDL, DML):
1668    arg_types = {
1669        "with": False,
1670        "this": True,
1671        "expression": False,
1672        "conflict": False,
1673        "returning": False,
1674        "overwrite": False,
1675        "exists": False,
1676        "partition": False,
1677        "alternative": False,
1678        "where": False,
1679        "ignore": False,
1680        "by_name": False,
1681    }
1682
1683    def with_(
1684        self,
1685        alias: ExpOrStr,
1686        as_: ExpOrStr,
1687        recursive: t.Optional[bool] = None,
1688        append: bool = True,
1689        dialect: DialectType = None,
1690        copy: bool = True,
1691        **opts,
1692    ) -> Insert:
1693        """
1694        Append to or set the common table expressions.
1695
1696        Example:
1697            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1698            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1699
1700        Args:
1701            alias: the SQL code string to parse as the table name.
1702                If an `Expression` instance is passed, this is used as-is.
1703            as_: the SQL code string to parse as the table expression.
1704                If an `Expression` instance is passed, it will be used as-is.
1705            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1706            append: if `True`, add to any existing expressions.
1707                Otherwise, this resets the expressions.
1708            dialect: the dialect used to parse the input expression.
1709            copy: if `False`, modify this expression instance in-place.
1710            opts: other options to use to parse the input expressions.
1711
1712        Returns:
1713            The modified expression.
1714        """
1715        return _apply_cte_builder(
1716            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1717        )
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:
1683    def with_(
1684        self,
1685        alias: ExpOrStr,
1686        as_: ExpOrStr,
1687        recursive: t.Optional[bool] = None,
1688        append: bool = True,
1689        dialect: DialectType = None,
1690        copy: bool = True,
1691        **opts,
1692    ) -> Insert:
1693        """
1694        Append to or set the common table expressions.
1695
1696        Example:
1697            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1698            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1699
1700        Args:
1701            alias: the SQL code string to parse as the table name.
1702                If an `Expression` instance is passed, this is used as-is.
1703            as_: the SQL code string to parse as the table expression.
1704                If an `Expression` instance is passed, it will be used as-is.
1705            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1706            append: if `True`, add to any existing expressions.
1707                Otherwise, this resets the expressions.
1708            dialect: the dialect used to parse the input expression.
1709            copy: if `False`, modify this expression instance in-place.
1710            opts: other options to use to parse the input expressions.
1711
1712        Returns:
1713            The modified expression.
1714        """
1715        return _apply_cte_builder(
1716            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1717        )

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):
1720class OnConflict(Expression):
1721    arg_types = {
1722        "duplicate": False,
1723        "expressions": False,
1724        "nothing": False,
1725        "key": False,
1726        "constraint": False,
1727    }
arg_types = {'duplicate': False, 'expressions': False, 'nothing': False, 'key': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1730class Returning(Expression):
1731    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1735class Introducer(Expression):
1736    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1740class National(Expression):
1741    pass
key = 'national'
class LoadData(Expression):
1744class LoadData(Expression):
1745    arg_types = {
1746        "this": True,
1747        "local": False,
1748        "overwrite": False,
1749        "inpath": True,
1750        "partition": False,
1751        "input_format": False,
1752        "serde": False,
1753    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1756class Partition(Expression):
1757    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class Fetch(Expression):
1760class Fetch(Expression):
1761    arg_types = {
1762        "direction": False,
1763        "count": False,
1764        "percent": False,
1765        "with_ties": False,
1766    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1769class Group(Expression):
1770    arg_types = {
1771        "expressions": False,
1772        "grouping_sets": False,
1773        "cube": False,
1774        "rollup": False,
1775        "totals": False,
1776        "all": False,
1777    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1780class Lambda(Expression):
1781    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1784class Limit(Expression):
1785    arg_types = {"this": False, "expression": True, "offset": False}
arg_types = {'this': False, 'expression': True, 'offset': False}
key = 'limit'
class Literal(Condition):
1788class Literal(Condition):
1789    arg_types = {"this": True, "is_string": True}
1790
1791    @property
1792    def hashable_args(self) -> t.Any:
1793        return (self.this, self.args.get("is_string"))
1794
1795    @classmethod
1796    def number(cls, number) -> Literal:
1797        return cls(this=str(number), is_string=False)
1798
1799    @classmethod
1800    def string(cls, string) -> Literal:
1801        return cls(this=str(string), is_string=True)
1802
1803    @property
1804    def output_name(self) -> str:
1805        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
1791    @property
1792    def hashable_args(self) -> t.Any:
1793        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
1795    @classmethod
1796    def number(cls, number) -> Literal:
1797        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
1799    @classmethod
1800    def string(cls, string) -> Literal:
1801        return cls(this=str(string), is_string=True)
output_name: str
1803    @property
1804    def output_name(self) -> str:
1805        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'literal'
class Join(Expression):
1808class Join(Expression):
1809    arg_types = {
1810        "this": True,
1811        "on": False,
1812        "side": False,
1813        "kind": False,
1814        "using": False,
1815        "method": False,
1816        "global": False,
1817        "hint": False,
1818    }
1819
1820    @property
1821    def method(self) -> str:
1822        return self.text("method").upper()
1823
1824    @property
1825    def kind(self) -> str:
1826        return self.text("kind").upper()
1827
1828    @property
1829    def side(self) -> str:
1830        return self.text("side").upper()
1831
1832    @property
1833    def hint(self) -> str:
1834        return self.text("hint").upper()
1835
1836    @property
1837    def alias_or_name(self) -> str:
1838        return self.this.alias_or_name
1839
1840    def on(
1841        self,
1842        *expressions: t.Optional[ExpOrStr],
1843        append: bool = True,
1844        dialect: DialectType = None,
1845        copy: bool = True,
1846        **opts,
1847    ) -> Join:
1848        """
1849        Append to or set the ON expressions.
1850
1851        Example:
1852            >>> import sqlglot
1853            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1854            'JOIN x ON y = 1'
1855
1856        Args:
1857            *expressions: the SQL code strings to parse.
1858                If an `Expression` instance is passed, it will be used as-is.
1859                Multiple expressions are combined with an AND operator.
1860            append: if `True`, AND the new expressions to any existing expression.
1861                Otherwise, this resets the expression.
1862            dialect: the dialect used to parse the input expressions.
1863            copy: if `False`, modify this expression instance in-place.
1864            opts: other options to use to parse the input expressions.
1865
1866        Returns:
1867            The modified Join expression.
1868        """
1869        join = _apply_conjunction_builder(
1870            *expressions,
1871            instance=self,
1872            arg="on",
1873            append=append,
1874            dialect=dialect,
1875            copy=copy,
1876            **opts,
1877        )
1878
1879        if join.kind == "CROSS":
1880            join.set("kind", None)
1881
1882        return join
1883
1884    def using(
1885        self,
1886        *expressions: t.Optional[ExpOrStr],
1887        append: bool = True,
1888        dialect: DialectType = None,
1889        copy: bool = True,
1890        **opts,
1891    ) -> Join:
1892        """
1893        Append to or set the USING expressions.
1894
1895        Example:
1896            >>> import sqlglot
1897            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1898            'JOIN x USING (foo, bla)'
1899
1900        Args:
1901            *expressions: the SQL code strings to parse.
1902                If an `Expression` instance is passed, it will be used as-is.
1903            append: if `True`, concatenate the new expressions to the existing "using" list.
1904                Otherwise, this resets the expression.
1905            dialect: the dialect used to parse the input expressions.
1906            copy: if `False`, modify this expression instance in-place.
1907            opts: other options to use to parse the input expressions.
1908
1909        Returns:
1910            The modified Join expression.
1911        """
1912        join = _apply_list_builder(
1913            *expressions,
1914            instance=self,
1915            arg="using",
1916            append=append,
1917            dialect=dialect,
1918            copy=copy,
1919            **opts,
1920        )
1921
1922        if join.kind == "CROSS":
1923            join.set("kind", None)
1924
1925        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
1820    @property
1821    def method(self) -> str:
1822        return self.text("method").upper()
kind: str
1824    @property
1825    def kind(self) -> str:
1826        return self.text("kind").upper()
side: str
1828    @property
1829    def side(self) -> str:
1830        return self.text("side").upper()
hint: str
1832    @property
1833    def hint(self) -> str:
1834        return self.text("hint").upper()
alias_or_name: str
1836    @property
1837    def alias_or_name(self) -> str:
1838        return self.this.alias_or_name
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
1840    def on(
1841        self,
1842        *expressions: t.Optional[ExpOrStr],
1843        append: bool = True,
1844        dialect: DialectType = None,
1845        copy: bool = True,
1846        **opts,
1847    ) -> Join:
1848        """
1849        Append to or set the ON expressions.
1850
1851        Example:
1852            >>> import sqlglot
1853            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1854            'JOIN x ON y = 1'
1855
1856        Args:
1857            *expressions: the SQL code strings to parse.
1858                If an `Expression` instance is passed, it will be used as-is.
1859                Multiple expressions are combined with an AND operator.
1860            append: if `True`, AND the new expressions to any existing expression.
1861                Otherwise, this resets the expression.
1862            dialect: the dialect used to parse the input expressions.
1863            copy: if `False`, modify this expression instance in-place.
1864            opts: other options to use to parse the input expressions.
1865
1866        Returns:
1867            The modified Join expression.
1868        """
1869        join = _apply_conjunction_builder(
1870            *expressions,
1871            instance=self,
1872            arg="on",
1873            append=append,
1874            dialect=dialect,
1875            copy=copy,
1876            **opts,
1877        )
1878
1879        if join.kind == "CROSS":
1880            join.set("kind", None)
1881
1882        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:
1884    def using(
1885        self,
1886        *expressions: t.Optional[ExpOrStr],
1887        append: bool = True,
1888        dialect: DialectType = None,
1889        copy: bool = True,
1890        **opts,
1891    ) -> Join:
1892        """
1893        Append to or set the USING expressions.
1894
1895        Example:
1896            >>> import sqlglot
1897            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1898            'JOIN x USING (foo, bla)'
1899
1900        Args:
1901            *expressions: the SQL code strings to parse.
1902                If an `Expression` instance is passed, it will be used as-is.
1903            append: if `True`, concatenate the new expressions to the existing "using" list.
1904                Otherwise, this resets the expression.
1905            dialect: the dialect used to parse the input expressions.
1906            copy: if `False`, modify this expression instance in-place.
1907            opts: other options to use to parse the input expressions.
1908
1909        Returns:
1910            The modified Join expression.
1911        """
1912        join = _apply_list_builder(
1913            *expressions,
1914            instance=self,
1915            arg="using",
1916            append=append,
1917            dialect=dialect,
1918            copy=copy,
1919            **opts,
1920        )
1921
1922        if join.kind == "CROSS":
1923            join.set("kind", None)
1924
1925        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):
1928class Lateral(UDTF):
1929    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):
1932class MatchRecognize(Expression):
1933    arg_types = {
1934        "partition_by": False,
1935        "order": False,
1936        "measures": False,
1937        "rows": False,
1938        "after": False,
1939        "pattern": False,
1940        "define": False,
1941        "alias": False,
1942    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
1947class Final(Expression):
1948    pass
key = 'final'
class Offset(Expression):
1951class Offset(Expression):
1952    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'offset'
class Order(Expression):
1955class Order(Expression):
1956    arg_types = {"this": False, "expressions": True, "interpolate": False}
arg_types = {'this': False, 'expressions': True, 'interpolate': False}
key = 'order'
class WithFill(Expression):
1960class WithFill(Expression):
1961    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
1966class Cluster(Order):
1967    pass
key = 'cluster'
class Distribute(Order):
1970class Distribute(Order):
1971    pass
key = 'distribute'
class Sort(Order):
1974class Sort(Order):
1975    pass
key = 'sort'
class Ordered(Expression):
1978class Ordered(Expression):
1979    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
key = 'ordered'
class Property(Expression):
1982class Property(Expression):
1983    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
1986class AlgorithmProperty(Property):
1987    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
1990class AutoIncrementProperty(Property):
1991    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
1995class AutoRefreshProperty(Property):
1996    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BlockCompressionProperty(Property):
1999class BlockCompressionProperty(Property):
2000    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):
2003class CharacterSetProperty(Property):
2004    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2007class ChecksumProperty(Property):
2008    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2011class CollateProperty(Property):
2012    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2015class CopyGrantsProperty(Property):
2016    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2019class DataBlocksizeProperty(Property):
2020    arg_types = {
2021        "size": False,
2022        "units": False,
2023        "minimum": False,
2024        "maximum": False,
2025        "default": False,
2026    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2029class DefinerProperty(Property):
2030    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2033class DistKeyProperty(Property):
2034    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2037class DistStyleProperty(Property):
2038    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2041class EngineProperty(Property):
2042    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2045class HeapProperty(Property):
2046    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2049class ToTableProperty(Property):
2050    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2053class ExecuteAsProperty(Property):
2054    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2057class ExternalProperty(Property):
2058    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2061class FallbackProperty(Property):
2062    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2065class FileFormatProperty(Property):
2066    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2069class FreespaceProperty(Property):
2070    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InputModelProperty(Property):
2073class InputModelProperty(Property):
2074    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2077class OutputModelProperty(Property):
2078    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2081class IsolatedLoadingProperty(Property):
2082    arg_types = {
2083        "no": True,
2084        "concurrent": True,
2085        "for_all": True,
2086        "for_insert": True,
2087        "for_none": True,
2088    }
arg_types = {'no': True, 'concurrent': True, 'for_all': True, 'for_insert': True, 'for_none': True}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2091class JournalProperty(Property):
2092    arg_types = {
2093        "no": False,
2094        "dual": False,
2095        "before": False,
2096        "local": False,
2097        "after": False,
2098    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2101class LanguageProperty(Property):
2102    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2106class ClusteredByProperty(Property):
2107    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2110class DictProperty(Property):
2111    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2114class DictSubProperty(Property):
2115    pass
key = 'dictsubproperty'
class DictRange(Property):
2118class DictRange(Property):
2119    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2124class OnCluster(Property):
2125    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2128class LikeProperty(Property):
2129    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2132class LocationProperty(Property):
2133    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockingProperty(Property):
2136class LockingProperty(Property):
2137    arg_types = {
2138        "this": False,
2139        "kind": True,
2140        "for_or_in": False,
2141        "lock_type": True,
2142        "override": False,
2143    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2146class LogProperty(Property):
2147    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2150class MaterializedProperty(Property):
2151    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2154class MergeBlockRatioProperty(Property):
2155    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):
2158class NoPrimaryIndexProperty(Property):
2159    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2162class OnProperty(Property):
2163    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2166class OnCommitProperty(Property):
2167    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2170class PartitionedByProperty(Property):
2171    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2175class PartitionBoundSpec(Expression):
2176    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2177    arg_types = {
2178        "this": False,
2179        "expression": False,
2180        "from_expressions": False,
2181        "to_expressions": False,
2182    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2185class PartitionedOfProperty(Property):
2186    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2187    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2190class RemoteWithConnectionModelProperty(Property):
2191    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2194class ReturnsProperty(Property):
2195    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2198class RowFormatProperty(Property):
2199    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2202class RowFormatDelimitedProperty(Property):
2203    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2204    arg_types = {
2205        "fields": False,
2206        "escaped": False,
2207        "collection_items": False,
2208        "map_keys": False,
2209        "lines": False,
2210        "null": False,
2211        "serde": False,
2212    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2215class RowFormatSerdeProperty(Property):
2216    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2220class QueryTransform(Expression):
2221    arg_types = {
2222        "expressions": True,
2223        "command_script": True,
2224        "schema": False,
2225        "row_format_before": False,
2226        "record_writer": False,
2227        "row_format_after": False,
2228        "record_reader": False,
2229    }
arg_types = {'expressions': True, 'command_script': True, 'schema': False, 'row_format_before': False, 'record_writer': False, 'row_format_after': False, 'record_reader': False}
key = 'querytransform'
class SampleProperty(Property):
2232class SampleProperty(Property):
2233    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2236class SchemaCommentProperty(Property):
2237    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2240class SerdeProperties(Property):
2241    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2244class SetProperty(Property):
2245    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SettingsProperty(Property):
2248class SettingsProperty(Property):
2249    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2252class SortKeyProperty(Property):
2253    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlSecurityProperty(Property):
2256class SqlSecurityProperty(Property):
2257    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2260class StabilityProperty(Property):
2261    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2264class TemporaryProperty(Property):
2265    arg_types = {}
arg_types = {}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2268class TransformModelProperty(Property):
2269    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2272class TransientProperty(Property):
2273    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2276class VolatileProperty(Property):
2277    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2280class WithDataProperty(Property):
2281    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2284class WithJournalTableProperty(Property):
2285    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2288class WithSystemVersioningProperty(Property):
2289    # this -> history table name, expression -> data consistency check
2290    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2293class Properties(Expression):
2294    arg_types = {"expressions": True}
2295
2296    NAME_TO_PROPERTY = {
2297        "ALGORITHM": AlgorithmProperty,
2298        "AUTO_INCREMENT": AutoIncrementProperty,
2299        "CHARACTER SET": CharacterSetProperty,
2300        "CLUSTERED_BY": ClusteredByProperty,
2301        "COLLATE": CollateProperty,
2302        "COMMENT": SchemaCommentProperty,
2303        "DEFINER": DefinerProperty,
2304        "DISTKEY": DistKeyProperty,
2305        "DISTSTYLE": DistStyleProperty,
2306        "ENGINE": EngineProperty,
2307        "EXECUTE AS": ExecuteAsProperty,
2308        "FORMAT": FileFormatProperty,
2309        "LANGUAGE": LanguageProperty,
2310        "LOCATION": LocationProperty,
2311        "PARTITIONED_BY": PartitionedByProperty,
2312        "RETURNS": ReturnsProperty,
2313        "ROW_FORMAT": RowFormatProperty,
2314        "SORTKEY": SortKeyProperty,
2315    }
2316
2317    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2318
2319    # CREATE property locations
2320    # Form: schema specified
2321    #   create [POST_CREATE]
2322    #     table a [POST_NAME]
2323    #     (b int) [POST_SCHEMA]
2324    #     with ([POST_WITH])
2325    #     index (b) [POST_INDEX]
2326    #
2327    # Form: alias selection
2328    #   create [POST_CREATE]
2329    #     table a [POST_NAME]
2330    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2331    #     index (c) [POST_INDEX]
2332    class Location(AutoName):
2333        POST_CREATE = auto()
2334        POST_NAME = auto()
2335        POST_SCHEMA = auto()
2336        POST_WITH = auto()
2337        POST_ALIAS = auto()
2338        POST_EXPRESSION = auto()
2339        POST_INDEX = auto()
2340        UNSUPPORTED = auto()
2341
2342    @classmethod
2343    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2344        expressions = []
2345        for key, value in properties_dict.items():
2346            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2347            if property_cls:
2348                expressions.append(property_cls(this=convert(value)))
2349            else:
2350                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2351
2352        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:
2342    @classmethod
2343    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2344        expressions = []
2345        for key, value in properties_dict.items():
2346            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2347            if property_cls:
2348                expressions.append(property_cls(this=convert(value)))
2349            else:
2350                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2351
2352        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2332    class Location(AutoName):
2333        POST_CREATE = auto()
2334        POST_NAME = auto()
2335        POST_SCHEMA = auto()
2336        POST_WITH = auto()
2337        POST_ALIAS = auto()
2338        POST_EXPRESSION = auto()
2339        POST_INDEX = auto()
2340        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):
2355class Qualify(Expression):
2356    pass
key = 'qualify'
class InputOutputFormat(Expression):
2359class InputOutputFormat(Expression):
2360    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2364class Return(Expression):
2365    pass
key = 'return'
class Reference(Expression):
2368class Reference(Expression):
2369    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2372class Tuple(Expression):
2373    arg_types = {"expressions": False}
2374
2375    def isin(
2376        self,
2377        *expressions: t.Any,
2378        query: t.Optional[ExpOrStr] = None,
2379        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2380        copy: bool = True,
2381        **opts,
2382    ) -> In:
2383        return In(
2384            this=maybe_copy(self, copy),
2385            expressions=[convert(e, copy=copy) for e in expressions],
2386            query=maybe_parse(query, copy=copy, **opts) if query else None,
2387            unnest=Unnest(
2388                expressions=[
2389                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2390                ]
2391            )
2392            if unnest
2393            else None,
2394        )
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:
2375    def isin(
2376        self,
2377        *expressions: t.Any,
2378        query: t.Optional[ExpOrStr] = None,
2379        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2380        copy: bool = True,
2381        **opts,
2382    ) -> In:
2383        return In(
2384            this=maybe_copy(self, copy),
2385            expressions=[convert(e, copy=copy) for e in expressions],
2386            query=maybe_parse(query, copy=copy, **opts) if query else None,
2387            unnest=Unnest(
2388                expressions=[
2389                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2390                ]
2391            )
2392            if unnest
2393            else None,
2394        )
key = 'tuple'
class Subqueryable(Unionable):
2397class Subqueryable(Unionable):
2398    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2399        """
2400        Convert this expression to an aliased expression that can be used as a Subquery.
2401
2402        Example:
2403            >>> subquery = Select().select("x").from_("tbl").subquery()
2404            >>> Select().select("x").from_(subquery).sql()
2405            'SELECT x FROM (SELECT x FROM tbl)'
2406
2407        Args:
2408            alias (str | Identifier): an optional alias for the subquery
2409            copy (bool): if `False`, modify this expression instance in-place.
2410
2411        Returns:
2412            Alias: the subquery
2413        """
2414        instance = maybe_copy(self, copy)
2415        if not isinstance(alias, Expression):
2416            alias = TableAlias(this=to_identifier(alias)) if alias else None
2417
2418        return Subquery(this=instance, alias=alias)
2419
2420    def limit(
2421        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2422    ) -> Select:
2423        raise NotImplementedError
2424
2425    @property
2426    def ctes(self):
2427        with_ = self.args.get("with")
2428        if not with_:
2429            return []
2430        return with_.expressions
2431
2432    @property
2433    def selects(self) -> t.List[Expression]:
2434        raise NotImplementedError("Subqueryable objects must implement `selects`")
2435
2436    @property
2437    def named_selects(self) -> t.List[str]:
2438        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2439
2440    def select(
2441        self,
2442        *expressions: t.Optional[ExpOrStr],
2443        append: bool = True,
2444        dialect: DialectType = None,
2445        copy: bool = True,
2446        **opts,
2447    ) -> Subqueryable:
2448        raise NotImplementedError("Subqueryable objects must implement `select`")
2449
2450    def with_(
2451        self,
2452        alias: ExpOrStr,
2453        as_: ExpOrStr,
2454        recursive: t.Optional[bool] = None,
2455        append: bool = True,
2456        dialect: DialectType = None,
2457        copy: bool = True,
2458        **opts,
2459    ) -> Subqueryable:
2460        """
2461        Append to or set the common table expressions.
2462
2463        Example:
2464            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2465            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2466
2467        Args:
2468            alias: the SQL code string to parse as the table name.
2469                If an `Expression` instance is passed, this is used as-is.
2470            as_: the SQL code string to parse as the table expression.
2471                If an `Expression` instance is passed, it will be used as-is.
2472            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2473            append: if `True`, add to any existing expressions.
2474                Otherwise, this resets the expressions.
2475            dialect: the dialect used to parse the input expression.
2476            copy: if `False`, modify this expression instance in-place.
2477            opts: other options to use to parse the input expressions.
2478
2479        Returns:
2480            The modified expression.
2481        """
2482        return _apply_cte_builder(
2483            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2484        )
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
2398    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2399        """
2400        Convert this expression to an aliased expression that can be used as a Subquery.
2401
2402        Example:
2403            >>> subquery = Select().select("x").from_("tbl").subquery()
2404            >>> Select().select("x").from_(subquery).sql()
2405            'SELECT x FROM (SELECT x FROM tbl)'
2406
2407        Args:
2408            alias (str | Identifier): an optional alias for the subquery
2409            copy (bool): if `False`, modify this expression instance in-place.
2410
2411        Returns:
2412            Alias: the subquery
2413        """
2414        instance = maybe_copy(self, copy)
2415        if not isinstance(alias, Expression):
2416            alias = TableAlias(this=to_identifier(alias)) if alias else None
2417
2418        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:
2420    def limit(
2421        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2422    ) -> Select:
2423        raise NotImplementedError
ctes
2425    @property
2426    def ctes(self):
2427        with_ = self.args.get("with")
2428        if not with_:
2429            return []
2430        return with_.expressions
selects: List[Expression]
2432    @property
2433    def selects(self) -> t.List[Expression]:
2434        raise NotImplementedError("Subqueryable objects must implement `selects`")
named_selects: List[str]
2436    @property
2437    def named_selects(self) -> t.List[str]:
2438        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subqueryable:
2440    def select(
2441        self,
2442        *expressions: t.Optional[ExpOrStr],
2443        append: bool = True,
2444        dialect: DialectType = None,
2445        copy: bool = True,
2446        **opts,
2447    ) -> Subqueryable:
2448        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:
2450    def with_(
2451        self,
2452        alias: ExpOrStr,
2453        as_: ExpOrStr,
2454        recursive: t.Optional[bool] = None,
2455        append: bool = True,
2456        dialect: DialectType = None,
2457        copy: bool = True,
2458        **opts,
2459    ) -> Subqueryable:
2460        """
2461        Append to or set the common table expressions.
2462
2463        Example:
2464            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2465            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2466
2467        Args:
2468            alias: the SQL code string to parse as the table name.
2469                If an `Expression` instance is passed, this is used as-is.
2470            as_: the SQL code string to parse as the table expression.
2471                If an `Expression` instance is passed, it will be used as-is.
2472            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2473            append: if `True`, add to any existing expressions.
2474                Otherwise, this resets the expressions.
2475            dialect: the dialect used to parse the input expression.
2476            copy: if `False`, modify this expression instance in-place.
2477            opts: other options to use to parse the input expressions.
2478
2479        Returns:
2480            The modified expression.
2481        """
2482        return _apply_cte_builder(
2483            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2484        )

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):
2512class WithTableHint(Expression):
2513    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2517class IndexTableHint(Expression):
2518    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2522class HistoricalData(Expression):
2523    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
2526class Table(Expression):
2527    arg_types = {
2528        "this": True,
2529        "alias": False,
2530        "db": False,
2531        "catalog": False,
2532        "laterals": False,
2533        "joins": False,
2534        "pivots": False,
2535        "hints": False,
2536        "system_time": False,
2537        "version": False,
2538        "format": False,
2539        "pattern": False,
2540        "ordinality": False,
2541        "when": False,
2542    }
2543
2544    @property
2545    def name(self) -> str:
2546        if isinstance(self.this, Func):
2547            return ""
2548        return self.this.name
2549
2550    @property
2551    def db(self) -> str:
2552        return self.text("db")
2553
2554    @property
2555    def catalog(self) -> str:
2556        return self.text("catalog")
2557
2558    @property
2559    def selects(self) -> t.List[Expression]:
2560        return []
2561
2562    @property
2563    def named_selects(self) -> t.List[str]:
2564        return []
2565
2566    @property
2567    def parts(self) -> t.List[Expression]:
2568        """Return the parts of a table in order catalog, db, table."""
2569        parts: t.List[Expression] = []
2570
2571        for arg in ("catalog", "db", "this"):
2572            part = self.args.get(arg)
2573
2574            if isinstance(part, Dot):
2575                parts.extend(part.flatten())
2576            elif isinstance(part, Expression):
2577                parts.append(part)
2578
2579        return parts
2580
2581    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2582        parts = self.parts
2583        col = column(*reversed(parts[0:4]), *parts[4:], copy=copy)  # type: ignore
2584        alias = self.args.get("alias")
2585        if alias:
2586            col = alias_(col, alias.this, copy=copy)
2587        return col
arg_types = {'this': True, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'ordinality': False, 'when': False}
name: str
2544    @property
2545    def name(self) -> str:
2546        if isinstance(self.this, Func):
2547            return ""
2548        return self.this.name
db: str
2550    @property
2551    def db(self) -> str:
2552        return self.text("db")
catalog: str
2554    @property
2555    def catalog(self) -> str:
2556        return self.text("catalog")
selects: List[Expression]
2558    @property
2559    def selects(self) -> t.List[Expression]:
2560        return []
named_selects: List[str]
2562    @property
2563    def named_selects(self) -> t.List[str]:
2564        return []
parts: List[Expression]
2566    @property
2567    def parts(self) -> t.List[Expression]:
2568        """Return the parts of a table in order catalog, db, table."""
2569        parts: t.List[Expression] = []
2570
2571        for arg in ("catalog", "db", "this"):
2572            part = self.args.get(arg)
2573
2574            if isinstance(part, Dot):
2575                parts.extend(part.flatten())
2576            elif isinstance(part, Expression):
2577                parts.append(part)
2578
2579        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
2581    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2582        parts = self.parts
2583        col = column(*reversed(parts[0:4]), *parts[4:], copy=copy)  # type: ignore
2584        alias = self.args.get("alias")
2585        if alias:
2586            col = alias_(col, alias.this, copy=copy)
2587        return col
key = 'table'
class Union(Subqueryable):
2590class Union(Subqueryable):
2591    arg_types = {
2592        "with": False,
2593        "this": True,
2594        "expression": True,
2595        "distinct": False,
2596        "by_name": False,
2597        **QUERY_MODIFIERS,
2598    }
2599
2600    def limit(
2601        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2602    ) -> Select:
2603        """
2604        Set the LIMIT expression.
2605
2606        Example:
2607            >>> select("1").union(select("1")).limit(1).sql()
2608            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2609
2610        Args:
2611            expression: the SQL code string to parse.
2612                This can also be an integer.
2613                If a `Limit` instance is passed, this is used as-is.
2614                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2615            dialect: the dialect used to parse the input expression.
2616            copy: if `False`, modify this expression instance in-place.
2617            opts: other options to use to parse the input expressions.
2618
2619        Returns:
2620            The limited subqueryable.
2621        """
2622        return (
2623            select("*")
2624            .from_(self.subquery(alias="_l_0", copy=copy))
2625            .limit(expression, dialect=dialect, copy=False, **opts)
2626        )
2627
2628    def select(
2629        self,
2630        *expressions: t.Optional[ExpOrStr],
2631        append: bool = True,
2632        dialect: DialectType = None,
2633        copy: bool = True,
2634        **opts,
2635    ) -> Union:
2636        """Append to or set the SELECT of the union recursively.
2637
2638        Example:
2639            >>> from sqlglot import parse_one
2640            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2641            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2642
2643        Args:
2644            *expressions: the SQL code strings to parse.
2645                If an `Expression` instance is passed, it will be used as-is.
2646            append: if `True`, add to any existing expressions.
2647                Otherwise, this resets the expressions.
2648            dialect: the dialect used to parse the input expressions.
2649            copy: if `False`, modify this expression instance in-place.
2650            opts: other options to use to parse the input expressions.
2651
2652        Returns:
2653            Union: the modified expression.
2654        """
2655        this = self.copy() if copy else self
2656        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2657        this.expression.unnest().select(
2658            *expressions, append=append, dialect=dialect, copy=False, **opts
2659        )
2660        return this
2661
2662    @property
2663    def named_selects(self) -> t.List[str]:
2664        return self.this.unnest().named_selects
2665
2666    @property
2667    def is_star(self) -> bool:
2668        return self.this.is_star or self.expression.is_star
2669
2670    @property
2671    def selects(self) -> t.List[Expression]:
2672        return self.this.unnest().selects
2673
2674    @property
2675    def left(self) -> Expression:
2676        return self.this
2677
2678    @property
2679    def right(self) -> Expression:
2680        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:
2600    def limit(
2601        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2602    ) -> Select:
2603        """
2604        Set the LIMIT expression.
2605
2606        Example:
2607            >>> select("1").union(select("1")).limit(1).sql()
2608            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2609
2610        Args:
2611            expression: the SQL code string to parse.
2612                This can also be an integer.
2613                If a `Limit` instance is passed, this is used as-is.
2614                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2615            dialect: the dialect used to parse the input expression.
2616            copy: if `False`, modify this expression instance in-place.
2617            opts: other options to use to parse the input expressions.
2618
2619        Returns:
2620            The limited subqueryable.
2621        """
2622        return (
2623            select("*")
2624            .from_(self.subquery(alias="_l_0", copy=copy))
2625            .limit(expression, dialect=dialect, copy=False, **opts)
2626        )

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:
2628    def select(
2629        self,
2630        *expressions: t.Optional[ExpOrStr],
2631        append: bool = True,
2632        dialect: DialectType = None,
2633        copy: bool = True,
2634        **opts,
2635    ) -> Union:
2636        """Append to or set the SELECT of the union recursively.
2637
2638        Example:
2639            >>> from sqlglot import parse_one
2640            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2641            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2642
2643        Args:
2644            *expressions: the SQL code strings to parse.
2645                If an `Expression` instance is passed, it will be used as-is.
2646            append: if `True`, add to any existing expressions.
2647                Otherwise, this resets the expressions.
2648            dialect: the dialect used to parse the input expressions.
2649            copy: if `False`, modify this expression instance in-place.
2650            opts: other options to use to parse the input expressions.
2651
2652        Returns:
2653            Union: the modified expression.
2654        """
2655        this = self.copy() if copy else self
2656        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2657        this.expression.unnest().select(
2658            *expressions, append=append, dialect=dialect, copy=False, **opts
2659        )
2660        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]
2662    @property
2663    def named_selects(self) -> t.List[str]:
2664        return self.this.unnest().named_selects
is_star: bool
2666    @property
2667    def is_star(self) -> bool:
2668        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

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

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:
2788    def group_by(
2789        self,
2790        *expressions: t.Optional[ExpOrStr],
2791        append: bool = True,
2792        dialect: DialectType = None,
2793        copy: bool = True,
2794        **opts,
2795    ) -> Select:
2796        """
2797        Set the GROUP BY expression.
2798
2799        Example:
2800            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2801            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2802
2803        Args:
2804            *expressions: the SQL code strings to parse.
2805                If a `Group` instance is passed, this is used as-is.
2806                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2807                If nothing is passed in then a group by is not applied to the expression
2808            append: if `True`, add to any existing expressions.
2809                Otherwise, this flattens all the `Group` expression into a single expression.
2810            dialect: the dialect used to parse the input expression.
2811            copy: if `False`, modify this expression instance in-place.
2812            opts: other options to use to parse the input expressions.
2813
2814        Returns:
2815            The modified Select expression.
2816        """
2817        if not expressions:
2818            return self if not copy else self.copy()
2819
2820        return _apply_child_list_builder(
2821            *expressions,
2822            instance=self,
2823            arg="group",
2824            append=append,
2825            copy=copy,
2826            prefix="GROUP BY",
2827            into=Group,
2828            dialect=dialect,
2829            **opts,
2830        )

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:
2832    def order_by(
2833        self,
2834        *expressions: t.Optional[ExpOrStr],
2835        append: bool = True,
2836        dialect: DialectType = None,
2837        copy: bool = True,
2838        **opts,
2839    ) -> Select:
2840        """
2841        Set the ORDER BY expression.
2842
2843        Example:
2844            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2845            'SELECT x FROM tbl ORDER BY x DESC'
2846
2847        Args:
2848            *expressions: the SQL code strings to parse.
2849                If a `Group` instance is passed, this is used as-is.
2850                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2851            append: if `True`, add to any existing expressions.
2852                Otherwise, this flattens all the `Order` expression into a single expression.
2853            dialect: the dialect used to parse the input expression.
2854            copy: if `False`, modify this expression instance in-place.
2855            opts: other options to use to parse the input expressions.
2856
2857        Returns:
2858            The modified Select expression.
2859        """
2860        return _apply_child_list_builder(
2861            *expressions,
2862            instance=self,
2863            arg="order",
2864            append=append,
2865            copy=copy,
2866            prefix="ORDER BY",
2867            into=Order,
2868            dialect=dialect,
2869            **opts,
2870        )

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:
2872    def sort_by(
2873        self,
2874        *expressions: t.Optional[ExpOrStr],
2875        append: bool = True,
2876        dialect: DialectType = None,
2877        copy: bool = True,
2878        **opts,
2879    ) -> Select:
2880        """
2881        Set the SORT BY expression.
2882
2883        Example:
2884            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2885            'SELECT x FROM tbl SORT BY x DESC'
2886
2887        Args:
2888            *expressions: the SQL code strings to parse.
2889                If a `Group` instance is passed, this is used as-is.
2890                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2891            append: if `True`, add to any existing expressions.
2892                Otherwise, this flattens all the `Order` expression into a single expression.
2893            dialect: the dialect used to parse the input expression.
2894            copy: if `False`, modify this expression instance in-place.
2895            opts: other options to use to parse the input expressions.
2896
2897        Returns:
2898            The modified Select expression.
2899        """
2900        return _apply_child_list_builder(
2901            *expressions,
2902            instance=self,
2903            arg="sort",
2904            append=append,
2905            copy=copy,
2906            prefix="SORT BY",
2907            into=Sort,
2908            dialect=dialect,
2909            **opts,
2910        )

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:
2912    def cluster_by(
2913        self,
2914        *expressions: t.Optional[ExpOrStr],
2915        append: bool = True,
2916        dialect: DialectType = None,
2917        copy: bool = True,
2918        **opts,
2919    ) -> Select:
2920        """
2921        Set the CLUSTER BY expression.
2922
2923        Example:
2924            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2925            'SELECT x FROM tbl CLUSTER BY x DESC'
2926
2927        Args:
2928            *expressions: the SQL code strings to parse.
2929                If a `Group` instance is passed, this is used as-is.
2930                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2931            append: if `True`, add to any existing expressions.
2932                Otherwise, this flattens all the `Order` expression into a single expression.
2933            dialect: the dialect used to parse the input expression.
2934            copy: if `False`, modify this expression instance in-place.
2935            opts: other options to use to parse the input expressions.
2936
2937        Returns:
2938            The modified Select expression.
2939        """
2940        return _apply_child_list_builder(
2941            *expressions,
2942            instance=self,
2943            arg="cluster",
2944            append=append,
2945            copy=copy,
2946            prefix="CLUSTER BY",
2947            into=Cluster,
2948            dialect=dialect,
2949            **opts,
2950        )

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:
2952    def limit(
2953        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2954    ) -> Select:
2955        """
2956        Set the LIMIT expression.
2957
2958        Example:
2959            >>> Select().from_("tbl").select("x").limit(10).sql()
2960            'SELECT x FROM tbl LIMIT 10'
2961
2962        Args:
2963            expression: the SQL code string to parse.
2964                This can also be an integer.
2965                If a `Limit` instance is passed, this is used as-is.
2966                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2967            dialect: the dialect used to parse the input expression.
2968            copy: if `False`, modify this expression instance in-place.
2969            opts: other options to use to parse the input expressions.
2970
2971        Returns:
2972            Select: the modified expression.
2973        """
2974        return _apply_builder(
2975            expression=expression,
2976            instance=self,
2977            arg="limit",
2978            into=Limit,
2979            prefix="LIMIT",
2980            dialect=dialect,
2981            copy=copy,
2982            into_arg="expression",
2983            **opts,
2984        )

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:
2986    def offset(
2987        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2988    ) -> Select:
2989        """
2990        Set the OFFSET expression.
2991
2992        Example:
2993            >>> Select().from_("tbl").select("x").offset(10).sql()
2994            'SELECT x FROM tbl OFFSET 10'
2995
2996        Args:
2997            expression: the SQL code string to parse.
2998                This can also be an integer.
2999                If a `Offset` instance is passed, this is used as-is.
3000                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3001            dialect: the dialect used to parse the input expression.
3002            copy: if `False`, modify this expression instance in-place.
3003            opts: other options to use to parse the input expressions.
3004
3005        Returns:
3006            The modified Select expression.
3007        """
3008        return _apply_builder(
3009            expression=expression,
3010            instance=self,
3011            arg="offset",
3012            into=Offset,
3013            prefix="OFFSET",
3014            dialect=dialect,
3015            copy=copy,
3016            into_arg="expression",
3017            **opts,
3018        )

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:
3020    def select(
3021        self,
3022        *expressions: t.Optional[ExpOrStr],
3023        append: bool = True,
3024        dialect: DialectType = None,
3025        copy: bool = True,
3026        **opts,
3027    ) -> Select:
3028        """
3029        Append to or set the SELECT expressions.
3030
3031        Example:
3032            >>> Select().select("x", "y").sql()
3033            'SELECT x, y'
3034
3035        Args:
3036            *expressions: the SQL code strings to parse.
3037                If an `Expression` instance is passed, it will be used as-is.
3038            append: if `True`, add to any existing expressions.
3039                Otherwise, this resets the expressions.
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            The modified Select expression.
3046        """
3047        return _apply_list_builder(
3048            *expressions,
3049            instance=self,
3050            arg="expressions",
3051            append=append,
3052            dialect=dialect,
3053            copy=copy,
3054            **opts,
3055        )

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:
3057    def lateral(
3058        self,
3059        *expressions: t.Optional[ExpOrStr],
3060        append: bool = True,
3061        dialect: DialectType = None,
3062        copy: bool = True,
3063        **opts,
3064    ) -> Select:
3065        """
3066        Append to or set the LATERAL expressions.
3067
3068        Example:
3069            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3070            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3071
3072        Args:
3073            *expressions: the SQL code strings to parse.
3074                If an `Expression` instance is passed, it will be used as-is.
3075            append: if `True`, add to any existing expressions.
3076                Otherwise, this resets the expressions.
3077            dialect: the dialect used to parse the input expressions.
3078            copy: if `False`, modify this expression instance in-place.
3079            opts: other options to use to parse the input expressions.
3080
3081        Returns:
3082            The modified Select expression.
3083        """
3084        return _apply_list_builder(
3085            *expressions,
3086            instance=self,
3087            arg="laterals",
3088            append=append,
3089            into=Lateral,
3090            prefix="LATERAL VIEW",
3091            dialect=dialect,
3092            copy=copy,
3093            **opts,
3094        )

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:
3096    def join(
3097        self,
3098        expression: ExpOrStr,
3099        on: t.Optional[ExpOrStr] = None,
3100        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3101        append: bool = True,
3102        join_type: t.Optional[str] = None,
3103        join_alias: t.Optional[Identifier | str] = None,
3104        dialect: DialectType = None,
3105        copy: bool = True,
3106        **opts,
3107    ) -> Select:
3108        """
3109        Append to or set the JOIN expressions.
3110
3111        Example:
3112            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3113            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3114
3115            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3116            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3117
3118            Use `join_type` to change the type of join:
3119
3120            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3121            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3122
3123        Args:
3124            expression: the SQL code string to parse.
3125                If an `Expression` instance is passed, it will be used as-is.
3126            on: optionally specify the join "on" criteria as a SQL string.
3127                If an `Expression` instance is passed, it will be used as-is.
3128            using: optionally specify the join "using" criteria as a SQL string.
3129                If an `Expression` instance is passed, it will be used as-is.
3130            append: if `True`, add to any existing expressions.
3131                Otherwise, this resets the expressions.
3132            join_type: if set, alter the parsed join type.
3133            join_alias: an optional alias for the joined source.
3134            dialect: the dialect used to parse the input expressions.
3135            copy: if `False`, modify this expression instance in-place.
3136            opts: other options to use to parse the input expressions.
3137
3138        Returns:
3139            Select: the modified expression.
3140        """
3141        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3142
3143        try:
3144            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3145        except ParseError:
3146            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3147
3148        join = expression if isinstance(expression, Join) else Join(this=expression)
3149
3150        if isinstance(join.this, Select):
3151            join.this.replace(join.this.subquery())
3152
3153        if join_type:
3154            method: t.Optional[Token]
3155            side: t.Optional[Token]
3156            kind: t.Optional[Token]
3157
3158            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3159
3160            if method:
3161                join.set("method", method.text)
3162            if side:
3163                join.set("side", side.text)
3164            if kind:
3165                join.set("kind", kind.text)
3166
3167        if on:
3168            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3169            join.set("on", on)
3170
3171        if using:
3172            join = _apply_list_builder(
3173                *ensure_list(using),
3174                instance=join,
3175                arg="using",
3176                append=append,
3177                copy=copy,
3178                into=Identifier,
3179                **opts,
3180            )
3181
3182        if join_alias:
3183            join.set("this", alias_(join.this, join_alias, table=True))
3184
3185        return _apply_list_builder(
3186            join,
3187            instance=self,
3188            arg="joins",
3189            append=append,
3190            copy=copy,
3191            **opts,
3192        )

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:
3194    def where(
3195        self,
3196        *expressions: t.Optional[ExpOrStr],
3197        append: bool = True,
3198        dialect: DialectType = None,
3199        copy: bool = True,
3200        **opts,
3201    ) -> Select:
3202        """
3203        Append to or set the WHERE expressions.
3204
3205        Example:
3206            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3207            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3208
3209        Args:
3210            *expressions: the SQL code strings to parse.
3211                If an `Expression` instance is passed, it will be used as-is.
3212                Multiple expressions are combined with an AND operator.
3213            append: if `True`, AND the new expressions to any existing expression.
3214                Otherwise, this resets the expression.
3215            dialect: the dialect used to parse the input expressions.
3216            copy: if `False`, modify this expression instance in-place.
3217            opts: other options to use to parse the input expressions.
3218
3219        Returns:
3220            Select: the modified expression.
3221        """
3222        return _apply_conjunction_builder(
3223            *expressions,
3224            instance=self,
3225            arg="where",
3226            append=append,
3227            into=Where,
3228            dialect=dialect,
3229            copy=copy,
3230            **opts,
3231        )

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:
3233    def having(
3234        self,
3235        *expressions: t.Optional[ExpOrStr],
3236        append: bool = True,
3237        dialect: DialectType = None,
3238        copy: bool = True,
3239        **opts,
3240    ) -> Select:
3241        """
3242        Append to or set the HAVING expressions.
3243
3244        Example:
3245            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3246            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3247
3248        Args:
3249            *expressions: the SQL code strings to parse.
3250                If an `Expression` instance is passed, it will be used as-is.
3251                Multiple expressions are combined with an AND operator.
3252            append: if `True`, AND the new expressions to any existing expression.
3253                Otherwise, this resets the expression.
3254            dialect: the dialect used to parse the input expressions.
3255            copy: if `False`, modify this expression instance in-place.
3256            opts: other options to use to parse the input expressions.
3257
3258        Returns:
3259            The modified Select expression.
3260        """
3261        return _apply_conjunction_builder(
3262            *expressions,
3263            instance=self,
3264            arg="having",
3265            append=append,
3266            into=Having,
3267            dialect=dialect,
3268            copy=copy,
3269            **opts,
3270        )

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:
3272    def window(
3273        self,
3274        *expressions: t.Optional[ExpOrStr],
3275        append: bool = True,
3276        dialect: DialectType = None,
3277        copy: bool = True,
3278        **opts,
3279    ) -> Select:
3280        return _apply_list_builder(
3281            *expressions,
3282            instance=self,
3283            arg="windows",
3284            append=append,
3285            into=Window,
3286            dialect=dialect,
3287            copy=copy,
3288            **opts,
3289        )
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:
3291    def qualify(
3292        self,
3293        *expressions: t.Optional[ExpOrStr],
3294        append: bool = True,
3295        dialect: DialectType = None,
3296        copy: bool = True,
3297        **opts,
3298    ) -> Select:
3299        return _apply_conjunction_builder(
3300            *expressions,
3301            instance=self,
3302            arg="qualify",
3303            append=append,
3304            into=Qualify,
3305            dialect=dialect,
3306            copy=copy,
3307            **opts,
3308        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3310    def distinct(
3311        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3312    ) -> Select:
3313        """
3314        Set the OFFSET expression.
3315
3316        Example:
3317            >>> Select().from_("tbl").select("x").distinct().sql()
3318            'SELECT DISTINCT x FROM tbl'
3319
3320        Args:
3321            ons: the expressions to distinct on
3322            distinct: whether the Select should be distinct
3323            copy: if `False`, modify this expression instance in-place.
3324
3325        Returns:
3326            Select: the modified expression.
3327        """
3328        instance = maybe_copy(self, copy)
3329        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3330        instance.set("distinct", Distinct(on=on) if distinct else None)
3331        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:
3333    def ctas(
3334        self,
3335        table: ExpOrStr,
3336        properties: t.Optional[t.Dict] = None,
3337        dialect: DialectType = None,
3338        copy: bool = True,
3339        **opts,
3340    ) -> Create:
3341        """
3342        Convert this expression to a CREATE TABLE AS statement.
3343
3344        Example:
3345            >>> Select().select("*").from_("tbl").ctas("x").sql()
3346            'CREATE TABLE x AS SELECT * FROM tbl'
3347
3348        Args:
3349            table: the SQL code string to parse as the table name.
3350                If another `Expression` instance is passed, it will be used as-is.
3351            properties: an optional mapping of table properties
3352            dialect: the dialect used to parse the input table.
3353            copy: if `False`, modify this expression instance in-place.
3354            opts: other options to use to parse the input table.
3355
3356        Returns:
3357            The new Create expression.
3358        """
3359        instance = maybe_copy(self, copy)
3360        table_expression = maybe_parse(
3361            table,
3362            into=Table,
3363            dialect=dialect,
3364            **opts,
3365        )
3366        properties_expression = None
3367        if properties:
3368            properties_expression = Properties.from_dict(properties)
3369
3370        return Create(
3371            this=table_expression,
3372            kind="TABLE",
3373            expression=instance,
3374            properties=properties_expression,
3375        )

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:
3377    def lock(self, update: bool = True, copy: bool = True) -> Select:
3378        """
3379        Set the locking read mode for this expression.
3380
3381        Examples:
3382            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3383            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3384
3385            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3386            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3387
3388        Args:
3389            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3390            copy: if `False`, modify this expression instance in-place.
3391
3392        Returns:
3393            The modified expression.
3394        """
3395        inst = maybe_copy(self, copy)
3396        inst.set("locks", [Lock(update=update)])
3397
3398        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:
3400    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3401        """
3402        Set hints for this expression.
3403
3404        Examples:
3405            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3406            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3407
3408        Args:
3409            hints: The SQL code strings to parse as the hints.
3410                If an `Expression` instance is passed, it will be used as-is.
3411            dialect: The dialect used to parse the hints.
3412            copy: If `False`, modify this expression instance in-place.
3413
3414        Returns:
3415            The modified expression.
3416        """
3417        inst = maybe_copy(self, copy)
3418        inst.set(
3419            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3420        )
3421
3422        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]
3424    @property
3425    def named_selects(self) -> t.List[str]:
3426        return [e.output_name for e in self.expressions if e.alias_or_name]
is_star: bool
3428    @property
3429    def is_star(self) -> bool:
3430        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3432    @property
3433    def selects(self) -> t.List[Expression]:
3434        return self.expressions
key = 'select'
class Subquery(DerivedTable, Unionable):
3437class Subquery(DerivedTable, Unionable):
3438    arg_types = {
3439        "this": True,
3440        "alias": False,
3441        "with": False,
3442        **QUERY_MODIFIERS,
3443    }
3444
3445    def unnest(self):
3446        """
3447        Returns the first non subquery.
3448        """
3449        expression = self
3450        while isinstance(expression, Subquery):
3451            expression = expression.this
3452        return expression
3453
3454    def unwrap(self) -> Subquery:
3455        expression = self
3456        while expression.same_parent and expression.is_wrapper:
3457            expression = t.cast(Subquery, expression.parent)
3458        return expression
3459
3460    @property
3461    def is_wrapper(self) -> bool:
3462        """
3463        Whether this Subquery acts as a simple wrapper around another expression.
3464
3465        SELECT * FROM (((SELECT * FROM t)))
3466                      ^
3467                      This corresponds to a "wrapper" Subquery node
3468        """
3469        return all(v is None for k, v in self.args.items() if k != "this")
3470
3471    @property
3472    def is_star(self) -> bool:
3473        return self.this.is_star
3474
3475    @property
3476    def output_name(self) -> str:
3477        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):
3445    def unnest(self):
3446        """
3447        Returns the first non subquery.
3448        """
3449        expression = self
3450        while isinstance(expression, Subquery):
3451            expression = expression.this
3452        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3454    def unwrap(self) -> Subquery:
3455        expression = self
3456        while expression.same_parent and expression.is_wrapper:
3457            expression = t.cast(Subquery, expression.parent)
3458        return expression
is_wrapper: bool
3460    @property
3461    def is_wrapper(self) -> bool:
3462        """
3463        Whether this Subquery acts as a simple wrapper around another expression.
3464
3465        SELECT * FROM (((SELECT * FROM t)))
3466                      ^
3467                      This corresponds to a "wrapper" Subquery node
3468        """
3469        return all(v is None for k, v in self.args.items() if k != "this")

Whether this Subquery acts as a simple wrapper around another expression.

SELECT * FROM (((SELECT * FROM t))) ^ This corresponds to a "wrapper" Subquery node

is_star: bool
3471    @property
3472    def is_star(self) -> bool:
3473        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3475    @property
3476    def output_name(self) -> str:
3477        return self.alias

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'subquery'
class TableSample(Expression):
3480class TableSample(Expression):
3481    arg_types = {
3482        "this": False,
3483        "expressions": False,
3484        "method": False,
3485        "bucket_numerator": False,
3486        "bucket_denominator": False,
3487        "bucket_field": False,
3488        "percent": False,
3489        "rows": False,
3490        "size": False,
3491        "seed": False,
3492    }
arg_types = {'this': False, 'expressions': False, 'method': False, 'bucket_numerator': False, 'bucket_denominator': False, 'bucket_field': False, 'percent': False, 'rows': False, 'size': False, 'seed': False}
key = 'tablesample'
class Tag(Expression):
3495class Tag(Expression):
3496    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3497
3498    arg_types = {
3499        "this": False,
3500        "prefix": False,
3501        "postfix": False,
3502    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3507class Pivot(Expression):
3508    arg_types = {
3509        "this": False,
3510        "alias": False,
3511        "expressions": False,
3512        "field": False,
3513        "unpivot": False,
3514        "using": False,
3515        "group": False,
3516        "columns": False,
3517        "include_nulls": False,
3518    }
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False}
key = 'pivot'
class Window(Condition):
3521class Window(Condition):
3522    arg_types = {
3523        "this": True,
3524        "partition_by": False,
3525        "order": False,
3526        "spec": False,
3527        "alias": False,
3528        "over": False,
3529        "first": False,
3530    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3533class WindowSpec(Expression):
3534    arg_types = {
3535        "kind": False,
3536        "start": False,
3537        "start_side": False,
3538        "end": False,
3539        "end_side": False,
3540    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3543class Where(Expression):
3544    pass
key = 'where'
class Star(Expression):
3547class Star(Expression):
3548    arg_types = {"except": False, "replace": False}
3549
3550    @property
3551    def name(self) -> str:
3552        return "*"
3553
3554    @property
3555    def output_name(self) -> str:
3556        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3550    @property
3551    def name(self) -> str:
3552        return "*"
output_name: str
3554    @property
3555    def output_name(self) -> str:
3556        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'star'
class Parameter(Condition):
3559class Parameter(Condition):
3560    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3563class SessionParameter(Condition):
3564    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3567class Placeholder(Condition):
3568    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3571class Null(Condition):
3572    arg_types: t.Dict[str, t.Any] = {}
3573
3574    @property
3575    def name(self) -> str:
3576        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3574    @property
3575    def name(self) -> str:
3576        return "NULL"
key = 'null'
class Boolean(Condition):
3579class Boolean(Condition):
3580    pass
key = 'boolean'
class DataTypeParam(Expression):
3583class DataTypeParam(Expression):
3584    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3587class DataType(Expression):
3588    arg_types = {
3589        "this": True,
3590        "expressions": False,
3591        "nested": False,
3592        "values": False,
3593        "prefix": False,
3594        "kind": False,
3595    }
3596
3597    class Type(AutoName):
3598        ARRAY = auto()
3599        BIGDECIMAL = auto()
3600        BIGINT = auto()
3601        BIGSERIAL = auto()
3602        BINARY = auto()
3603        BIT = auto()
3604        BOOLEAN = auto()
3605        CHAR = auto()
3606        DATE = auto()
3607        DATEMULTIRANGE = auto()
3608        DATERANGE = auto()
3609        DATETIME = auto()
3610        DATETIME64 = auto()
3611        DECIMAL = auto()
3612        DOUBLE = auto()
3613        ENUM = auto()
3614        ENUM8 = auto()
3615        ENUM16 = auto()
3616        FIXEDSTRING = auto()
3617        FLOAT = auto()
3618        GEOGRAPHY = auto()
3619        GEOMETRY = auto()
3620        HLLSKETCH = auto()
3621        HSTORE = auto()
3622        IMAGE = auto()
3623        INET = auto()
3624        INT = auto()
3625        INT128 = auto()
3626        INT256 = auto()
3627        INT4MULTIRANGE = auto()
3628        INT4RANGE = auto()
3629        INT8MULTIRANGE = auto()
3630        INT8RANGE = auto()
3631        INTERVAL = auto()
3632        IPADDRESS = auto()
3633        IPPREFIX = auto()
3634        JSON = auto()
3635        JSONB = auto()
3636        LONGBLOB = auto()
3637        LONGTEXT = auto()
3638        LOWCARDINALITY = auto()
3639        MAP = auto()
3640        MEDIUMBLOB = auto()
3641        MEDIUMINT = auto()
3642        MEDIUMTEXT = auto()
3643        MONEY = auto()
3644        NCHAR = auto()
3645        NESTED = auto()
3646        NULL = auto()
3647        NULLABLE = auto()
3648        NUMMULTIRANGE = auto()
3649        NUMRANGE = auto()
3650        NVARCHAR = auto()
3651        OBJECT = auto()
3652        ROWVERSION = auto()
3653        SERIAL = auto()
3654        SET = auto()
3655        SMALLINT = auto()
3656        SMALLMONEY = auto()
3657        SMALLSERIAL = auto()
3658        STRUCT = auto()
3659        SUPER = auto()
3660        TEXT = auto()
3661        TINYBLOB = auto()
3662        TINYTEXT = auto()
3663        TIME = auto()
3664        TIMETZ = auto()
3665        TIMESTAMP = auto()
3666        TIMESTAMPLTZ = auto()
3667        TIMESTAMPTZ = auto()
3668        TIMESTAMP_S = auto()
3669        TIMESTAMP_MS = auto()
3670        TIMESTAMP_NS = auto()
3671        TINYINT = auto()
3672        TSMULTIRANGE = auto()
3673        TSRANGE = auto()
3674        TSTZMULTIRANGE = auto()
3675        TSTZRANGE = auto()
3676        UBIGINT = auto()
3677        UINT = auto()
3678        UINT128 = auto()
3679        UINT256 = auto()
3680        UMEDIUMINT = auto()
3681        UDECIMAL = auto()
3682        UNIQUEIDENTIFIER = auto()
3683        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3684        USERDEFINED = "USER-DEFINED"
3685        USMALLINT = auto()
3686        UTINYINT = auto()
3687        UUID = auto()
3688        VARBINARY = auto()
3689        VARCHAR = auto()
3690        VARIANT = auto()
3691        XML = auto()
3692        YEAR = auto()
3693
3694    TEXT_TYPES = {
3695        Type.CHAR,
3696        Type.NCHAR,
3697        Type.VARCHAR,
3698        Type.NVARCHAR,
3699        Type.TEXT,
3700    }
3701
3702    INTEGER_TYPES = {
3703        Type.INT,
3704        Type.TINYINT,
3705        Type.SMALLINT,
3706        Type.BIGINT,
3707        Type.INT128,
3708        Type.INT256,
3709        Type.BIT,
3710    }
3711
3712    FLOAT_TYPES = {
3713        Type.FLOAT,
3714        Type.DOUBLE,
3715    }
3716
3717    NUMERIC_TYPES = {
3718        *INTEGER_TYPES,
3719        *FLOAT_TYPES,
3720    }
3721
3722    TEMPORAL_TYPES = {
3723        Type.TIME,
3724        Type.TIMETZ,
3725        Type.TIMESTAMP,
3726        Type.TIMESTAMPTZ,
3727        Type.TIMESTAMPLTZ,
3728        Type.TIMESTAMP_S,
3729        Type.TIMESTAMP_MS,
3730        Type.TIMESTAMP_NS,
3731        Type.DATE,
3732        Type.DATETIME,
3733        Type.DATETIME64,
3734    }
3735
3736    @classmethod
3737    def build(
3738        cls,
3739        dtype: DATA_TYPE,
3740        dialect: DialectType = None,
3741        udt: bool = False,
3742        **kwargs,
3743    ) -> DataType:
3744        """
3745        Constructs a DataType object.
3746
3747        Args:
3748            dtype: the data type of interest.
3749            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3750            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3751                DataType, thus creating a user-defined type.
3752            kawrgs: additional arguments to pass in the constructor of DataType.
3753
3754        Returns:
3755            The constructed DataType object.
3756        """
3757        from sqlglot import parse_one
3758
3759        if isinstance(dtype, str):
3760            if dtype.upper() == "UNKNOWN":
3761                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3762
3763            try:
3764                data_type_exp = parse_one(
3765                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3766                )
3767            except ParseError:
3768                if udt:
3769                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3770                raise
3771        elif isinstance(dtype, DataType.Type):
3772            data_type_exp = DataType(this=dtype)
3773        elif isinstance(dtype, DataType):
3774            return dtype
3775        else:
3776            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3777
3778        return DataType(**{**data_type_exp.args, **kwargs})
3779
3780    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3781        """
3782        Checks whether this DataType matches one of the provided data types. Nested types or precision
3783        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3784
3785        Args:
3786            dtypes: the data types to compare this DataType to.
3787
3788        Returns:
3789            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3790        """
3791        for dtype in dtypes:
3792            other = DataType.build(dtype, udt=True)
3793
3794            if (
3795                other.expressions
3796                or self.this == DataType.Type.USERDEFINED
3797                or other.this == DataType.Type.USERDEFINED
3798            ):
3799                matches = self == other
3800            else:
3801                matches = self.this == other.this
3802
3803            if matches:
3804                return True
3805        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>}
INTEGER_TYPES = {<Type.BIT: 'BIT'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.BIT: 'BIT'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>}
TEMPORAL_TYPES = {<Type.DATE: 'DATE'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIME: 'TIME'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP: 'TIMESTAMP'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, **kwargs) -> DataType:
3736    @classmethod
3737    def build(
3738        cls,
3739        dtype: DATA_TYPE,
3740        dialect: DialectType = None,
3741        udt: bool = False,
3742        **kwargs,
3743    ) -> DataType:
3744        """
3745        Constructs a DataType object.
3746
3747        Args:
3748            dtype: the data type of interest.
3749            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3750            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3751                DataType, thus creating a user-defined type.
3752            kawrgs: additional arguments to pass in the constructor of DataType.
3753
3754        Returns:
3755            The constructed DataType object.
3756        """
3757        from sqlglot import parse_one
3758
3759        if isinstance(dtype, str):
3760            if dtype.upper() == "UNKNOWN":
3761                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3762
3763            try:
3764                data_type_exp = parse_one(
3765                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3766                )
3767            except ParseError:
3768                if udt:
3769                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3770                raise
3771        elif isinstance(dtype, DataType.Type):
3772            data_type_exp = DataType(this=dtype)
3773        elif isinstance(dtype, DataType):
3774            return dtype
3775        else:
3776            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3777
3778        return DataType(**{**data_type_exp.args, **kwargs})

Constructs a DataType object.

Arguments:
  • dtype: the data type of interest.
  • dialect: the dialect to use for parsing dtype, in case it's a string.
  • udt: when set to True, dtype will be used as-is if it can't be parsed into a DataType, thus creating a user-defined type.
  • kawrgs: additional arguments to pass in the constructor of DataType.
Returns:

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
3780    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3781        """
3782        Checks whether this DataType matches one of the provided data types. Nested types or precision
3783        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3784
3785        Args:
3786            dtypes: the data types to compare this DataType to.
3787
3788        Returns:
3789            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3790        """
3791        for dtype in dtypes:
3792            other = DataType.build(dtype, udt=True)
3793
3794            if (
3795                other.expressions
3796                or self.this == DataType.Type.USERDEFINED
3797                or other.this == DataType.Type.USERDEFINED
3798            ):
3799                matches = self == other
3800            else:
3801                matches = self.this == other.this
3802
3803            if matches:
3804                return True
3805        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):
3597    class Type(AutoName):
3598        ARRAY = auto()
3599        BIGDECIMAL = auto()
3600        BIGINT = auto()
3601        BIGSERIAL = auto()
3602        BINARY = auto()
3603        BIT = auto()
3604        BOOLEAN = auto()
3605        CHAR = auto()
3606        DATE = auto()
3607        DATEMULTIRANGE = auto()
3608        DATERANGE = auto()
3609        DATETIME = auto()
3610        DATETIME64 = auto()
3611        DECIMAL = auto()
3612        DOUBLE = auto()
3613        ENUM = auto()
3614        ENUM8 = auto()
3615        ENUM16 = auto()
3616        FIXEDSTRING = auto()
3617        FLOAT = auto()
3618        GEOGRAPHY = auto()
3619        GEOMETRY = auto()
3620        HLLSKETCH = auto()
3621        HSTORE = auto()
3622        IMAGE = auto()
3623        INET = auto()
3624        INT = auto()
3625        INT128 = auto()
3626        INT256 = auto()
3627        INT4MULTIRANGE = auto()
3628        INT4RANGE = auto()
3629        INT8MULTIRANGE = auto()
3630        INT8RANGE = auto()
3631        INTERVAL = auto()
3632        IPADDRESS = auto()
3633        IPPREFIX = auto()
3634        JSON = auto()
3635        JSONB = auto()
3636        LONGBLOB = auto()
3637        LONGTEXT = auto()
3638        LOWCARDINALITY = auto()
3639        MAP = auto()
3640        MEDIUMBLOB = auto()
3641        MEDIUMINT = auto()
3642        MEDIUMTEXT = auto()
3643        MONEY = auto()
3644        NCHAR = auto()
3645        NESTED = auto()
3646        NULL = auto()
3647        NULLABLE = auto()
3648        NUMMULTIRANGE = auto()
3649        NUMRANGE = auto()
3650        NVARCHAR = auto()
3651        OBJECT = auto()
3652        ROWVERSION = auto()
3653        SERIAL = auto()
3654        SET = auto()
3655        SMALLINT = auto()
3656        SMALLMONEY = auto()
3657        SMALLSERIAL = auto()
3658        STRUCT = auto()
3659        SUPER = auto()
3660        TEXT = auto()
3661        TINYBLOB = auto()
3662        TINYTEXT = auto()
3663        TIME = auto()
3664        TIMETZ = auto()
3665        TIMESTAMP = auto()
3666        TIMESTAMPLTZ = auto()
3667        TIMESTAMPTZ = auto()
3668        TIMESTAMP_S = auto()
3669        TIMESTAMP_MS = auto()
3670        TIMESTAMP_NS = auto()
3671        TINYINT = auto()
3672        TSMULTIRANGE = auto()
3673        TSRANGE = auto()
3674        TSTZMULTIRANGE = auto()
3675        TSTZRANGE = auto()
3676        UBIGINT = auto()
3677        UINT = auto()
3678        UINT128 = auto()
3679        UINT256 = auto()
3680        UMEDIUMINT = auto()
3681        UDECIMAL = auto()
3682        UNIQUEIDENTIFIER = auto()
3683        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3684        USERDEFINED = "USER-DEFINED"
3685        USMALLINT = auto()
3686        UTINYINT = auto()
3687        UUID = auto()
3688        VARBINARY = auto()
3689        VARCHAR = auto()
3690        VARIANT = auto()
3691        XML = auto()
3692        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'>
TIMESTAMP_S = <Type.TIMESTAMP_S: 'TIMESTAMP_S'>
TIMESTAMP_MS = <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>
TIMESTAMP_NS = <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>
TINYINT = <Type.TINYINT: 'TINYINT'>
TSMULTIRANGE = <Type.TSMULTIRANGE: 'TSMULTIRANGE'>
TSRANGE = <Type.TSRANGE: 'TSRANGE'>
TSTZMULTIRANGE = <Type.TSTZMULTIRANGE: 'TSTZMULTIRANGE'>
TSTZRANGE = <Type.TSTZRANGE: 'TSTZRANGE'>
UBIGINT = <Type.UBIGINT: 'UBIGINT'>
UINT = <Type.UINT: 'UINT'>
UINT128 = <Type.UINT128: 'UINT128'>
UINT256 = <Type.UINT256: 'UINT256'>
UMEDIUMINT = <Type.UMEDIUMINT: 'UMEDIUMINT'>
UDECIMAL = <Type.UDECIMAL: 'UDECIMAL'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
Inherited Members
enum.Enum
name
value
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
3812class PseudoType(DataType):
3813    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3817class ObjectIdentifier(DataType):
3818    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3822class SubqueryPredicate(Predicate):
3823    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3826class All(SubqueryPredicate):
3827    pass
key = 'all'
class Any(SubqueryPredicate):
3830class Any(SubqueryPredicate):
3831    pass
key = 'any'
class Exists(SubqueryPredicate):
3834class Exists(SubqueryPredicate):
3835    pass
key = 'exists'
class Command(Expression):
3840class Command(Expression):
3841    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3844class Transaction(Expression):
3845    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3848class Commit(Expression):
3849    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3852class Rollback(Expression):
3853    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3856class AlterTable(Expression):
3857    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):
3860class AddConstraint(Expression):
3861    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3864class DropPartition(Expression):
3865    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3869class Binary(Condition):
3870    arg_types = {"this": True, "expression": True}
3871
3872    @property
3873    def left(self) -> Expression:
3874        return self.this
3875
3876    @property
3877    def right(self) -> Expression:
3878        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
3872    @property
3873    def left(self) -> Expression:
3874        return self.this
right: Expression
3876    @property
3877    def right(self) -> Expression:
3878        return self.expression
key = 'binary'
class Add(Binary):
3881class Add(Binary):
3882    pass
key = 'add'
class Connector(Binary):
3885class Connector(Binary):
3886    pass
key = 'connector'
class And(Connector):
3889class And(Connector):
3890    pass
key = 'and'
class Or(Connector):
3893class Or(Connector):
3894    pass
key = 'or'
class BitwiseAnd(Binary):
3897class BitwiseAnd(Binary):
3898    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3901class BitwiseLeftShift(Binary):
3902    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3905class BitwiseOr(Binary):
3906    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3909class BitwiseRightShift(Binary):
3910    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3913class BitwiseXor(Binary):
3914    pass
key = 'bitwisexor'
class Div(Binary):
3917class Div(Binary):
3918    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
arg_types = {'this': True, 'expression': True, 'typed': False, 'safe': False}
key = 'div'
class Overlaps(Binary):
3921class Overlaps(Binary):
3922    pass
key = 'overlaps'
class Dot(Binary):
3925class Dot(Binary):
3926    @property
3927    def name(self) -> str:
3928        return self.expression.name
3929
3930    @property
3931    def output_name(self) -> str:
3932        return self.name
3933
3934    @classmethod
3935    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3936        """Build a Dot object with a sequence of expressions."""
3937        if len(expressions) < 2:
3938            raise ValueError(f"Dot requires >= 2 expressions.")
3939
3940        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
3941
3942    @property
3943    def parts(self) -> t.List[Expression]:
3944        """Return the parts of a table / column in order catalog, db, table."""
3945        this, *parts = self.flatten()
3946
3947        parts.reverse()
3948
3949        for arg in ("this", "table", "db", "catalog"):
3950            part = this.args.get(arg)
3951
3952            if isinstance(part, Expression):
3953                parts.append(part)
3954
3955        parts.reverse()
3956        return parts
name: str
3926    @property
3927    def name(self) -> str:
3928        return self.expression.name
output_name: str
3930    @property
3931    def output_name(self) -> str:
3932        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
@classmethod
def build( self, expressions: Sequence[Expression]) -> Dot:
3934    @classmethod
3935    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3936        """Build a Dot object with a sequence of expressions."""
3937        if len(expressions) < 2:
3938            raise ValueError(f"Dot requires >= 2 expressions.")
3939
3940        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))

Build a Dot object with a sequence of expressions.

parts: List[Expression]
3942    @property
3943    def parts(self) -> t.List[Expression]:
3944        """Return the parts of a table / column in order catalog, db, table."""
3945        this, *parts = self.flatten()
3946
3947        parts.reverse()
3948
3949        for arg in ("this", "table", "db", "catalog"):
3950            part = this.args.get(arg)
3951
3952            if isinstance(part, Expression):
3953                parts.append(part)
3954
3955        parts.reverse()
3956        return parts

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

key = 'dot'
class DPipe(Binary):
3959class DPipe(Binary):
3960    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
3963class EQ(Binary, Predicate):
3964    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
3967class NullSafeEQ(Binary, Predicate):
3968    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
3971class NullSafeNEQ(Binary, Predicate):
3972    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
3976class PropertyEQ(Binary):
3977    pass
key = 'propertyeq'
class Distance(Binary):
3980class Distance(Binary):
3981    pass
key = 'distance'
class Escape(Binary):
3984class Escape(Binary):
3985    pass
key = 'escape'
class Glob(Binary, Predicate):
3988class Glob(Binary, Predicate):
3989    pass
key = 'glob'
class GT(Binary, Predicate):
3992class GT(Binary, Predicate):
3993    pass
key = 'gt'
class GTE(Binary, Predicate):
3996class GTE(Binary, Predicate):
3997    pass
key = 'gte'
class ILike(Binary, Predicate):
4000class ILike(Binary, Predicate):
4001    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4004class ILikeAny(Binary, Predicate):
4005    pass
key = 'ilikeany'
class IntDiv(Binary):
4008class IntDiv(Binary):
4009    pass
key = 'intdiv'
class Is(Binary, Predicate):
4012class Is(Binary, Predicate):
4013    pass
key = 'is'
class Kwarg(Binary):
4016class Kwarg(Binary):
4017    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4020class Like(Binary, Predicate):
4021    pass
key = 'like'
class LikeAny(Binary, Predicate):
4024class LikeAny(Binary, Predicate):
4025    pass
key = 'likeany'
class LT(Binary, Predicate):
4028class LT(Binary, Predicate):
4029    pass
key = 'lt'
class LTE(Binary, Predicate):
4032class LTE(Binary, Predicate):
4033    pass
key = 'lte'
class Mod(Binary):
4036class Mod(Binary):
4037    pass
key = 'mod'
class Mul(Binary):
4040class Mul(Binary):
4041    pass
key = 'mul'
class NEQ(Binary, Predicate):
4044class NEQ(Binary, Predicate):
4045    pass
key = 'neq'
class Operator(Binary):
4049class Operator(Binary):
4050    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4053class SimilarTo(Binary, Predicate):
4054    pass
key = 'similarto'
class Slice(Binary):
4057class Slice(Binary):
4058    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4061class Sub(Binary):
4062    pass
key = 'sub'
class ArrayOverlaps(Binary):
4065class ArrayOverlaps(Binary):
4066    pass
key = 'arrayoverlaps'
class Unary(Condition):
4071class Unary(Condition):
4072    pass
key = 'unary'
class BitwiseNot(Unary):
4075class BitwiseNot(Unary):
4076    pass
key = 'bitwisenot'
class Not(Unary):
4079class Not(Unary):
4080    pass
key = 'not'
class Paren(Unary):
4083class Paren(Unary):
4084    arg_types = {"this": True, "with": False}
4085
4086    @property
4087    def output_name(self) -> str:
4088        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4086    @property
4087    def output_name(self) -> str:
4088        return self.this.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'paren'
class Neg(Unary):
4091class Neg(Unary):
4092    pass
key = 'neg'
class Alias(Expression):
4095class Alias(Expression):
4096    arg_types = {"this": True, "alias": False}
4097
4098    @property
4099    def output_name(self) -> str:
4100        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4098    @property
4099    def output_name(self) -> str:
4100        return self.alias

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'alias'
class Aliases(Expression):
4103class Aliases(Expression):
4104    arg_types = {"this": True, "expressions": True}
4105
4106    @property
4107    def aliases(self):
4108        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4106    @property
4107    def aliases(self):
4108        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4112class AtIndex(Expression):
4113    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4116class AtTimeZone(Expression):
4117    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
4120class Between(Predicate):
4121    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4124class Bracket(Condition):
4125    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4126    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4127
4128    @property
4129    def output_name(self) -> str:
4130        if len(self.expressions) == 1:
4131            return self.expressions[0].output_name
4132
4133        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4128    @property
4129    def output_name(self) -> str:
4130        if len(self.expressions) == 1:
4131            return self.expressions[0].output_name
4132
4133        return super().output_name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'bracket'
class Distinct(Expression):
4136class Distinct(Expression):
4137    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4140class In(Predicate):
4141    arg_types = {
4142        "this": True,
4143        "expressions": False,
4144        "query": False,
4145        "unnest": False,
4146        "field": False,
4147        "is_global": False,
4148    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4152class ForIn(Expression):
4153    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4156class TimeUnit(Expression):
4157    """Automatically converts unit arg into a var."""
4158
4159    arg_types = {"unit": False}
4160
4161    UNABBREVIATED_UNIT_NAME = {
4162        "D": "DAY",
4163        "H": "HOUR",
4164        "M": "MINUTE",
4165        "MS": "MILLISECOND",
4166        "NS": "NANOSECOND",
4167        "Q": "QUARTER",
4168        "S": "SECOND",
4169        "US": "MICROSECOND",
4170        "W": "WEEK",
4171        "Y": "YEAR",
4172    }
4173
4174    VAR_LIKE = (Column, Literal, Var)
4175
4176    def __init__(self, **args):
4177        unit = args.get("unit")
4178        if isinstance(unit, self.VAR_LIKE):
4179            args["unit"] = Var(
4180                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4181            )
4182        elif isinstance(unit, Week):
4183            unit.set("this", Var(this=unit.this.name.upper()))
4184
4185        super().__init__(**args)
4186
4187    @property
4188    def unit(self) -> t.Optional[Var]:
4189        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4176    def __init__(self, **args):
4177        unit = args.get("unit")
4178        if isinstance(unit, self.VAR_LIKE):
4179            args["unit"] = Var(
4180                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4181            )
4182        elif isinstance(unit, Week):
4183            unit.set("this", Var(this=unit.this.name.upper()))
4184
4185        super().__init__(**args)
arg_types = {'unit': False}
UNABBREVIATED_UNIT_NAME = {'D': 'DAY', 'H': 'HOUR', 'M': 'MINUTE', 'MS': 'MILLISECOND', 'NS': 'NANOSECOND', 'Q': 'QUARTER', 'S': 'SECOND', 'US': 'MICROSECOND', 'W': 'WEEK', 'Y': 'YEAR'}
VAR_LIKE = (<class 'Column'>, <class 'Literal'>, <class 'Var'>)
unit: Optional[Var]
4187    @property
4188    def unit(self) -> t.Optional[Var]:
4189        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4192class IntervalOp(TimeUnit):
4193    arg_types = {"unit": True, "expression": True}
4194
4195    def interval(self):
4196        return Interval(
4197            this=self.expression.copy(),
4198            unit=self.unit.copy(),
4199        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4195    def interval(self):
4196        return Interval(
4197            this=self.expression.copy(),
4198            unit=self.unit.copy(),
4199        )
key = 'intervalop'
class IntervalSpan(DataType):
4205class IntervalSpan(DataType):
4206    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4209class Interval(TimeUnit):
4210    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4213class IgnoreNulls(Expression):
4214    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4217class RespectNulls(Expression):
4218    pass
key = 'respectnulls'
class Func(Condition):
4222class Func(Condition):
4223    """
4224    The base class for all function expressions.
4225
4226    Attributes:
4227        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4228            treated as a variable length argument and the argument's value will be stored as a list.
4229        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4230            for this function expression. These values are used to map this node to a name during parsing
4231            as well as to provide the function's name during SQL string generation. By default the SQL
4232            name is set to the expression's class name transformed to snake case.
4233    """
4234
4235    is_var_len_args = False
4236
4237    @classmethod
4238    def from_arg_list(cls, args):
4239        if cls.is_var_len_args:
4240            all_arg_keys = list(cls.arg_types)
4241            # If this function supports variable length argument treat the last argument as such.
4242            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4243            num_non_var = len(non_var_len_arg_keys)
4244
4245            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4246            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4247        else:
4248            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4249
4250        return cls(**args_dict)
4251
4252    @classmethod
4253    def sql_names(cls):
4254        if cls is Func:
4255            raise NotImplementedError(
4256                "SQL name is only supported by concrete function implementations"
4257            )
4258        if "_sql_names" not in cls.__dict__:
4259            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4260        return cls._sql_names
4261
4262    @classmethod
4263    def sql_name(cls):
4264        return cls.sql_names()[0]
4265
4266    @classmethod
4267    def default_parser_mappings(cls):
4268        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):
4237    @classmethod
4238    def from_arg_list(cls, args):
4239        if cls.is_var_len_args:
4240            all_arg_keys = list(cls.arg_types)
4241            # If this function supports variable length argument treat the last argument as such.
4242            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4243            num_non_var = len(non_var_len_arg_keys)
4244
4245            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4246            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4247        else:
4248            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4249
4250        return cls(**args_dict)
@classmethod
def sql_names(cls):
4252    @classmethod
4253    def sql_names(cls):
4254        if cls is Func:
4255            raise NotImplementedError(
4256                "SQL name is only supported by concrete function implementations"
4257            )
4258        if "_sql_names" not in cls.__dict__:
4259            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4260        return cls._sql_names
@classmethod
def sql_name(cls):
4262    @classmethod
4263    def sql_name(cls):
4264        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4266    @classmethod
4267    def default_parser_mappings(cls):
4268        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4271class AggFunc(Func):
4272    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4275class ParameterizedAgg(AggFunc):
4276    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4279class Abs(Func):
4280    pass
key = 'abs'
class ArgMax(AggFunc):
4283class ArgMax(AggFunc):
4284    arg_types = {"this": True, "expression": True, "count": False}
4285    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4288class ArgMin(AggFunc):
4289    arg_types = {"this": True, "expression": True, "count": False}
4290    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4293class ApproxTopK(AggFunc):
4294    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4297class Flatten(Func):
4298    pass
key = 'flatten'
class Transform(Func):
4302class Transform(Func):
4303    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4306class Anonymous(Func):
4307    arg_types = {"this": True, "expressions": False}
4308    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4311class AnonymousAggFunc(AggFunc):
4312    arg_types = {"this": True, "expressions": False}
4313    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4317class CombinedAggFunc(AnonymousAggFunc):
4318    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4321class CombinedParameterizedAgg(ParameterizedAgg):
4322    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
arg_types = {'this': True, 'expressions': True, 'params': True, 'parts': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
4327class Hll(AggFunc):
4328    arg_types = {"this": True, "expressions": False}
4329    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4332class ApproxDistinct(AggFunc):
4333    arg_types = {"this": True, "accuracy": False}
4334    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4337class Array(Func):
4338    arg_types = {"expressions": False}
4339    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4343class ToArray(Func):
4344    pass
key = 'toarray'
class ToChar(Func):
4349class ToChar(Func):
4350    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4353class GenerateSeries(Func):
4354    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4357class ArrayAgg(AggFunc):
4358    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4361class ArrayUniqueAgg(AggFunc):
4362    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4365class ArrayAll(Func):
4366    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4369class ArrayAny(Func):
4370    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4373class ArrayConcat(Func):
4374    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4375    arg_types = {"this": True, "expressions": False}
4376    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4379class ArrayContains(Binary, Func):
4380    pass
key = 'arraycontains'
class ArrayContained(Binary):
4383class ArrayContained(Binary):
4384    pass
key = 'arraycontained'
class ArrayFilter(Func):
4387class ArrayFilter(Func):
4388    arg_types = {"this": True, "expression": True}
4389    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4392class ArrayJoin(Func):
4393    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4396class ArraySize(Func):
4397    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4400class ArraySort(Func):
4401    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4404class ArraySum(Func):
4405    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4408class ArrayUnionAgg(AggFunc):
4409    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4412class Avg(AggFunc):
4413    pass
key = 'avg'
class AnyValue(AggFunc):
4416class AnyValue(AggFunc):
4417    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):
4420class First(Func):
4421    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4424class Last(Func):
4425    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4428class Case(Func):
4429    arg_types = {"this": False, "ifs": True, "default": False}
4430
4431    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4432        instance = maybe_copy(self, copy)
4433        instance.append(
4434            "ifs",
4435            If(
4436                this=maybe_parse(condition, copy=copy, **opts),
4437                true=maybe_parse(then, copy=copy, **opts),
4438            ),
4439        )
4440        return instance
4441
4442    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4443        instance = maybe_copy(self, copy)
4444        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4445        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:
4431    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4432        instance = maybe_copy(self, copy)
4433        instance.append(
4434            "ifs",
4435            If(
4436                this=maybe_parse(condition, copy=copy, **opts),
4437                true=maybe_parse(then, copy=copy, **opts),
4438            ),
4439        )
4440        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4442    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4443        instance = maybe_copy(self, copy)
4444        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4445        return instance
key = 'case'
class Cast(Func):
4448class Cast(Func):
4449    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4450
4451    @property
4452    def name(self) -> str:
4453        return self.this.name
4454
4455    @property
4456    def to(self) -> DataType:
4457        return self.args["to"]
4458
4459    @property
4460    def output_name(self) -> str:
4461        return self.name
4462
4463    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4464        """
4465        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4466        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4467        array<int> != array<float>.
4468
4469        Args:
4470            dtypes: the data types to compare this Cast's DataType to.
4471
4472        Returns:
4473            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4474        """
4475        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4451    @property
4452    def name(self) -> str:
4453        return self.this.name
to: DataType
4455    @property
4456    def to(self) -> DataType:
4457        return self.args["to"]
output_name: str
4459    @property
4460    def output_name(self) -> str:
4461        return self.name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
4463    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4464        """
4465        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4466        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4467        array<int> != array<float>.
4468
4469        Args:
4470            dtypes: the data types to compare this Cast's DataType to.
4471
4472        Returns:
4473            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4474        """
4475        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):
4478class TryCast(Cast):
4479    pass
key = 'trycast'
class CastToStrType(Func):
4482class CastToStrType(Func):
4483    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4486class Collate(Binary, Func):
4487    pass
key = 'collate'
class Ceil(Func):
4490class Ceil(Func):
4491    arg_types = {"this": True, "decimals": False}
4492    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4495class Coalesce(Func):
4496    arg_types = {"this": True, "expressions": False}
4497    is_var_len_args = True
4498    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4501class Chr(Func):
4502    arg_types = {"this": True, "charset": False, "expressions": False}
4503    is_var_len_args = True
4504    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4507class Concat(Func):
4508    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4509    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4512class ConcatWs(Concat):
4513    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4516class Count(AggFunc):
4517    arg_types = {"this": False, "expressions": False}
4518    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4521class CountIf(AggFunc):
4522    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class CurrentDate(Func):
4525class CurrentDate(Func):
4526    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4529class CurrentDatetime(Func):
4530    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4533class CurrentTime(Func):
4534    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4537class CurrentTimestamp(Func):
4538    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4541class CurrentUser(Func):
4542    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4545class DateAdd(Func, IntervalOp):
4546    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4549class DateSub(Func, IntervalOp):
4550    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4553class DateDiff(Func, TimeUnit):
4554    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4555    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4558class DateTrunc(Func):
4559    arg_types = {"unit": True, "this": True, "zone": False}
4560
4561    def __init__(self, **args):
4562        unit = args.get("unit")
4563        if isinstance(unit, TimeUnit.VAR_LIKE):
4564            args["unit"] = Literal.string(
4565                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4566            )
4567        elif isinstance(unit, Week):
4568            unit.set("this", Literal.string(unit.this.name.upper()))
4569
4570        super().__init__(**args)
4571
4572    @property
4573    def unit(self) -> Expression:
4574        return self.args["unit"]
DateTrunc(**args)
4561    def __init__(self, **args):
4562        unit = args.get("unit")
4563        if isinstance(unit, TimeUnit.VAR_LIKE):
4564            args["unit"] = Literal.string(
4565                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4566            )
4567        elif isinstance(unit, Week):
4568            unit.set("this", Literal.string(unit.this.name.upper()))
4569
4570        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4572    @property
4573    def unit(self) -> Expression:
4574        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4577class DatetimeAdd(Func, IntervalOp):
4578    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4581class DatetimeSub(Func, IntervalOp):
4582    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4585class DatetimeDiff(Func, TimeUnit):
4586    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4589class DatetimeTrunc(Func, TimeUnit):
4590    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4593class DayOfWeek(Func):
4594    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4597class DayOfMonth(Func):
4598    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4601class DayOfYear(Func):
4602    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4605class ToDays(Func):
4606    pass
key = 'todays'
class WeekOfYear(Func):
4609class WeekOfYear(Func):
4610    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4613class MonthsBetween(Func):
4614    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4617class LastDay(Func, TimeUnit):
4618    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4619    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4622class Extract(Func):
4623    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4626class Timestamp(Func):
4627    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4630class TimestampAdd(Func, TimeUnit):
4631    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4634class TimestampSub(Func, TimeUnit):
4635    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4638class TimestampDiff(Func, TimeUnit):
4639    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4642class TimestampTrunc(Func, TimeUnit):
4643    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4646class TimeAdd(Func, TimeUnit):
4647    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4650class TimeSub(Func, TimeUnit):
4651    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4654class TimeDiff(Func, TimeUnit):
4655    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4658class TimeTrunc(Func, TimeUnit):
4659    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4662class DateFromParts(Func):
4663    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4664    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4667class TimeFromParts(Func):
4668    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4669    arg_types = {
4670        "hour": True,
4671        "min": True,
4672        "sec": True,
4673        "nano": False,
4674        "fractions": False,
4675        "precision": False,
4676    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4679class DateStrToDate(Func):
4680    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4683class DateToDateStr(Func):
4684    pass
key = 'datetodatestr'
class DateToDi(Func):
4687class DateToDi(Func):
4688    pass
key = 'datetodi'
class Date(Func):
4692class Date(Func):
4693    arg_types = {"this": False, "zone": False, "expressions": False}
4694    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4697class Day(Func):
4698    pass
key = 'day'
class Decode(Func):
4701class Decode(Func):
4702    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4705class DiToDate(Func):
4706    pass
key = 'ditodate'
class Encode(Func):
4709class Encode(Func):
4710    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4713class Exp(Func):
4714    pass
key = 'exp'
class Explode(Func):
4718class Explode(Func):
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 = 'explode'
class ExplodeOuter(Explode):
4723class ExplodeOuter(Explode):
4724    pass
key = 'explodeouter'
class Posexplode(Explode):
4727class Posexplode(Explode):
4728    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4731class PosexplodeOuter(Posexplode):
4732    pass
key = 'posexplodeouter'
class Floor(Func):
4735class Floor(Func):
4736    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4739class FromBase64(Func):
4740    pass
key = 'frombase64'
class ToBase64(Func):
4743class ToBase64(Func):
4744    pass
key = 'tobase64'
class Greatest(Func):
4747class Greatest(Func):
4748    arg_types = {"this": True, "expressions": False}
4749    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4752class GroupConcat(AggFunc):
4753    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4756class Hex(Func):
4757    pass
key = 'hex'
class Xor(Connector, Func):
4760class Xor(Connector, Func):
4761    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4764class If(Func):
4765    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4768class Nullif(Func):
4769    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4772class Initcap(Func):
4773    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4776class IsNan(Func):
4777    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4780class IsInf(Func):
4781    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class FormatJson(Expression):
4784class FormatJson(Expression):
4785    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4788class JSONKeyValue(Expression):
4789    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4792class JSONObject(Func):
4793    arg_types = {
4794        "expressions": False,
4795        "null_handling": False,
4796        "unique_keys": False,
4797        "return_type": False,
4798        "encoding": False,
4799    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4803class JSONArray(Func):
4804    arg_types = {
4805        "expressions": True,
4806        "null_handling": False,
4807        "return_type": False,
4808        "strict": False,
4809    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4813class JSONArrayAgg(Func):
4814    arg_types = {
4815        "this": True,
4816        "order": False,
4817        "null_handling": False,
4818        "return_type": False,
4819        "strict": False,
4820    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4825class JSONColumnDef(Expression):
4826    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
arg_types = {'this': False, 'kind': False, 'path': False, 'nested_schema': False}
key = 'jsoncolumndef'
class JSONSchema(Expression):
4829class JSONSchema(Expression):
4830    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4834class JSONTable(Func):
4835    arg_types = {
4836        "this": True,
4837        "schema": True,
4838        "path": False,
4839        "error_handling": False,
4840        "empty_handling": False,
4841    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4844class OpenJSONColumnDef(Expression):
4845    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):
4848class OpenJSON(Func):
4849    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4852class JSONBContains(Binary):
4853    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4856class JSONExtract(Binary, Func):
4857    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4860class JSONExtractScalar(JSONExtract):
4861    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4864class JSONBExtract(JSONExtract):
4865    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4868class JSONBExtractScalar(JSONExtract):
4869    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4872class JSONFormat(Func):
4873    arg_types = {"this": False, "options": False}
4874    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4878class JSONArrayContains(Binary, Predicate, Func):
4879    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4882class ParseJSON(Func):
4883    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4884    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4885    arg_types = {"this": True, "expressions": False}
4886    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class GetPath(Func):
4890class GetPath(Func):
4891    arg_types = {"this": True, "expression": True}
4892
4893    @property
4894    def output_name(self) -> str:
4895        return self.expression.output_name
arg_types = {'this': True, 'expression': True}
output_name: str
4893    @property
4894    def output_name(self) -> str:
4895        return self.expression.output_name

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'getpath'
class Least(Func):
4898class Least(Func):
4899    arg_types = {"this": True, "expressions": False}
4900    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4903class Left(Func):
4904    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4911class Length(Func):
4912    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4915class Levenshtein(Func):
4916    arg_types = {
4917        "this": True,
4918        "expression": False,
4919        "ins_cost": False,
4920        "del_cost": False,
4921        "sub_cost": False,
4922    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4925class Ln(Func):
4926    pass
key = 'ln'
class Log(Func):
4929class Log(Func):
4930    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4933class Log2(Func):
4934    pass
key = 'log2'
class Log10(Func):
4937class Log10(Func):
4938    pass
key = 'log10'
class LogicalOr(AggFunc):
4941class LogicalOr(AggFunc):
4942    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4945class LogicalAnd(AggFunc):
4946    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4949class Lower(Func):
4950    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4953class Map(Func):
4954    arg_types = {"keys": False, "values": False}
4955
4956    @property
4957    def keys(self) -> t.List[Expression]:
4958        keys = self.args.get("keys")
4959        return keys.expressions if keys else []
4960
4961    @property
4962    def values(self) -> t.List[Expression]:
4963        values = self.args.get("values")
4964        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
4956    @property
4957    def keys(self) -> t.List[Expression]:
4958        keys = self.args.get("keys")
4959        return keys.expressions if keys else []
values: List[Expression]
4961    @property
4962    def values(self) -> t.List[Expression]:
4963        values = self.args.get("values")
4964        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
4967class MapFromEntries(Func):
4968    pass
key = 'mapfromentries'
class StarMap(Func):
4971class StarMap(Func):
4972    pass
key = 'starmap'
class VarMap(Func):
4975class VarMap(Func):
4976    arg_types = {"keys": True, "values": True}
4977    is_var_len_args = True
4978
4979    @property
4980    def keys(self) -> t.List[Expression]:
4981        return self.args["keys"].expressions
4982
4983    @property
4984    def values(self) -> t.List[Expression]:
4985        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
4979    @property
4980    def keys(self) -> t.List[Expression]:
4981        return self.args["keys"].expressions
values: List[Expression]
4983    @property
4984    def values(self) -> t.List[Expression]:
4985        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
4989class MatchAgainst(Func):
4990    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4993class Max(AggFunc):
4994    arg_types = {"this": True, "expressions": False}
4995    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
4998class MD5(Func):
4999    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5003class MD5Digest(Func):
5004    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5007class Min(AggFunc):
5008    arg_types = {"this": True, "expressions": False}
5009    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5012class Month(Func):
5013    pass
key = 'month'
class Nvl2(Func):
5016class Nvl2(Func):
5017    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5021class Predict(Func):
5022    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5025class Pow(Binary, Func):
5026    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5029class PercentileCont(AggFunc):
5030    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5033class PercentileDisc(AggFunc):
5034    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5037class Quantile(AggFunc):
5038    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5041class ApproxQuantile(Quantile):
5042    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Rand(Func):
5045class Rand(Func):
5046    _sql_names = ["RAND", "RANDOM"]
5047    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5050class Randn(Func):
5051    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5054class RangeN(Func):
5055    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5058class ReadCSV(Func):
5059    _sql_names = ["READ_CSV"]
5060    is_var_len_args = True
5061    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5064class Reduce(Func):
5065    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):
5068class RegexpExtract(Func):
5069    arg_types = {
5070        "this": True,
5071        "expression": True,
5072        "position": False,
5073        "occurrence": False,
5074        "parameters": False,
5075        "group": False,
5076    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5079class RegexpReplace(Func):
5080    arg_types = {
5081        "this": True,
5082        "expression": True,
5083        "replacement": True,
5084        "position": False,
5085        "occurrence": False,
5086        "parameters": False,
5087        "modifiers": False,
5088    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5091class RegexpLike(Binary, Func):
5092    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5095class RegexpILike(Binary, Func):
5096    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5101class RegexpSplit(Func):
5102    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5105class Repeat(Func):
5106    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5109class Round(Func):
5110    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
5113class RowNumber(Func):
5114    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5117class SafeDivide(Func):
5118    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5121class SHA(Func):
5122    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5125class SHA2(Func):
5126    _sql_names = ["SHA2"]
5127    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5130class SortArray(Func):
5131    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5134class Split(Func):
5135    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5140class Substring(Func):
5141    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5144class StandardHash(Func):
5145    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5148class StartsWith(Func):
5149    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5150    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5153class StrPosition(Func):
5154    arg_types = {
5155        "this": True,
5156        "substr": True,
5157        "position": False,
5158        "instance": False,
5159    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5162class StrToDate(Func):
5163    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5166class StrToTime(Func):
5167    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5172class StrToUnix(Func):
5173    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5178class StrToMap(Func):
5179    arg_types = {
5180        "this": True,
5181        "pair_delim": False,
5182        "key_value_delim": False,
5183        "duplicate_resolution_callback": False,
5184    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5187class NumberToStr(Func):
5188    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5191class FromBase(Func):
5192    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5195class Struct(Func):
5196    arg_types = {"expressions": False}
5197    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5200class StructExtract(Func):
5201    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5206class Stuff(Func):
5207    _sql_names = ["STUFF", "INSERT"]
5208    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):
5211class Sum(AggFunc):
5212    pass
key = 'sum'
class Sqrt(Func):
5215class Sqrt(Func):
5216    pass
key = 'sqrt'
class Stddev(AggFunc):
5219class Stddev(AggFunc):
5220    pass
key = 'stddev'
class StddevPop(AggFunc):
5223class StddevPop(AggFunc):
5224    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5227class StddevSamp(AggFunc):
5228    pass
key = 'stddevsamp'
class TimeToStr(Func):
5231class TimeToStr(Func):
5232    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5235class TimeToTimeStr(Func):
5236    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5239class TimeToUnix(Func):
5240    pass
key = 'timetounix'
class TimeStrToDate(Func):
5243class TimeStrToDate(Func):
5244    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5247class TimeStrToTime(Func):
5248    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5251class TimeStrToUnix(Func):
5252    pass
key = 'timestrtounix'
class Trim(Func):
5255class Trim(Func):
5256    arg_types = {
5257        "this": True,
5258        "expression": False,
5259        "position": False,
5260        "collation": False,
5261    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5264class TsOrDsAdd(Func, TimeUnit):
5265    # return_type is used to correctly cast the arguments of this expression when transpiling it
5266    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5267
5268    @property
5269    def return_type(self) -> DataType:
5270        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
arg_types = {'this': True, 'expression': True, 'unit': False, 'return_type': False}
return_type: DataType
5268    @property
5269    def return_type(self) -> DataType:
5270        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5273class TsOrDsDiff(Func, TimeUnit):
5274    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5277class TsOrDsToDateStr(Func):
5278    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5281class TsOrDsToDate(Func):
5282    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5285class TsOrDsToTime(Func):
5286    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5289class TsOrDiToDi(Func):
5290    pass
key = 'tsorditodi'
class Unhex(Func):
5293class Unhex(Func):
5294    pass
key = 'unhex'
class UnixDate(Func):
5298class UnixDate(Func):
5299    pass
key = 'unixdate'
class UnixToStr(Func):
5302class UnixToStr(Func):
5303    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5308class UnixToTime(Func):
5309    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5310
5311    SECONDS = Literal.string("seconds")
5312    MILLIS = Literal.string("millis")
5313    MICROS = Literal.string("micros")
5314    NANOS = Literal.string("nanos")
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)
NANOS = Literal(this=nanos, is_string=True)
key = 'unixtotime'
class UnixToTimeStr(Func):
5317class UnixToTimeStr(Func):
5318    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5321class TimestampFromParts(Func):
5322    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5323    arg_types = {
5324        "year": True,
5325        "month": True,
5326        "day": True,
5327        "hour": True,
5328        "min": True,
5329        "sec": True,
5330        "nano": False,
5331        "zone": False,
5332        "milli": False,
5333    }
arg_types = {'year': True, 'month': True, 'day': True, 'hour': True, 'min': True, 'sec': True, 'nano': False, 'zone': False, 'milli': False}
key = 'timestampfromparts'
class Upper(Func):
5336class Upper(Func):
5337    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5340class Variance(AggFunc):
5341    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5344class VariancePop(AggFunc):
5345    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5348class Week(Func):
5349    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5352class XMLTable(Func):
5353    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):
5356class Year(Func):
5357    pass
key = 'year'
class Use(Expression):
5360class Use(Expression):
5361    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5364class Merge(Expression):
5365    arg_types = {"this": True, "using": True, "on": True, "expressions": True, "with": False}
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
5368class When(Func):
5369    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):
5374class NextValueFor(Func):
5375    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayContains'>, <class 'ArrayFilter'>, <class 'ArrayJoin'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'Count'>, <class 'CountIf'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GenerateSeries'>, <class 'GetPath'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONTable'>, <class 'Last'>, <class 'LastDay'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'Log10'>, <class 'Log2'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'OpenJSON'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'Transform'>, <class 'Trim'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_JOIN': <class 'ArrayJoin'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GET_PATH': <class 'GetPath'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOG10': <class 'Log10'>, 'LOG2': <class 'Log2'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'WHEN': <class 'When'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
5413def maybe_parse(
5414    sql_or_expression: ExpOrStr,
5415    *,
5416    into: t.Optional[IntoType] = None,
5417    dialect: DialectType = None,
5418    prefix: t.Optional[str] = None,
5419    copy: bool = False,
5420    **opts,
5421) -> Expression:
5422    """Gracefully handle a possible string or expression.
5423
5424    Example:
5425        >>> maybe_parse("1")
5426        Literal(this=1, is_string=False)
5427        >>> maybe_parse(to_identifier("x"))
5428        Identifier(this=x, quoted=False)
5429
5430    Args:
5431        sql_or_expression: the SQL code string or an expression
5432        into: the SQLGlot Expression to parse into
5433        dialect: the dialect used to parse the input expressions (in the case that an
5434            input expression is a SQL string).
5435        prefix: a string to prefix the sql with before it gets parsed
5436            (automatically includes a space)
5437        copy: whether or not to copy the expression.
5438        **opts: other options to use to parse the input expressions (again, in the case
5439            that an input expression is a SQL string).
5440
5441    Returns:
5442        Expression: the parsed or given expression.
5443    """
5444    if isinstance(sql_or_expression, Expression):
5445        if copy:
5446            return sql_or_expression.copy()
5447        return sql_or_expression
5448
5449    if sql_or_expression is None:
5450        raise ParseError(f"SQL cannot be None")
5451
5452    import sqlglot
5453
5454    sql = str(sql_or_expression)
5455    if prefix:
5456        sql = f"{prefix} {sql}"
5457
5458    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):
5471def maybe_copy(instance, copy=True):
5472    return instance.copy() if copy and instance else instance
def union( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
5686def union(
5687    left: ExpOrStr,
5688    right: ExpOrStr,
5689    distinct: bool = True,
5690    dialect: DialectType = None,
5691    copy: bool = True,
5692    **opts,
5693) -> Union:
5694    """
5695    Initializes a syntax tree from one UNION expression.
5696
5697    Example:
5698        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5699        'SELECT * FROM foo UNION SELECT * FROM bla'
5700
5701    Args:
5702        left: the SQL code string corresponding to the left-hand side.
5703            If an `Expression` instance is passed, it will be used as-is.
5704        right: the SQL code string corresponding to the right-hand side.
5705            If an `Expression` instance is passed, it will be used as-is.
5706        distinct: set the DISTINCT flag if and only if this is true.
5707        dialect: the dialect used to parse the input expression.
5708        copy: whether or not to copy the expression.
5709        opts: other options to use to parse the input expressions.
5710
5711    Returns:
5712        The new Union instance.
5713    """
5714    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5715    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5716
5717    return Union(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one UNION expression.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union instance.

def intersect( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
5720def intersect(
5721    left: ExpOrStr,
5722    right: ExpOrStr,
5723    distinct: bool = True,
5724    dialect: DialectType = None,
5725    copy: bool = True,
5726    **opts,
5727) -> Intersect:
5728    """
5729    Initializes a syntax tree from one INTERSECT expression.
5730
5731    Example:
5732        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5733        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5734
5735    Args:
5736        left: the SQL code string corresponding to the left-hand side.
5737            If an `Expression` instance is passed, it will be used as-is.
5738        right: the SQL code string corresponding to the right-hand side.
5739            If an `Expression` instance is passed, it will be used as-is.
5740        distinct: set the DISTINCT flag if and only if this is true.
5741        dialect: the dialect used to parse the input expression.
5742        copy: whether or not to copy the expression.
5743        opts: other options to use to parse the input expressions.
5744
5745    Returns:
5746        The new Intersect instance.
5747    """
5748    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5749    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5750
5751    return Intersect(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one INTERSECT expression.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect instance.

def except_( left: Union[str, Expression], right: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
5754def except_(
5755    left: ExpOrStr,
5756    right: ExpOrStr,
5757    distinct: bool = True,
5758    dialect: DialectType = None,
5759    copy: bool = True,
5760    **opts,
5761) -> Except:
5762    """
5763    Initializes a syntax tree from one EXCEPT expression.
5764
5765    Example:
5766        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5767        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5768
5769    Args:
5770        left: the SQL code string corresponding to the left-hand side.
5771            If an `Expression` instance is passed, it will be used as-is.
5772        right: the SQL code string corresponding to the right-hand side.
5773            If an `Expression` instance is passed, it will be used as-is.
5774        distinct: set the DISTINCT flag if and only if this is true.
5775        dialect: the dialect used to parse the input expression.
5776        copy: whether or not to copy the expression.
5777        opts: other options to use to parse the input expressions.
5778
5779    Returns:
5780        The new Except instance.
5781    """
5782    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5783    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5784
5785    return Except(this=left, expression=right, distinct=distinct)

Initializes a syntax tree from one EXCEPT expression.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • left: the SQL code string corresponding to the left-hand side. If an Expression instance is passed, it will be used as-is.
  • right: the SQL code string corresponding to the right-hand side. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether or not to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except instance.

def select( *expressions: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
5788def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5789    """
5790    Initializes a syntax tree from one or multiple SELECT expressions.
5791
5792    Example:
5793        >>> select("col1", "col2").from_("tbl").sql()
5794        'SELECT col1, col2 FROM tbl'
5795
5796    Args:
5797        *expressions: the SQL code string to parse as the expressions of a
5798            SELECT statement. If an Expression instance is passed, this is used as-is.
5799        dialect: the dialect used to parse the input expressions (in the case that an
5800            input expression is a SQL string).
5801        **opts: other options to use to parse the input expressions (again, in the case
5802            that an input expression is a SQL string).
5803
5804    Returns:
5805        Select: the syntax tree for the SELECT statement.
5806    """
5807    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:
5810def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5811    """
5812    Initializes a syntax tree from a FROM expression.
5813
5814    Example:
5815        >>> from_("tbl").select("col1", "col2").sql()
5816        'SELECT col1, col2 FROM tbl'
5817
5818    Args:
5819        *expression: the SQL code string to parse as the FROM expressions of a
5820            SELECT statement. If an Expression instance is passed, this is used as-is.
5821        dialect: the dialect used to parse the input expression (in the case that the
5822            input expression is a SQL string).
5823        **opts: other options to use to parse the input expressions (again, in the case
5824            that the input expression is a SQL string).
5825
5826    Returns:
5827        Select: the syntax tree for the SELECT statement.
5828    """
5829    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:
5832def update(
5833    table: str | Table,
5834    properties: dict,
5835    where: t.Optional[ExpOrStr] = None,
5836    from_: t.Optional[ExpOrStr] = None,
5837    dialect: DialectType = None,
5838    **opts,
5839) -> Update:
5840    """
5841    Creates an update statement.
5842
5843    Example:
5844        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5845        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5846
5847    Args:
5848        *properties: dictionary of properties to set which are
5849            auto converted to sql objects eg None -> NULL
5850        where: sql conditional parsed into a WHERE statement
5851        from_: sql statement parsed into a FROM statement
5852        dialect: the dialect used to parse the input expressions.
5853        **opts: other options to use to parse the input expressions.
5854
5855    Returns:
5856        Update: the syntax tree for the UPDATE statement.
5857    """
5858    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5859    update_expr.set(
5860        "expressions",
5861        [
5862            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5863            for k, v in properties.items()
5864        ],
5865    )
5866    if from_:
5867        update_expr.set(
5868            "from",
5869            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5870        )
5871    if isinstance(where, Condition):
5872        where = Where(this=where)
5873    if where:
5874        update_expr.set(
5875            "where",
5876            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5877        )
5878    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:
5881def delete(
5882    table: ExpOrStr,
5883    where: t.Optional[ExpOrStr] = None,
5884    returning: t.Optional[ExpOrStr] = None,
5885    dialect: DialectType = None,
5886    **opts,
5887) -> Delete:
5888    """
5889    Builds a delete statement.
5890
5891    Example:
5892        >>> delete("my_table", where="id > 1").sql()
5893        'DELETE FROM my_table WHERE id > 1'
5894
5895    Args:
5896        where: sql conditional parsed into a WHERE statement
5897        returning: sql conditional parsed into a RETURNING statement
5898        dialect: the dialect used to parse the input expressions.
5899        **opts: other options to use to parse the input expressions.
5900
5901    Returns:
5902        Delete: the syntax tree for the DELETE statement.
5903    """
5904    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5905    if where:
5906        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5907    if returning:
5908        delete_expr = t.cast(
5909            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5910        )
5911    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, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
5914def insert(
5915    expression: ExpOrStr,
5916    into: ExpOrStr,
5917    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5918    overwrite: t.Optional[bool] = None,
5919    returning: t.Optional[ExpOrStr] = None,
5920    dialect: DialectType = None,
5921    copy: bool = True,
5922    **opts,
5923) -> Insert:
5924    """
5925    Builds an INSERT statement.
5926
5927    Example:
5928        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5929        'INSERT INTO tbl VALUES (1, 2, 3)'
5930
5931    Args:
5932        expression: the sql string or expression of the INSERT statement
5933        into: the tbl to insert data to.
5934        columns: optionally the table's column names.
5935        overwrite: whether to INSERT OVERWRITE or not.
5936        returning: sql conditional parsed into a RETURNING statement
5937        dialect: the dialect used to parse the input expressions.
5938        copy: whether or not to copy the expression.
5939        **opts: other options to use to parse the input expressions.
5940
5941    Returns:
5942        Insert: the syntax tree for the INSERT statement.
5943    """
5944    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5945    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5946
5947    if columns:
5948        this = _apply_list_builder(
5949            *columns,
5950            instance=Schema(this=this),
5951            arg="expressions",
5952            into=Identifier,
5953            copy=False,
5954            dialect=dialect,
5955            **opts,
5956        )
5957
5958    insert = Insert(this=this, expression=expr, overwrite=overwrite)
5959
5960    if returning:
5961        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
5962
5963    return insert

Builds an INSERT statement.

Example:
>>> insert("VALUES (1, 2, 3)", "tbl").sql()
'INSERT INTO tbl VALUES (1, 2, 3)'
Arguments:
  • expression: the sql string or expression of the INSERT statement
  • into: the tbl to insert data to.
  • columns: optionally the table's column names.
  • overwrite: whether to INSERT OVERWRITE or not.
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • copy: whether or not to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Insert: the syntax tree for the INSERT statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
5966def condition(
5967    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5968) -> Condition:
5969    """
5970    Initialize a logical condition expression.
5971
5972    Example:
5973        >>> condition("x=1").sql()
5974        'x = 1'
5975
5976        This is helpful for composing larger logical syntax trees:
5977        >>> where = condition("x=1")
5978        >>> where = where.and_("y=1")
5979        >>> Select().from_("tbl").select("*").where(where).sql()
5980        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5981
5982    Args:
5983        *expression: the SQL code string to parse.
5984            If an Expression instance is passed, this is used as-is.
5985        dialect: the dialect used to parse the input expression (in the case that the
5986            input expression is a SQL string).
5987        copy: Whether or not to copy `expression` (only applies to expressions).
5988        **opts: other options to use to parse the input expressions (again, in the case
5989            that the input expression is a SQL string).
5990
5991    Returns:
5992        The new Condition instance
5993    """
5994    return maybe_parse(
5995        expression,
5996        into=Condition,
5997        dialect=dialect,
5998        copy=copy,
5999        **opts,
6000    )

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:
6003def and_(
6004    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6005) -> Condition:
6006    """
6007    Combine multiple conditions with an AND logical operator.
6008
6009    Example:
6010        >>> and_("x=1", and_("y=1", "z=1")).sql()
6011        'x = 1 AND (y = 1 AND z = 1)'
6012
6013    Args:
6014        *expressions: the SQL code strings to parse.
6015            If an Expression instance is passed, this is used as-is.
6016        dialect: the dialect used to parse the input expression.
6017        copy: whether or not to copy `expressions` (only applies to Expressions).
6018        **opts: other options to use to parse the input expressions.
6019
6020    Returns:
6021        And: the new condition
6022    """
6023    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:
6026def or_(
6027    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6028) -> Condition:
6029    """
6030    Combine multiple conditions with an OR logical operator.
6031
6032    Example:
6033        >>> or_("x=1", or_("y=1", "z=1")).sql()
6034        'x = 1 OR (y = 1 OR z = 1)'
6035
6036    Args:
6037        *expressions: the SQL code strings to parse.
6038            If an Expression instance is passed, this is used as-is.
6039        dialect: the dialect used to parse the input expression.
6040        copy: whether or not to copy `expressions` (only applies to Expressions).
6041        **opts: other options to use to parse the input expressions.
6042
6043    Returns:
6044        Or: the new condition
6045    """
6046    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:
6049def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6050    """
6051    Wrap a condition with a NOT operator.
6052
6053    Example:
6054        >>> not_("this_suit='black'").sql()
6055        "NOT this_suit = 'black'"
6056
6057    Args:
6058        expression: the SQL code string to parse.
6059            If an Expression instance is passed, this is used as-is.
6060        dialect: the dialect used to parse the input expression.
6061        copy: whether to copy the expression or not.
6062        **opts: other options to use to parse the input expressions.
6063
6064    Returns:
6065        The new condition.
6066    """
6067    this = condition(
6068        expression,
6069        dialect=dialect,
6070        copy=copy,
6071        **opts,
6072    )
6073    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:
6076def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6077    """
6078    Wrap an expression in parentheses.
6079
6080    Example:
6081        >>> paren("5 + 3").sql()
6082        '(5 + 3)'
6083
6084    Args:
6085        expression: the SQL code string to parse.
6086            If an Expression instance is passed, this is used as-is.
6087        copy: whether to copy the expression or not.
6088
6089    Returns:
6090        The wrapped expression.
6091    """
6092    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):
6110def to_identifier(name, quoted=None, copy=True):
6111    """Builds an identifier.
6112
6113    Args:
6114        name: The name to turn into an identifier.
6115        quoted: Whether or not force quote the identifier.
6116        copy: Whether or not to copy name if it's an Identifier.
6117
6118    Returns:
6119        The identifier ast node.
6120    """
6121
6122    if name is None:
6123        return None
6124
6125    if isinstance(name, Identifier):
6126        identifier = maybe_copy(name, copy)
6127    elif isinstance(name, str):
6128        identifier = Identifier(
6129            this=name,
6130            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6131        )
6132    else:
6133        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6134    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether or not force quote the identifier.
  • copy: Whether or not to copy name if it's an Identifier.
Returns:

The identifier ast node.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Identifier:
6137def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6138    """
6139    Parses a given string into an identifier.
6140
6141    Args:
6142        name: The name to parse into an identifier.
6143        dialect: The dialect to parse against.
6144
6145    Returns:
6146        The identifier ast node.
6147    """
6148    try:
6149        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6150    except ParseError:
6151        expression = to_identifier(name)
6152
6153    return expression

Parses a given string into an identifier.

Arguments:
  • name: The name to parse into an identifier.
  • dialect: The dialect to parse against.
Returns:

The identifier ast node.

INTERVAL_STRING_RE = re.compile('\\s*([0-9]+)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
6159def to_interval(interval: str | Literal) -> Interval:
6160    """Builds an interval expression from a string like '1 day' or '5 months'."""
6161    if isinstance(interval, Literal):
6162        if not interval.is_string:
6163            raise ValueError("Invalid interval string.")
6164
6165        interval = interval.this
6166
6167    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6168
6169    if not interval_parts:
6170        raise ValueError("Invalid interval string.")
6171
6172    return Interval(
6173        this=Literal.string(interval_parts.group(1)),
6174        unit=Var(this=interval_parts.group(2).upper()),
6175    )

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

def to_table( sql_path: Union[str, Table, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Optional[Table]:
6188def to_table(
6189    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6190) -> t.Optional[Table]:
6191    """
6192    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6193    If a table is passed in then that table is returned.
6194
6195    Args:
6196        sql_path: a `[catalog].[schema].[table]` string.
6197        dialect: the source dialect according to which the table name will be parsed.
6198        copy: Whether or not to copy a table if it is passed in.
6199        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6200
6201    Returns:
6202        A table expression.
6203    """
6204    if sql_path is None or isinstance(sql_path, Table):
6205        return maybe_copy(sql_path, copy=copy)
6206    if not isinstance(sql_path, str):
6207        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6208
6209    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6210    if table:
6211        for k, v in kwargs.items():
6212            table.set(k, v)
6213
6214    return table

Create a table expression from a [catalog].[schema].[table] sql path. Catalog and schema are optional. If a table is passed in then that table is returned.

Arguments:
  • sql_path: a [catalog].[schema].[table] string.
  • dialect: the source dialect according to which the table name will be parsed.
  • copy: Whether or not to copy a table if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, **kwargs) -> Column:
6217def to_column(sql_path: str | Column, **kwargs) -> Column:
6218    """
6219    Create a column from a `[table].[column]` sql path. Schema is optional.
6220
6221    If a column is passed in then that column is returned.
6222
6223    Args:
6224        sql_path: `[table].[column]` string
6225    Returns:
6226        Table: A column expression
6227    """
6228    if sql_path is None or isinstance(sql_path, Column):
6229        return sql_path
6230    if not isinstance(sql_path, str):
6231        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6232    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):
6235def alias_(
6236    expression: ExpOrStr,
6237    alias: str | Identifier,
6238    table: bool | t.Sequence[str | Identifier] = False,
6239    quoted: t.Optional[bool] = None,
6240    dialect: DialectType = None,
6241    copy: bool = True,
6242    **opts,
6243):
6244    """Create an Alias expression.
6245
6246    Example:
6247        >>> alias_('foo', 'bar').sql()
6248        'foo AS bar'
6249
6250        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6251        '(SELECT 1, 2) AS bar(a, b)'
6252
6253    Args:
6254        expression: the SQL code strings to parse.
6255            If an Expression instance is passed, this is used as-is.
6256        alias: the alias name to use. If the name has
6257            special characters it is quoted.
6258        table: Whether or not to create a table alias, can also be a list of columns.
6259        quoted: whether or not to quote the alias
6260        dialect: the dialect used to parse the input expression.
6261        copy: Whether or not to copy the expression.
6262        **opts: other options to use to parse the input expressions.
6263
6264    Returns:
6265        Alias: the aliased expression
6266    """
6267    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6268    alias = to_identifier(alias, quoted=quoted)
6269
6270    if table:
6271        table_alias = TableAlias(this=alias)
6272        exp.set("alias", table_alias)
6273
6274        if not isinstance(table, bool):
6275            for column in table:
6276                table_alias.append("columns", to_identifier(column, quoted=quoted))
6277
6278        return exp
6279
6280    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6281    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6282    # for the complete Window expression.
6283    #
6284    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6285
6286    if "alias" in exp.arg_types and not isinstance(exp, Window):
6287        exp.set("alias", alias)
6288        return exp
6289    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:
6292def subquery(
6293    expression: ExpOrStr,
6294    alias: t.Optional[Identifier | str] = None,
6295    dialect: DialectType = None,
6296    **opts,
6297) -> Select:
6298    """
6299    Build a subquery expression.
6300
6301    Example:
6302        >>> subquery('select x from tbl', 'bar').select('x').sql()
6303        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6304
6305    Args:
6306        expression: the SQL code strings to parse.
6307            If an Expression instance is passed, this is used as-is.
6308        alias: the alias name to use.
6309        dialect: the dialect used to parse the input expression.
6310        **opts: other options to use to parse the input expressions.
6311
6312    Returns:
6313        A new Select instance with the subquery expression included.
6314    """
6315
6316    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6317    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, *fields: Union[str, Identifier], quoted: Optional[bool] = None, copy: bool = True) -> Column | Dot:
6320def column(
6321    col: str | Identifier,
6322    table: t.Optional[str | Identifier] = None,
6323    db: t.Optional[str | Identifier] = None,
6324    catalog: t.Optional[str | Identifier] = None,
6325    *fields: t.Union[str, Identifier],
6326    quoted: t.Optional[bool] = None,
6327    copy: bool = True,
6328) -> Column | Dot:
6329    """
6330    Build a Column.
6331
6332    Args:
6333        col: Column name.
6334        table: Table name.
6335        db: Database name.
6336        catalog: Catalog name.
6337        fields: Additional fields using dots.
6338        quoted: Whether to force quotes on the column's identifiers.
6339        copy: Whether or not to copy identifiers if passed in.
6340
6341    Returns:
6342        The new Column instance.
6343    """
6344    this: t.Union[Column, Dot] = Column(
6345        this=to_identifier(col, quoted=quoted, copy=copy),
6346        table=to_identifier(table, quoted=quoted, copy=copy),
6347        db=to_identifier(db, quoted=quoted, copy=copy),
6348        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6349    )
6350
6351    if fields:
6352        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6353    return this

Build a Column.

Arguments:
  • col: Column name.
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • fields: Additional fields using dots.
  • quoted: Whether to force quotes on the column's identifiers.
  • copy: Whether or not to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], **opts) -> Cast:
6356def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6357    """Cast an expression to a data type.
6358
6359    Example:
6360        >>> cast('x + 1', 'int').sql()
6361        'CAST(x + 1 AS INT)'
6362
6363    Args:
6364        expression: The expression to cast.
6365        to: The datatype to cast to.
6366
6367    Returns:
6368        The new Cast instance.
6369    """
6370    expression = maybe_parse(expression, **opts)
6371    data_type = DataType.build(to, **opts)
6372    expression = Cast(this=expression, to=data_type)
6373    expression.type = data_type
6374    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:
6377def table_(
6378    table: Identifier | str,
6379    db: t.Optional[Identifier | str] = None,
6380    catalog: t.Optional[Identifier | str] = None,
6381    quoted: t.Optional[bool] = None,
6382    alias: t.Optional[Identifier | str] = None,
6383) -> Table:
6384    """Build a Table.
6385
6386    Args:
6387        table: Table name.
6388        db: Database name.
6389        catalog: Catalog name.
6390        quote: Whether to force quotes on the table's identifiers.
6391        alias: Table's alias.
6392
6393    Returns:
6394        The new Table instance.
6395    """
6396    return Table(
6397        this=to_identifier(table, quoted=quoted) if table else None,
6398        db=to_identifier(db, quoted=quoted) if db else None,
6399        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6400        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6401    )

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:
6404def values(
6405    values: t.Iterable[t.Tuple[t.Any, ...]],
6406    alias: t.Optional[str] = None,
6407    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6408) -> Values:
6409    """Build VALUES statement.
6410
6411    Example:
6412        >>> values([(1, '2')]).sql()
6413        "VALUES (1, '2')"
6414
6415    Args:
6416        values: values statements that will be converted to SQL
6417        alias: optional alias
6418        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6419         If either are provided then an alias is also required.
6420
6421    Returns:
6422        Values: the Values expression object
6423    """
6424    if columns and not alias:
6425        raise ValueError("Alias is required when providing columns")
6426
6427    return Values(
6428        expressions=[convert(tup) for tup in values],
6429        alias=(
6430            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6431            if columns
6432            else (TableAlias(this=to_identifier(alias)) if alias else None)
6433        ),
6434    )

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:
6437def var(name: t.Optional[ExpOrStr]) -> Var:
6438    """Build a SQL variable.
6439
6440    Example:
6441        >>> repr(var('x'))
6442        'Var(this=x)'
6443
6444        >>> repr(var(column('x', table='y')))
6445        'Var(this=x)'
6446
6447    Args:
6448        name: The name of the var or an expression who's name will become the var.
6449
6450    Returns:
6451        The new variable node.
6452    """
6453    if not name:
6454        raise ValueError("Cannot convert empty name into var.")
6455
6456    if isinstance(name, Expression):
6457        name = name.name
6458    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:
6461def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6462    """Build ALTER TABLE... RENAME... expression
6463
6464    Args:
6465        old_name: The old name of the table
6466        new_name: The new name of the table
6467
6468    Returns:
6469        Alter table expression
6470    """
6471    old_table = to_table(old_name)
6472    new_table = to_table(new_name)
6473    return AlterTable(
6474        this=old_table,
6475        actions=[
6476            RenameTable(this=new_table),
6477        ],
6478    )

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:
6481def convert(value: t.Any, copy: bool = False) -> Expression:
6482    """Convert a python value into an expression object.
6483
6484    Raises an error if a conversion is not possible.
6485
6486    Args:
6487        value: A python object.
6488        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6489
6490    Returns:
6491        Expression: the equivalent expression object.
6492    """
6493    if isinstance(value, Expression):
6494        return maybe_copy(value, copy)
6495    if isinstance(value, str):
6496        return Literal.string(value)
6497    if isinstance(value, bool):
6498        return Boolean(this=value)
6499    if value is None or (isinstance(value, float) and math.isnan(value)):
6500        return NULL
6501    if isinstance(value, numbers.Number):
6502        return Literal.number(value)
6503    if isinstance(value, datetime.datetime):
6504        datetime_literal = Literal.string(
6505            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6506        )
6507        return TimeStrToTime(this=datetime_literal)
6508    if isinstance(value, datetime.date):
6509        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6510        return DateStrToDate(this=date_literal)
6511    if isinstance(value, tuple):
6512        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6513    if isinstance(value, list):
6514        return Array(expressions=[convert(v, copy=copy) for v in value])
6515    if isinstance(value, dict):
6516        return Map(
6517            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6518            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6519        )
6520    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:
6523def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6524    """
6525    Replace children of an expression with the result of a lambda fun(child) -> exp.
6526    """
6527    for k, v in expression.args.items():
6528        is_list_arg = type(v) is list
6529
6530        child_nodes = v if is_list_arg else [v]
6531        new_child_nodes = []
6532
6533        for cn in child_nodes:
6534            if isinstance(cn, Expression):
6535                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6536                    new_child_nodes.append(child_node)
6537                    child_node.parent = expression
6538                    child_node.arg_key = k
6539            else:
6540                new_child_nodes.append(cn)
6541
6542        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]:
6545def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6546    """
6547    Return all table names referenced through columns in an expression.
6548
6549    Example:
6550        >>> import sqlglot
6551        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6552        ['a', 'c']
6553
6554    Args:
6555        expression: expression to find table names.
6556        exclude: a table name to exclude
6557
6558    Returns:
6559        A list of unique names.
6560    """
6561    return {
6562        table
6563        for table in (column.table for column in expression.find_all(Column))
6564        if table and table != exclude
6565    }

Return all table names referenced through columns in an expression.

Example:
>>> import sqlglot
>>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
['a', 'c']
Arguments:
  • expression: expression to find table names.
  • exclude: a table name to exclude
Returns:

A list of unique names.

def table_name( table: Table | str, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, identify: bool = False) -> str:
6568def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6569    """Get the full name of a table as a string.
6570
6571    Args:
6572        table: Table expression node or string.
6573        dialect: The dialect to generate the table name for.
6574        identify: Determines when an identifier should be quoted. Possible values are:
6575            False (default): Never quote, except in cases where it's mandatory by the dialect.
6576            True: Always quote.
6577
6578    Examples:
6579        >>> from sqlglot import exp, parse_one
6580        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6581        'a.b.c'
6582
6583    Returns:
6584        The table name.
6585    """
6586
6587    table = maybe_parse(table, into=Table, dialect=dialect)
6588
6589    if not table:
6590        raise ValueError(f"Cannot parse {table}")
6591
6592    return ".".join(
6593        part.sql(dialect=dialect, identify=True, copy=False)
6594        if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6595        else part.name
6596        for part in table.parts
6597    )

Get the full name of a table as a string.

Arguments:
  • table: Table expression node or string.
  • dialect: The dialect to generate the table name for.
  • identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True: Always quote.
Examples:
>>> from sqlglot import exp, parse_one
>>> table_name(parse_one("select * from a.b.c").find(exp.Table))
'a.b.c'
Returns:

The table name.

def normalize_table_name( table: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> str:
6600def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6601    """Returns a case normalized table name without quotes.
6602
6603    Args:
6604        table: the table to normalize
6605        dialect: the dialect to use for normalization rules
6606        copy: whether or not to copy the expression.
6607
6608    Examples:
6609        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6610        'A-B.c'
6611    """
6612    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6613
6614    return ".".join(
6615        p.name
6616        for p in normalize_identifiers(
6617            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6618        ).parts
6619    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether or not to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> ~E:
6622def replace_tables(
6623    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6624) -> E:
6625    """Replace all tables in expression according to the mapping.
6626
6627    Args:
6628        expression: expression node to be transformed and replaced.
6629        mapping: mapping of table names.
6630        dialect: the dialect of the mapping table
6631        copy: whether or not to copy the expression.
6632
6633    Examples:
6634        >>> from sqlglot import exp, parse_one
6635        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6636        'SELECT * FROM c /* a.b */'
6637
6638    Returns:
6639        The mapped expression.
6640    """
6641
6642    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6643
6644    def _replace_tables(node: Expression) -> Expression:
6645        if isinstance(node, Table):
6646            original = normalize_table_name(node, dialect=dialect)
6647            new_name = mapping.get(original)
6648
6649            if new_name:
6650                table = to_table(
6651                    new_name,
6652                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6653                )
6654                table.add_comments([original])
6655                return table
6656        return node
6657
6658    return expression.transform(_replace_tables, copy=copy)

Replace all tables in expression according to the mapping.

Arguments:
  • expression: expression node to be transformed and replaced.
  • mapping: mapping of table names.
  • dialect: the dialect of the mapping table
  • copy: whether or not to copy the expression.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
'SELECT * FROM c /* a.b */'
Returns:

The mapped expression.

def replace_placeholders( expression: Expression, *args, **kwargs) -> Expression:
6661def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6662    """Replace placeholders in an expression.
6663
6664    Args:
6665        expression: expression node to be transformed and replaced.
6666        args: positional names that will substitute unnamed placeholders in the given order.
6667        kwargs: keyword arguments that will substitute named placeholders.
6668
6669    Examples:
6670        >>> from sqlglot import exp, parse_one
6671        >>> replace_placeholders(
6672        ...     parse_one("select * from :tbl where ? = ?"),
6673        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6674        ... ).sql()
6675        "SELECT * FROM foo WHERE str_col = 'b'"
6676
6677    Returns:
6678        The mapped expression.
6679    """
6680
6681    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6682        if isinstance(node, Placeholder):
6683            if node.name:
6684                new_name = kwargs.get(node.name)
6685                if new_name:
6686                    return convert(new_name)
6687            else:
6688                try:
6689                    return convert(next(args))
6690                except StopIteration:
6691                    pass
6692        return node
6693
6694    return expression.transform(_replace_placeholders, iter(args), **kwargs)

Replace placeholders in an expression.

Arguments:
  • expression: expression node to be transformed and replaced.
  • args: positional names that will substitute unnamed placeholders in the given order.
  • kwargs: keyword arguments that will substitute named placeholders.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_placeholders(
...     parse_one("select * from :tbl where ? = ?"),
...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
... ).sql()
"SELECT * FROM foo WHERE str_col = 'b'"
Returns:

The mapped expression.

def expand( expression: Expression, sources: Dict[str, Subqueryable], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
6697def expand(
6698    expression: Expression,
6699    sources: t.Dict[str, Subqueryable],
6700    dialect: DialectType = None,
6701    copy: bool = True,
6702) -> Expression:
6703    """Transforms an expression by expanding all referenced sources into subqueries.
6704
6705    Examples:
6706        >>> from sqlglot import parse_one
6707        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6708        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6709
6710        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6711        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6712
6713    Args:
6714        expression: The expression to expand.
6715        sources: A dictionary of name to Subqueryables.
6716        dialect: The dialect of the sources dict.
6717        copy: Whether or not to copy the expression during transformation. Defaults to True.
6718
6719    Returns:
6720        The transformed expression.
6721    """
6722    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6723
6724    def _expand(node: Expression):
6725        if isinstance(node, Table):
6726            name = normalize_table_name(node, dialect=dialect)
6727            source = sources.get(name)
6728            if source:
6729                subquery = source.subquery(node.alias or name)
6730                subquery.comments = [f"source: {name}"]
6731                return subquery.transform(_expand, copy=False)
6732        return node
6733
6734    return expression.transform(_expand, copy=copy)

Transforms an expression by expanding all referenced sources into subqueries.

Examples:
>>> from sqlglot import parse_one
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
Arguments:
  • expression: The expression to expand.
  • sources: A dictionary of name to Subqueryables.
  • dialect: The dialect of the sources dict.
  • copy: Whether or not to copy the expression during transformation. Defaults to True.
Returns:

The transformed expression.

def func( name: str, *args, copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Func:
6737def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
6738    """
6739    Returns a Func expression.
6740
6741    Examples:
6742        >>> func("abs", 5).sql()
6743        'ABS(5)'
6744
6745        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6746        'CAST(5 AS DOUBLE)'
6747
6748    Args:
6749        name: the name of the function to build.
6750        args: the args used to instantiate the function of interest.
6751        copy: whether or not to copy the argument expressions.
6752        dialect: the source dialect.
6753        kwargs: the kwargs used to instantiate the function of interest.
6754
6755    Note:
6756        The arguments `args` and `kwargs` are mutually exclusive.
6757
6758    Returns:
6759        An instance of the function of interest, or an anonymous function, if `name` doesn't
6760        correspond to an existing `sqlglot.expressions.Func` class.
6761    """
6762    if args and kwargs:
6763        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6764
6765    from sqlglot.dialects.dialect import Dialect
6766
6767    dialect = Dialect.get_or_raise(dialect)
6768
6769    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
6770    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
6771
6772    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
6773    if constructor:
6774        if converted:
6775            if "dialect" in constructor.__code__.co_varnames:
6776                function = constructor(converted, dialect=dialect)
6777            else:
6778                function = constructor(converted)
6779        elif constructor.__name__ == "from_arg_list":
6780            function = constructor.__self__(**kwargs)  # type: ignore
6781        else:
6782            constructor = FUNCTION_BY_NAME.get(name.upper())
6783            if constructor:
6784                function = constructor(**kwargs)
6785            else:
6786                raise ValueError(
6787                    f"Unable to convert '{name}' into a Func. Either manually construct "
6788                    "the Func expression of interest or parse the function call."
6789                )
6790    else:
6791        kwargs = kwargs or {"expressions": converted}
6792        function = Anonymous(this=name, **kwargs)
6793
6794    for error_message in function.error_messages(converted):
6795        raise ValueError(error_message)
6796
6797    return function

Returns a Func expression.

Examples:
>>> func("abs", 5).sql()
'ABS(5)'
>>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
'CAST(5 AS DOUBLE)'
Arguments:
  • name: the name of the function to build.
  • args: the args used to instantiate the function of interest.
  • copy: whether or not to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Note:

The arguments args and kwargs are mutually exclusive.

Returns:

An instance of the function of interest, or an anonymous function, if name doesn't correspond to an existing Func class.

def case( expression: Union[str, Expression, NoneType] = None, **opts) -> Case:
6800def case(
6801    expression: t.Optional[ExpOrStr] = None,
6802    **opts,
6803) -> Case:
6804    """
6805    Initialize a CASE statement.
6806
6807    Example:
6808        case().when("a = 1", "foo").else_("bar")
6809
6810    Args:
6811        expression: Optionally, the input expression (not all dialects support this)
6812        **opts: Extra keyword arguments for parsing `expression`
6813    """
6814    if expression is not None:
6815        this = maybe_parse(expression, **opts)
6816    else:
6817        this = None
6818    return Case(this=this, ifs=[])

Initialize a CASE statement.

Example:

case().when("a = 1", "foo").else_("bar")

Arguments:
  • expression: Optionally, the input expression (not all dialects support this)
  • **opts: Extra keyword arguments for parsing expression
def cast_unless( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], *types: Union[str, DataType, DataType.Type], **opts: Any) -> Expression | Cast:
6821def cast_unless(
6822    expression: ExpOrStr,
6823    to: DATA_TYPE,
6824    *types: DATA_TYPE,
6825    **opts: t.Any,
6826) -> Expression | Cast:
6827    """
6828    Cast an expression to a data type unless it is a specified type.
6829
6830    Args:
6831        expression: The expression to cast.
6832        to: The data type to cast to.
6833        **types: The types to exclude from casting.
6834        **opts: Extra keyword arguments for parsing `expression`
6835    """
6836    expr = maybe_parse(expression, **opts)
6837    if expr.is_type(*types):
6838        return expr
6839    return cast(expr, to, **opts)

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

Arguments:
  • expression: The expression to cast.
  • to: The data type to cast to.
  • **types: The types to exclude from casting.
  • **opts: Extra keyword arguments for parsing expression
def true() -> Boolean:
6842def true() -> Boolean:
6843    """
6844    Returns a true Boolean expression.
6845    """
6846    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
6849def false() -> Boolean:
6850    """
6851    Returns a false Boolean expression.
6852    """
6853    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6856def null() -> Null:
6857    """
6858    Returns a Null expression.
6859    """
6860    return Null()

Returns a Null expression.

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