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 = {
1929        "this": True,
1930        "view": False,
1931        "outer": False,
1932        "alias": False,
1933        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
1934    }
1935
1936
1937class MatchRecognize(Expression):
1938    arg_types = {
1939        "partition_by": False,
1940        "order": False,
1941        "measures": False,
1942        "rows": False,
1943        "after": False,
1944        "pattern": False,
1945        "define": False,
1946        "alias": False,
1947    }
1948
1949
1950# Clickhouse FROM FINAL modifier
1951# https://clickhouse.com/docs/en/sql-reference/statements/select/from/#final-modifier
1952class Final(Expression):
1953    pass
1954
1955
1956class Offset(Expression):
1957    arg_types = {"this": False, "expression": True}
1958
1959
1960class Order(Expression):
1961    arg_types = {"this": False, "expressions": True, "interpolate": False}
1962
1963
1964# https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier
1965class WithFill(Expression):
1966    arg_types = {"from": False, "to": False, "step": False}
1967
1968
1969# hive specific sorts
1970# https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy
1971class Cluster(Order):
1972    pass
1973
1974
1975class Distribute(Order):
1976    pass
1977
1978
1979class Sort(Order):
1980    pass
1981
1982
1983class Ordered(Expression):
1984    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
1985
1986
1987class Property(Expression):
1988    arg_types = {"this": True, "value": True}
1989
1990
1991class AlgorithmProperty(Property):
1992    arg_types = {"this": True}
1993
1994
1995class AutoIncrementProperty(Property):
1996    arg_types = {"this": True}
1997
1998
1999# https://docs.aws.amazon.com/prescriptive-guidance/latest/materialized-views-redshift/refreshing-materialized-views.html
2000class AutoRefreshProperty(Property):
2001    arg_types = {"this": True}
2002
2003
2004class BlockCompressionProperty(Property):
2005    arg_types = {"autotemp": False, "always": False, "default": True, "manual": True, "never": True}
2006
2007
2008class CharacterSetProperty(Property):
2009    arg_types = {"this": True, "default": True}
2010
2011
2012class ChecksumProperty(Property):
2013    arg_types = {"on": False, "default": False}
2014
2015
2016class CollateProperty(Property):
2017    arg_types = {"this": True, "default": False}
2018
2019
2020class CopyGrantsProperty(Property):
2021    arg_types = {}
2022
2023
2024class DataBlocksizeProperty(Property):
2025    arg_types = {
2026        "size": False,
2027        "units": False,
2028        "minimum": False,
2029        "maximum": False,
2030        "default": False,
2031    }
2032
2033
2034class DefinerProperty(Property):
2035    arg_types = {"this": True}
2036
2037
2038class DistKeyProperty(Property):
2039    arg_types = {"this": True}
2040
2041
2042class DistStyleProperty(Property):
2043    arg_types = {"this": True}
2044
2045
2046class EngineProperty(Property):
2047    arg_types = {"this": True}
2048
2049
2050class HeapProperty(Property):
2051    arg_types = {}
2052
2053
2054class ToTableProperty(Property):
2055    arg_types = {"this": True}
2056
2057
2058class ExecuteAsProperty(Property):
2059    arg_types = {"this": True}
2060
2061
2062class ExternalProperty(Property):
2063    arg_types = {"this": False}
2064
2065
2066class FallbackProperty(Property):
2067    arg_types = {"no": True, "protection": False}
2068
2069
2070class FileFormatProperty(Property):
2071    arg_types = {"this": True}
2072
2073
2074class FreespaceProperty(Property):
2075    arg_types = {"this": True, "percent": False}
2076
2077
2078class InputModelProperty(Property):
2079    arg_types = {"this": True}
2080
2081
2082class OutputModelProperty(Property):
2083    arg_types = {"this": True}
2084
2085
2086class IsolatedLoadingProperty(Property):
2087    arg_types = {
2088        "no": True,
2089        "concurrent": True,
2090        "for_all": True,
2091        "for_insert": True,
2092        "for_none": True,
2093    }
2094
2095
2096class JournalProperty(Property):
2097    arg_types = {
2098        "no": False,
2099        "dual": False,
2100        "before": False,
2101        "local": False,
2102        "after": False,
2103    }
2104
2105
2106class LanguageProperty(Property):
2107    arg_types = {"this": True}
2108
2109
2110# spark ddl
2111class ClusteredByProperty(Property):
2112    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
2113
2114
2115class DictProperty(Property):
2116    arg_types = {"this": True, "kind": True, "settings": False}
2117
2118
2119class DictSubProperty(Property):
2120    pass
2121
2122
2123class DictRange(Property):
2124    arg_types = {"this": True, "min": True, "max": True}
2125
2126
2127# Clickhouse CREATE ... ON CLUSTER modifier
2128# https://clickhouse.com/docs/en/sql-reference/distributed-ddl
2129class OnCluster(Property):
2130    arg_types = {"this": True}
2131
2132
2133class LikeProperty(Property):
2134    arg_types = {"this": True, "expressions": False}
2135
2136
2137class LocationProperty(Property):
2138    arg_types = {"this": True}
2139
2140
2141class LockingProperty(Property):
2142    arg_types = {
2143        "this": False,
2144        "kind": True,
2145        "for_or_in": False,
2146        "lock_type": True,
2147        "override": False,
2148    }
2149
2150
2151class LogProperty(Property):
2152    arg_types = {"no": True}
2153
2154
2155class MaterializedProperty(Property):
2156    arg_types = {"this": False}
2157
2158
2159class MergeBlockRatioProperty(Property):
2160    arg_types = {"this": False, "no": False, "default": False, "percent": False}
2161
2162
2163class NoPrimaryIndexProperty(Property):
2164    arg_types = {}
2165
2166
2167class OnProperty(Property):
2168    arg_types = {"this": True}
2169
2170
2171class OnCommitProperty(Property):
2172    arg_types = {"delete": False}
2173
2174
2175class PartitionedByProperty(Property):
2176    arg_types = {"this": True}
2177
2178
2179# https://www.postgresql.org/docs/current/sql-createtable.html
2180class PartitionBoundSpec(Expression):
2181    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2182    arg_types = {
2183        "this": False,
2184        "expression": False,
2185        "from_expressions": False,
2186        "to_expressions": False,
2187    }
2188
2189
2190class PartitionedOfProperty(Property):
2191    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2192    arg_types = {"this": True, "expression": True}
2193
2194
2195class RemoteWithConnectionModelProperty(Property):
2196    arg_types = {"this": True}
2197
2198
2199class ReturnsProperty(Property):
2200    arg_types = {"this": True, "is_table": False, "table": False}
2201
2202
2203class RowFormatProperty(Property):
2204    arg_types = {"this": True}
2205
2206
2207class RowFormatDelimitedProperty(Property):
2208    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2209    arg_types = {
2210        "fields": False,
2211        "escaped": False,
2212        "collection_items": False,
2213        "map_keys": False,
2214        "lines": False,
2215        "null": False,
2216        "serde": False,
2217    }
2218
2219
2220class RowFormatSerdeProperty(Property):
2221    arg_types = {"this": True, "serde_properties": False}
2222
2223
2224# https://spark.apache.org/docs/3.1.2/sql-ref-syntax-qry-select-transform.html
2225class QueryTransform(Expression):
2226    arg_types = {
2227        "expressions": True,
2228        "command_script": True,
2229        "schema": False,
2230        "row_format_before": False,
2231        "record_writer": False,
2232        "row_format_after": False,
2233        "record_reader": False,
2234    }
2235
2236
2237class SampleProperty(Property):
2238    arg_types = {"this": True}
2239
2240
2241class SchemaCommentProperty(Property):
2242    arg_types = {"this": True}
2243
2244
2245class SerdeProperties(Property):
2246    arg_types = {"expressions": True}
2247
2248
2249class SetProperty(Property):
2250    arg_types = {"multi": True}
2251
2252
2253class SettingsProperty(Property):
2254    arg_types = {"expressions": True}
2255
2256
2257class SortKeyProperty(Property):
2258    arg_types = {"this": True, "compound": False}
2259
2260
2261class SqlSecurityProperty(Property):
2262    arg_types = {"definer": True}
2263
2264
2265class StabilityProperty(Property):
2266    arg_types = {"this": True}
2267
2268
2269class TemporaryProperty(Property):
2270    arg_types = {}
2271
2272
2273class TransformModelProperty(Property):
2274    arg_types = {"expressions": True}
2275
2276
2277class TransientProperty(Property):
2278    arg_types = {"this": False}
2279
2280
2281class VolatileProperty(Property):
2282    arg_types = {"this": False}
2283
2284
2285class WithDataProperty(Property):
2286    arg_types = {"no": True, "statistics": False}
2287
2288
2289class WithJournalTableProperty(Property):
2290    arg_types = {"this": True}
2291
2292
2293class WithSystemVersioningProperty(Property):
2294    # this -> history table name, expression -> data consistency check
2295    arg_types = {"this": False, "expression": False}
2296
2297
2298class Properties(Expression):
2299    arg_types = {"expressions": True}
2300
2301    NAME_TO_PROPERTY = {
2302        "ALGORITHM": AlgorithmProperty,
2303        "AUTO_INCREMENT": AutoIncrementProperty,
2304        "CHARACTER SET": CharacterSetProperty,
2305        "CLUSTERED_BY": ClusteredByProperty,
2306        "COLLATE": CollateProperty,
2307        "COMMENT": SchemaCommentProperty,
2308        "DEFINER": DefinerProperty,
2309        "DISTKEY": DistKeyProperty,
2310        "DISTSTYLE": DistStyleProperty,
2311        "ENGINE": EngineProperty,
2312        "EXECUTE AS": ExecuteAsProperty,
2313        "FORMAT": FileFormatProperty,
2314        "LANGUAGE": LanguageProperty,
2315        "LOCATION": LocationProperty,
2316        "PARTITIONED_BY": PartitionedByProperty,
2317        "RETURNS": ReturnsProperty,
2318        "ROW_FORMAT": RowFormatProperty,
2319        "SORTKEY": SortKeyProperty,
2320    }
2321
2322    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2323
2324    # CREATE property locations
2325    # Form: schema specified
2326    #   create [POST_CREATE]
2327    #     table a [POST_NAME]
2328    #     (b int) [POST_SCHEMA]
2329    #     with ([POST_WITH])
2330    #     index (b) [POST_INDEX]
2331    #
2332    # Form: alias selection
2333    #   create [POST_CREATE]
2334    #     table a [POST_NAME]
2335    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2336    #     index (c) [POST_INDEX]
2337    class Location(AutoName):
2338        POST_CREATE = auto()
2339        POST_NAME = auto()
2340        POST_SCHEMA = auto()
2341        POST_WITH = auto()
2342        POST_ALIAS = auto()
2343        POST_EXPRESSION = auto()
2344        POST_INDEX = auto()
2345        UNSUPPORTED = auto()
2346
2347    @classmethod
2348    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2349        expressions = []
2350        for key, value in properties_dict.items():
2351            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2352            if property_cls:
2353                expressions.append(property_cls(this=convert(value)))
2354            else:
2355                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2356
2357        return cls(expressions=expressions)
2358
2359
2360class Qualify(Expression):
2361    pass
2362
2363
2364class InputOutputFormat(Expression):
2365    arg_types = {"input_format": False, "output_format": False}
2366
2367
2368# https://www.ibm.com/docs/en/ias?topic=procedures-return-statement-in-sql
2369class Return(Expression):
2370    pass
2371
2372
2373class Reference(Expression):
2374    arg_types = {"this": True, "expressions": False, "options": False}
2375
2376
2377class Tuple(Expression):
2378    arg_types = {"expressions": False}
2379
2380    def isin(
2381        self,
2382        *expressions: t.Any,
2383        query: t.Optional[ExpOrStr] = None,
2384        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2385        copy: bool = True,
2386        **opts,
2387    ) -> In:
2388        return In(
2389            this=maybe_copy(self, copy),
2390            expressions=[convert(e, copy=copy) for e in expressions],
2391            query=maybe_parse(query, copy=copy, **opts) if query else None,
2392            unnest=Unnest(
2393                expressions=[
2394                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2395                ]
2396            )
2397            if unnest
2398            else None,
2399        )
2400
2401
2402class Subqueryable(Unionable):
2403    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2404        """
2405        Convert this expression to an aliased expression that can be used as a Subquery.
2406
2407        Example:
2408            >>> subquery = Select().select("x").from_("tbl").subquery()
2409            >>> Select().select("x").from_(subquery).sql()
2410            'SELECT x FROM (SELECT x FROM tbl)'
2411
2412        Args:
2413            alias (str | Identifier): an optional alias for the subquery
2414            copy (bool): if `False`, modify this expression instance in-place.
2415
2416        Returns:
2417            Alias: the subquery
2418        """
2419        instance = maybe_copy(self, copy)
2420        if not isinstance(alias, Expression):
2421            alias = TableAlias(this=to_identifier(alias)) if alias else None
2422
2423        return Subquery(this=instance, alias=alias)
2424
2425    def limit(
2426        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2427    ) -> Select:
2428        raise NotImplementedError
2429
2430    @property
2431    def ctes(self):
2432        with_ = self.args.get("with")
2433        if not with_:
2434            return []
2435        return with_.expressions
2436
2437    @property
2438    def selects(self) -> t.List[Expression]:
2439        raise NotImplementedError("Subqueryable objects must implement `selects`")
2440
2441    @property
2442    def named_selects(self) -> t.List[str]:
2443        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2444
2445    def select(
2446        self,
2447        *expressions: t.Optional[ExpOrStr],
2448        append: bool = True,
2449        dialect: DialectType = None,
2450        copy: bool = True,
2451        **opts,
2452    ) -> Subqueryable:
2453        raise NotImplementedError("Subqueryable objects must implement `select`")
2454
2455    def with_(
2456        self,
2457        alias: ExpOrStr,
2458        as_: ExpOrStr,
2459        recursive: t.Optional[bool] = None,
2460        append: bool = True,
2461        dialect: DialectType = None,
2462        copy: bool = True,
2463        **opts,
2464    ) -> Subqueryable:
2465        """
2466        Append to or set the common table expressions.
2467
2468        Example:
2469            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2470            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2471
2472        Args:
2473            alias: the SQL code string to parse as the table name.
2474                If an `Expression` instance is passed, this is used as-is.
2475            as_: the SQL code string to parse as the table expression.
2476                If an `Expression` instance is passed, it will be used as-is.
2477            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2478            append: if `True`, add to any existing expressions.
2479                Otherwise, this resets the expressions.
2480            dialect: the dialect used to parse the input expression.
2481            copy: if `False`, modify this expression instance in-place.
2482            opts: other options to use to parse the input expressions.
2483
2484        Returns:
2485            The modified expression.
2486        """
2487        return _apply_cte_builder(
2488            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2489        )
2490
2491
2492QUERY_MODIFIERS = {
2493    "match": False,
2494    "laterals": False,
2495    "joins": False,
2496    "connect": False,
2497    "pivots": False,
2498    "where": False,
2499    "group": False,
2500    "having": False,
2501    "qualify": False,
2502    "windows": False,
2503    "distribute": False,
2504    "sort": False,
2505    "cluster": False,
2506    "order": False,
2507    "limit": False,
2508    "offset": False,
2509    "locks": False,
2510    "sample": False,
2511    "settings": False,
2512    "format": False,
2513}
2514
2515
2516# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16
2517class WithTableHint(Expression):
2518    arg_types = {"expressions": True}
2519
2520
2521# https://dev.mysql.com/doc/refman/8.0/en/index-hints.html
2522class IndexTableHint(Expression):
2523    arg_types = {"this": True, "expressions": False, "target": False}
2524
2525
2526# https://docs.snowflake.com/en/sql-reference/constructs/at-before
2527class HistoricalData(Expression):
2528    arg_types = {"this": True, "kind": True, "expression": True}
2529
2530
2531class Table(Expression):
2532    arg_types = {
2533        "this": True,
2534        "alias": False,
2535        "db": False,
2536        "catalog": False,
2537        "laterals": False,
2538        "joins": False,
2539        "pivots": False,
2540        "hints": False,
2541        "system_time": False,
2542        "version": False,
2543        "format": False,
2544        "pattern": False,
2545        "ordinality": False,
2546        "when": False,
2547    }
2548
2549    @property
2550    def name(self) -> str:
2551        if isinstance(self.this, Func):
2552            return ""
2553        return self.this.name
2554
2555    @property
2556    def db(self) -> str:
2557        return self.text("db")
2558
2559    @property
2560    def catalog(self) -> str:
2561        return self.text("catalog")
2562
2563    @property
2564    def selects(self) -> t.List[Expression]:
2565        return []
2566
2567    @property
2568    def named_selects(self) -> t.List[str]:
2569        return []
2570
2571    @property
2572    def parts(self) -> t.List[Expression]:
2573        """Return the parts of a table in order catalog, db, table."""
2574        parts: t.List[Expression] = []
2575
2576        for arg in ("catalog", "db", "this"):
2577            part = self.args.get(arg)
2578
2579            if isinstance(part, Dot):
2580                parts.extend(part.flatten())
2581            elif isinstance(part, Expression):
2582                parts.append(part)
2583
2584        return parts
2585
2586    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
2587        parts = self.parts
2588        col = column(*reversed(parts[0:4]), *parts[4:], copy=copy)  # type: ignore
2589        alias = self.args.get("alias")
2590        if alias:
2591            col = alias_(col, alias.this, copy=copy)
2592        return col
2593
2594
2595class Union(Subqueryable):
2596    arg_types = {
2597        "with": False,
2598        "this": True,
2599        "expression": True,
2600        "distinct": False,
2601        "by_name": False,
2602        **QUERY_MODIFIERS,
2603    }
2604
2605    def limit(
2606        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2607    ) -> Select:
2608        """
2609        Set the LIMIT expression.
2610
2611        Example:
2612            >>> select("1").union(select("1")).limit(1).sql()
2613            'SELECT * FROM (SELECT 1 UNION SELECT 1) AS _l_0 LIMIT 1'
2614
2615        Args:
2616            expression: the SQL code string to parse.
2617                This can also be an integer.
2618                If a `Limit` instance is passed, this is used as-is.
2619                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2620            dialect: the dialect used to parse the input expression.
2621            copy: if `False`, modify this expression instance in-place.
2622            opts: other options to use to parse the input expressions.
2623
2624        Returns:
2625            The limited subqueryable.
2626        """
2627        return (
2628            select("*")
2629            .from_(self.subquery(alias="_l_0", copy=copy))
2630            .limit(expression, dialect=dialect, copy=False, **opts)
2631        )
2632
2633    def select(
2634        self,
2635        *expressions: t.Optional[ExpOrStr],
2636        append: bool = True,
2637        dialect: DialectType = None,
2638        copy: bool = True,
2639        **opts,
2640    ) -> Union:
2641        """Append to or set the SELECT of the union recursively.
2642
2643        Example:
2644            >>> from sqlglot import parse_one
2645            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2646            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2647
2648        Args:
2649            *expressions: the SQL code strings to parse.
2650                If an `Expression` instance is passed, it will be used as-is.
2651            append: if `True`, add to any existing expressions.
2652                Otherwise, this resets the expressions.
2653            dialect: the dialect used to parse the input expressions.
2654            copy: if `False`, modify this expression instance in-place.
2655            opts: other options to use to parse the input expressions.
2656
2657        Returns:
2658            Union: the modified expression.
2659        """
2660        this = self.copy() if copy else self
2661        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2662        this.expression.unnest().select(
2663            *expressions, append=append, dialect=dialect, copy=False, **opts
2664        )
2665        return this
2666
2667    @property
2668    def named_selects(self) -> t.List[str]:
2669        return self.this.unnest().named_selects
2670
2671    @property
2672    def is_star(self) -> bool:
2673        return self.this.is_star or self.expression.is_star
2674
2675    @property
2676    def selects(self) -> t.List[Expression]:
2677        return self.this.unnest().selects
2678
2679    @property
2680    def left(self) -> Expression:
2681        return self.this
2682
2683    @property
2684    def right(self) -> Expression:
2685        return self.expression
2686
2687
2688class Except(Union):
2689    pass
2690
2691
2692class Intersect(Union):
2693    pass
2694
2695
2696class Unnest(UDTF):
2697    arg_types = {
2698        "expressions": True,
2699        "alias": False,
2700        "offset": False,
2701    }
2702
2703
2704class Update(Expression):
2705    arg_types = {
2706        "with": False,
2707        "this": False,
2708        "expressions": True,
2709        "from": False,
2710        "where": False,
2711        "returning": False,
2712        "order": False,
2713        "limit": False,
2714    }
2715
2716
2717class Values(UDTF):
2718    arg_types = {"expressions": True, "alias": False}
2719
2720
2721class Var(Expression):
2722    pass
2723
2724
2725class Version(Expression):
2726    """
2727    Time travel, iceberg, bigquery etc
2728    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
2729    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
2730    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
2731    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
2732    this is either TIMESTAMP or VERSION
2733    kind is ("AS OF", "BETWEEN")
2734    """
2735
2736    arg_types = {"this": True, "kind": True, "expression": False}
2737
2738
2739class Schema(Expression):
2740    arg_types = {"this": False, "expressions": False}
2741
2742
2743# https://dev.mysql.com/doc/refman/8.0/en/select.html
2744# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html
2745class Lock(Expression):
2746    arg_types = {"update": True, "expressions": False, "wait": False}
2747
2748
2749class Select(Subqueryable):
2750    arg_types = {
2751        "with": False,
2752        "kind": False,
2753        "expressions": False,
2754        "hint": False,
2755        "distinct": False,
2756        "into": False,
2757        "from": False,
2758        **QUERY_MODIFIERS,
2759    }
2760
2761    def from_(
2762        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
2763    ) -> Select:
2764        """
2765        Set the FROM expression.
2766
2767        Example:
2768            >>> Select().from_("tbl").select("x").sql()
2769            'SELECT x FROM tbl'
2770
2771        Args:
2772            expression : the SQL code strings to parse.
2773                If a `From` instance is passed, this is used as-is.
2774                If another `Expression` instance is passed, it will be wrapped in a `From`.
2775            dialect: the dialect used to parse the input expression.
2776            copy: if `False`, modify this expression instance in-place.
2777            opts: other options to use to parse the input expressions.
2778
2779        Returns:
2780            The modified Select expression.
2781        """
2782        return _apply_builder(
2783            expression=expression,
2784            instance=self,
2785            arg="from",
2786            into=From,
2787            prefix="FROM",
2788            dialect=dialect,
2789            copy=copy,
2790            **opts,
2791        )
2792
2793    def group_by(
2794        self,
2795        *expressions: t.Optional[ExpOrStr],
2796        append: bool = True,
2797        dialect: DialectType = None,
2798        copy: bool = True,
2799        **opts,
2800    ) -> Select:
2801        """
2802        Set the GROUP BY expression.
2803
2804        Example:
2805            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
2806            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
2807
2808        Args:
2809            *expressions: the SQL code strings to parse.
2810                If a `Group` instance is passed, this is used as-is.
2811                If another `Expression` instance is passed, it will be wrapped in a `Group`.
2812                If nothing is passed in then a group by is not applied to the expression
2813            append: if `True`, add to any existing expressions.
2814                Otherwise, this flattens all the `Group` expression into a single expression.
2815            dialect: the dialect used to parse the input expression.
2816            copy: if `False`, modify this expression instance in-place.
2817            opts: other options to use to parse the input expressions.
2818
2819        Returns:
2820            The modified Select expression.
2821        """
2822        if not expressions:
2823            return self if not copy else self.copy()
2824
2825        return _apply_child_list_builder(
2826            *expressions,
2827            instance=self,
2828            arg="group",
2829            append=append,
2830            copy=copy,
2831            prefix="GROUP BY",
2832            into=Group,
2833            dialect=dialect,
2834            **opts,
2835        )
2836
2837    def order_by(
2838        self,
2839        *expressions: t.Optional[ExpOrStr],
2840        append: bool = True,
2841        dialect: DialectType = None,
2842        copy: bool = True,
2843        **opts,
2844    ) -> Select:
2845        """
2846        Set the ORDER BY expression.
2847
2848        Example:
2849            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
2850            'SELECT x FROM tbl ORDER BY x DESC'
2851
2852        Args:
2853            *expressions: the SQL code strings to parse.
2854                If a `Group` instance is passed, this is used as-is.
2855                If another `Expression` instance is passed, it will be wrapped in a `Order`.
2856            append: if `True`, add to any existing expressions.
2857                Otherwise, this flattens all the `Order` expression into a single expression.
2858            dialect: the dialect used to parse the input expression.
2859            copy: if `False`, modify this expression instance in-place.
2860            opts: other options to use to parse the input expressions.
2861
2862        Returns:
2863            The modified Select expression.
2864        """
2865        return _apply_child_list_builder(
2866            *expressions,
2867            instance=self,
2868            arg="order",
2869            append=append,
2870            copy=copy,
2871            prefix="ORDER BY",
2872            into=Order,
2873            dialect=dialect,
2874            **opts,
2875        )
2876
2877    def sort_by(
2878        self,
2879        *expressions: t.Optional[ExpOrStr],
2880        append: bool = True,
2881        dialect: DialectType = None,
2882        copy: bool = True,
2883        **opts,
2884    ) -> Select:
2885        """
2886        Set the SORT BY expression.
2887
2888        Example:
2889            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
2890            'SELECT x FROM tbl SORT BY x DESC'
2891
2892        Args:
2893            *expressions: the SQL code strings to parse.
2894                If a `Group` instance is passed, this is used as-is.
2895                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
2896            append: if `True`, add to any existing expressions.
2897                Otherwise, this flattens all the `Order` expression into a single expression.
2898            dialect: the dialect used to parse the input expression.
2899            copy: if `False`, modify this expression instance in-place.
2900            opts: other options to use to parse the input expressions.
2901
2902        Returns:
2903            The modified Select expression.
2904        """
2905        return _apply_child_list_builder(
2906            *expressions,
2907            instance=self,
2908            arg="sort",
2909            append=append,
2910            copy=copy,
2911            prefix="SORT BY",
2912            into=Sort,
2913            dialect=dialect,
2914            **opts,
2915        )
2916
2917    def cluster_by(
2918        self,
2919        *expressions: t.Optional[ExpOrStr],
2920        append: bool = True,
2921        dialect: DialectType = None,
2922        copy: bool = True,
2923        **opts,
2924    ) -> Select:
2925        """
2926        Set the CLUSTER BY expression.
2927
2928        Example:
2929            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2930            'SELECT x FROM tbl CLUSTER BY x DESC'
2931
2932        Args:
2933            *expressions: the SQL code strings to parse.
2934                If a `Group` instance is passed, this is used as-is.
2935                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2936            append: if `True`, add to any existing expressions.
2937                Otherwise, this flattens all the `Order` expression into a single expression.
2938            dialect: the dialect used to parse the input expression.
2939            copy: if `False`, modify this expression instance in-place.
2940            opts: other options to use to parse the input expressions.
2941
2942        Returns:
2943            The modified Select expression.
2944        """
2945        return _apply_child_list_builder(
2946            *expressions,
2947            instance=self,
2948            arg="cluster",
2949            append=append,
2950            copy=copy,
2951            prefix="CLUSTER BY",
2952            into=Cluster,
2953            dialect=dialect,
2954            **opts,
2955        )
2956
2957    def limit(
2958        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2959    ) -> Select:
2960        """
2961        Set the LIMIT expression.
2962
2963        Example:
2964            >>> Select().from_("tbl").select("x").limit(10).sql()
2965            'SELECT x FROM tbl LIMIT 10'
2966
2967        Args:
2968            expression: the SQL code string to parse.
2969                This can also be an integer.
2970                If a `Limit` instance is passed, this is used as-is.
2971                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
2972            dialect: the dialect used to parse the input expression.
2973            copy: if `False`, modify this expression instance in-place.
2974            opts: other options to use to parse the input expressions.
2975
2976        Returns:
2977            Select: the modified expression.
2978        """
2979        return _apply_builder(
2980            expression=expression,
2981            instance=self,
2982            arg="limit",
2983            into=Limit,
2984            prefix="LIMIT",
2985            dialect=dialect,
2986            copy=copy,
2987            into_arg="expression",
2988            **opts,
2989        )
2990
2991    def offset(
2992        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2993    ) -> Select:
2994        """
2995        Set the OFFSET expression.
2996
2997        Example:
2998            >>> Select().from_("tbl").select("x").offset(10).sql()
2999            'SELECT x FROM tbl OFFSET 10'
3000
3001        Args:
3002            expression: the SQL code string to parse.
3003                This can also be an integer.
3004                If a `Offset` instance is passed, this is used as-is.
3005                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3006            dialect: the dialect used to parse the input expression.
3007            copy: if `False`, modify this expression instance in-place.
3008            opts: other options to use to parse the input expressions.
3009
3010        Returns:
3011            The modified Select expression.
3012        """
3013        return _apply_builder(
3014            expression=expression,
3015            instance=self,
3016            arg="offset",
3017            into=Offset,
3018            prefix="OFFSET",
3019            dialect=dialect,
3020            copy=copy,
3021            into_arg="expression",
3022            **opts,
3023        )
3024
3025    def select(
3026        self,
3027        *expressions: t.Optional[ExpOrStr],
3028        append: bool = True,
3029        dialect: DialectType = None,
3030        copy: bool = True,
3031        **opts,
3032    ) -> Select:
3033        """
3034        Append to or set the SELECT expressions.
3035
3036        Example:
3037            >>> Select().select("x", "y").sql()
3038            'SELECT x, y'
3039
3040        Args:
3041            *expressions: the SQL code strings to parse.
3042                If an `Expression` instance is passed, it will be used as-is.
3043            append: if `True`, add to any existing expressions.
3044                Otherwise, this resets the expressions.
3045            dialect: the dialect used to parse the input expressions.
3046            copy: if `False`, modify this expression instance in-place.
3047            opts: other options to use to parse the input expressions.
3048
3049        Returns:
3050            The modified Select expression.
3051        """
3052        return _apply_list_builder(
3053            *expressions,
3054            instance=self,
3055            arg="expressions",
3056            append=append,
3057            dialect=dialect,
3058            copy=copy,
3059            **opts,
3060        )
3061
3062    def lateral(
3063        self,
3064        *expressions: t.Optional[ExpOrStr],
3065        append: bool = True,
3066        dialect: DialectType = None,
3067        copy: bool = True,
3068        **opts,
3069    ) -> Select:
3070        """
3071        Append to or set the LATERAL expressions.
3072
3073        Example:
3074            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3075            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3076
3077        Args:
3078            *expressions: the SQL code strings to parse.
3079                If an `Expression` instance is passed, it will be used as-is.
3080            append: if `True`, add to any existing expressions.
3081                Otherwise, this resets the expressions.
3082            dialect: the dialect used to parse the input expressions.
3083            copy: if `False`, modify this expression instance in-place.
3084            opts: other options to use to parse the input expressions.
3085
3086        Returns:
3087            The modified Select expression.
3088        """
3089        return _apply_list_builder(
3090            *expressions,
3091            instance=self,
3092            arg="laterals",
3093            append=append,
3094            into=Lateral,
3095            prefix="LATERAL VIEW",
3096            dialect=dialect,
3097            copy=copy,
3098            **opts,
3099        )
3100
3101    def join(
3102        self,
3103        expression: ExpOrStr,
3104        on: t.Optional[ExpOrStr] = None,
3105        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3106        append: bool = True,
3107        join_type: t.Optional[str] = None,
3108        join_alias: t.Optional[Identifier | str] = None,
3109        dialect: DialectType = None,
3110        copy: bool = True,
3111        **opts,
3112    ) -> Select:
3113        """
3114        Append to or set the JOIN expressions.
3115
3116        Example:
3117            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3118            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3119
3120            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3121            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3122
3123            Use `join_type` to change the type of join:
3124
3125            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3126            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3127
3128        Args:
3129            expression: the SQL code string to parse.
3130                If an `Expression` instance is passed, it will be used as-is.
3131            on: optionally specify the join "on" criteria as a SQL string.
3132                If an `Expression` instance is passed, it will be used as-is.
3133            using: optionally specify the join "using" criteria as a SQL string.
3134                If an `Expression` instance is passed, it will be used as-is.
3135            append: if `True`, add to any existing expressions.
3136                Otherwise, this resets the expressions.
3137            join_type: if set, alter the parsed join type.
3138            join_alias: an optional alias for the joined source.
3139            dialect: the dialect used to parse the input expressions.
3140            copy: if `False`, modify this expression instance in-place.
3141            opts: other options to use to parse the input expressions.
3142
3143        Returns:
3144            Select: the modified expression.
3145        """
3146        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3147
3148        try:
3149            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3150        except ParseError:
3151            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3152
3153        join = expression if isinstance(expression, Join) else Join(this=expression)
3154
3155        if isinstance(join.this, Select):
3156            join.this.replace(join.this.subquery())
3157
3158        if join_type:
3159            method: t.Optional[Token]
3160            side: t.Optional[Token]
3161            kind: t.Optional[Token]
3162
3163            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3164
3165            if method:
3166                join.set("method", method.text)
3167            if side:
3168                join.set("side", side.text)
3169            if kind:
3170                join.set("kind", kind.text)
3171
3172        if on:
3173            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3174            join.set("on", on)
3175
3176        if using:
3177            join = _apply_list_builder(
3178                *ensure_list(using),
3179                instance=join,
3180                arg="using",
3181                append=append,
3182                copy=copy,
3183                into=Identifier,
3184                **opts,
3185            )
3186
3187        if join_alias:
3188            join.set("this", alias_(join.this, join_alias, table=True))
3189
3190        return _apply_list_builder(
3191            join,
3192            instance=self,
3193            arg="joins",
3194            append=append,
3195            copy=copy,
3196            **opts,
3197        )
3198
3199    def where(
3200        self,
3201        *expressions: t.Optional[ExpOrStr],
3202        append: bool = True,
3203        dialect: DialectType = None,
3204        copy: bool = True,
3205        **opts,
3206    ) -> Select:
3207        """
3208        Append to or set the WHERE expressions.
3209
3210        Example:
3211            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3212            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3213
3214        Args:
3215            *expressions: the SQL code strings to parse.
3216                If an `Expression` instance is passed, it will be used as-is.
3217                Multiple expressions are combined with an AND operator.
3218            append: if `True`, AND the new expressions to any existing expression.
3219                Otherwise, this resets the expression.
3220            dialect: the dialect used to parse the input expressions.
3221            copy: if `False`, modify this expression instance in-place.
3222            opts: other options to use to parse the input expressions.
3223
3224        Returns:
3225            Select: the modified expression.
3226        """
3227        return _apply_conjunction_builder(
3228            *expressions,
3229            instance=self,
3230            arg="where",
3231            append=append,
3232            into=Where,
3233            dialect=dialect,
3234            copy=copy,
3235            **opts,
3236        )
3237
3238    def having(
3239        self,
3240        *expressions: t.Optional[ExpOrStr],
3241        append: bool = True,
3242        dialect: DialectType = None,
3243        copy: bool = True,
3244        **opts,
3245    ) -> Select:
3246        """
3247        Append to or set the HAVING expressions.
3248
3249        Example:
3250            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3251            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3252
3253        Args:
3254            *expressions: the SQL code strings to parse.
3255                If an `Expression` instance is passed, it will be used as-is.
3256                Multiple expressions are combined with an AND operator.
3257            append: if `True`, AND the new expressions to any existing expression.
3258                Otherwise, this resets the expression.
3259            dialect: the dialect used to parse the input expressions.
3260            copy: if `False`, modify this expression instance in-place.
3261            opts: other options to use to parse the input expressions.
3262
3263        Returns:
3264            The modified Select expression.
3265        """
3266        return _apply_conjunction_builder(
3267            *expressions,
3268            instance=self,
3269            arg="having",
3270            append=append,
3271            into=Having,
3272            dialect=dialect,
3273            copy=copy,
3274            **opts,
3275        )
3276
3277    def window(
3278        self,
3279        *expressions: t.Optional[ExpOrStr],
3280        append: bool = True,
3281        dialect: DialectType = None,
3282        copy: bool = True,
3283        **opts,
3284    ) -> Select:
3285        return _apply_list_builder(
3286            *expressions,
3287            instance=self,
3288            arg="windows",
3289            append=append,
3290            into=Window,
3291            dialect=dialect,
3292            copy=copy,
3293            **opts,
3294        )
3295
3296    def qualify(
3297        self,
3298        *expressions: t.Optional[ExpOrStr],
3299        append: bool = True,
3300        dialect: DialectType = None,
3301        copy: bool = True,
3302        **opts,
3303    ) -> Select:
3304        return _apply_conjunction_builder(
3305            *expressions,
3306            instance=self,
3307            arg="qualify",
3308            append=append,
3309            into=Qualify,
3310            dialect=dialect,
3311            copy=copy,
3312            **opts,
3313        )
3314
3315    def distinct(
3316        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3317    ) -> Select:
3318        """
3319        Set the OFFSET expression.
3320
3321        Example:
3322            >>> Select().from_("tbl").select("x").distinct().sql()
3323            'SELECT DISTINCT x FROM tbl'
3324
3325        Args:
3326            ons: the expressions to distinct on
3327            distinct: whether the Select should be distinct
3328            copy: if `False`, modify this expression instance in-place.
3329
3330        Returns:
3331            Select: the modified expression.
3332        """
3333        instance = maybe_copy(self, copy)
3334        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3335        instance.set("distinct", Distinct(on=on) if distinct else None)
3336        return instance
3337
3338    def ctas(
3339        self,
3340        table: ExpOrStr,
3341        properties: t.Optional[t.Dict] = None,
3342        dialect: DialectType = None,
3343        copy: bool = True,
3344        **opts,
3345    ) -> Create:
3346        """
3347        Convert this expression to a CREATE TABLE AS statement.
3348
3349        Example:
3350            >>> Select().select("*").from_("tbl").ctas("x").sql()
3351            'CREATE TABLE x AS SELECT * FROM tbl'
3352
3353        Args:
3354            table: the SQL code string to parse as the table name.
3355                If another `Expression` instance is passed, it will be used as-is.
3356            properties: an optional mapping of table properties
3357            dialect: the dialect used to parse the input table.
3358            copy: if `False`, modify this expression instance in-place.
3359            opts: other options to use to parse the input table.
3360
3361        Returns:
3362            The new Create expression.
3363        """
3364        instance = maybe_copy(self, copy)
3365        table_expression = maybe_parse(
3366            table,
3367            into=Table,
3368            dialect=dialect,
3369            **opts,
3370        )
3371        properties_expression = None
3372        if properties:
3373            properties_expression = Properties.from_dict(properties)
3374
3375        return Create(
3376            this=table_expression,
3377            kind="TABLE",
3378            expression=instance,
3379            properties=properties_expression,
3380        )
3381
3382    def lock(self, update: bool = True, copy: bool = True) -> Select:
3383        """
3384        Set the locking read mode for this expression.
3385
3386        Examples:
3387            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3388            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3389
3390            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3391            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3392
3393        Args:
3394            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3395            copy: if `False`, modify this expression instance in-place.
3396
3397        Returns:
3398            The modified expression.
3399        """
3400        inst = maybe_copy(self, copy)
3401        inst.set("locks", [Lock(update=update)])
3402
3403        return inst
3404
3405    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3406        """
3407        Set hints for this expression.
3408
3409        Examples:
3410            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3411            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3412
3413        Args:
3414            hints: The SQL code strings to parse as the hints.
3415                If an `Expression` instance is passed, it will be used as-is.
3416            dialect: The dialect used to parse the hints.
3417            copy: If `False`, modify this expression instance in-place.
3418
3419        Returns:
3420            The modified expression.
3421        """
3422        inst = maybe_copy(self, copy)
3423        inst.set(
3424            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3425        )
3426
3427        return inst
3428
3429    @property
3430    def named_selects(self) -> t.List[str]:
3431        return [e.output_name for e in self.expressions if e.alias_or_name]
3432
3433    @property
3434    def is_star(self) -> bool:
3435        return any(expression.is_star for expression in self.expressions)
3436
3437    @property
3438    def selects(self) -> t.List[Expression]:
3439        return self.expressions
3440
3441
3442class Subquery(DerivedTable, Unionable):
3443    arg_types = {
3444        "this": True,
3445        "alias": False,
3446        "with": False,
3447        **QUERY_MODIFIERS,
3448    }
3449
3450    def unnest(self):
3451        """
3452        Returns the first non subquery.
3453        """
3454        expression = self
3455        while isinstance(expression, Subquery):
3456            expression = expression.this
3457        return expression
3458
3459    def unwrap(self) -> Subquery:
3460        expression = self
3461        while expression.same_parent and expression.is_wrapper:
3462            expression = t.cast(Subquery, expression.parent)
3463        return expression
3464
3465    @property
3466    def is_wrapper(self) -> bool:
3467        """
3468        Whether this Subquery acts as a simple wrapper around another expression.
3469
3470        SELECT * FROM (((SELECT * FROM t)))
3471                      ^
3472                      This corresponds to a "wrapper" Subquery node
3473        """
3474        return all(v is None for k, v in self.args.items() if k != "this")
3475
3476    @property
3477    def is_star(self) -> bool:
3478        return self.this.is_star
3479
3480    @property
3481    def output_name(self) -> str:
3482        return self.alias
3483
3484
3485class TableSample(Expression):
3486    arg_types = {
3487        "this": False,
3488        "expressions": False,
3489        "method": False,
3490        "bucket_numerator": False,
3491        "bucket_denominator": False,
3492        "bucket_field": False,
3493        "percent": False,
3494        "rows": False,
3495        "size": False,
3496        "seed": False,
3497    }
3498
3499
3500class Tag(Expression):
3501    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3502
3503    arg_types = {
3504        "this": False,
3505        "prefix": False,
3506        "postfix": False,
3507    }
3508
3509
3510# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax
3511# https://duckdb.org/docs/sql/statements/pivot
3512class Pivot(Expression):
3513    arg_types = {
3514        "this": False,
3515        "alias": False,
3516        "expressions": False,
3517        "field": False,
3518        "unpivot": False,
3519        "using": False,
3520        "group": False,
3521        "columns": False,
3522        "include_nulls": False,
3523    }
3524
3525
3526class Window(Condition):
3527    arg_types = {
3528        "this": True,
3529        "partition_by": False,
3530        "order": False,
3531        "spec": False,
3532        "alias": False,
3533        "over": False,
3534        "first": False,
3535    }
3536
3537
3538class WindowSpec(Expression):
3539    arg_types = {
3540        "kind": False,
3541        "start": False,
3542        "start_side": False,
3543        "end": False,
3544        "end_side": False,
3545    }
3546
3547
3548class Where(Expression):
3549    pass
3550
3551
3552class Star(Expression):
3553    arg_types = {"except": False, "replace": False}
3554
3555    @property
3556    def name(self) -> str:
3557        return "*"
3558
3559    @property
3560    def output_name(self) -> str:
3561        return self.name
3562
3563
3564class Parameter(Condition):
3565    arg_types = {"this": True, "expression": False}
3566
3567
3568class SessionParameter(Condition):
3569    arg_types = {"this": True, "kind": False}
3570
3571
3572class Placeholder(Condition):
3573    arg_types = {"this": False, "kind": False}
3574
3575
3576class Null(Condition):
3577    arg_types: t.Dict[str, t.Any] = {}
3578
3579    @property
3580    def name(self) -> str:
3581        return "NULL"
3582
3583
3584class Boolean(Condition):
3585    pass
3586
3587
3588class DataTypeParam(Expression):
3589    arg_types = {"this": True, "expression": False}
3590
3591
3592class DataType(Expression):
3593    arg_types = {
3594        "this": True,
3595        "expressions": False,
3596        "nested": False,
3597        "values": False,
3598        "prefix": False,
3599        "kind": False,
3600    }
3601
3602    class Type(AutoName):
3603        ARRAY = auto()
3604        BIGDECIMAL = auto()
3605        BIGINT = auto()
3606        BIGSERIAL = auto()
3607        BINARY = auto()
3608        BIT = auto()
3609        BOOLEAN = auto()
3610        CHAR = auto()
3611        DATE = auto()
3612        DATEMULTIRANGE = auto()
3613        DATERANGE = auto()
3614        DATETIME = auto()
3615        DATETIME64 = auto()
3616        DECIMAL = auto()
3617        DOUBLE = auto()
3618        ENUM = auto()
3619        ENUM8 = auto()
3620        ENUM16 = auto()
3621        FIXEDSTRING = auto()
3622        FLOAT = auto()
3623        GEOGRAPHY = auto()
3624        GEOMETRY = auto()
3625        HLLSKETCH = auto()
3626        HSTORE = auto()
3627        IMAGE = auto()
3628        INET = auto()
3629        INT = auto()
3630        INT128 = auto()
3631        INT256 = auto()
3632        INT4MULTIRANGE = auto()
3633        INT4RANGE = auto()
3634        INT8MULTIRANGE = auto()
3635        INT8RANGE = auto()
3636        INTERVAL = auto()
3637        IPADDRESS = auto()
3638        IPPREFIX = auto()
3639        JSON = auto()
3640        JSONB = auto()
3641        LONGBLOB = auto()
3642        LONGTEXT = auto()
3643        LOWCARDINALITY = auto()
3644        MAP = auto()
3645        MEDIUMBLOB = auto()
3646        MEDIUMINT = auto()
3647        MEDIUMTEXT = auto()
3648        MONEY = auto()
3649        NCHAR = auto()
3650        NESTED = auto()
3651        NULL = auto()
3652        NULLABLE = auto()
3653        NUMMULTIRANGE = auto()
3654        NUMRANGE = auto()
3655        NVARCHAR = auto()
3656        OBJECT = auto()
3657        ROWVERSION = auto()
3658        SERIAL = auto()
3659        SET = auto()
3660        SMALLINT = auto()
3661        SMALLMONEY = auto()
3662        SMALLSERIAL = auto()
3663        STRUCT = auto()
3664        SUPER = auto()
3665        TEXT = auto()
3666        TINYBLOB = auto()
3667        TINYTEXT = auto()
3668        TIME = auto()
3669        TIMETZ = auto()
3670        TIMESTAMP = auto()
3671        TIMESTAMPLTZ = auto()
3672        TIMESTAMPTZ = auto()
3673        TIMESTAMP_S = auto()
3674        TIMESTAMP_MS = auto()
3675        TIMESTAMP_NS = auto()
3676        TINYINT = auto()
3677        TSMULTIRANGE = auto()
3678        TSRANGE = auto()
3679        TSTZMULTIRANGE = auto()
3680        TSTZRANGE = auto()
3681        UBIGINT = auto()
3682        UINT = auto()
3683        UINT128 = auto()
3684        UINT256 = auto()
3685        UMEDIUMINT = auto()
3686        UDECIMAL = auto()
3687        UNIQUEIDENTIFIER = auto()
3688        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3689        USERDEFINED = "USER-DEFINED"
3690        USMALLINT = auto()
3691        UTINYINT = auto()
3692        UUID = auto()
3693        VARBINARY = auto()
3694        VARCHAR = auto()
3695        VARIANT = auto()
3696        XML = auto()
3697        YEAR = auto()
3698
3699    TEXT_TYPES = {
3700        Type.CHAR,
3701        Type.NCHAR,
3702        Type.VARCHAR,
3703        Type.NVARCHAR,
3704        Type.TEXT,
3705    }
3706
3707    INTEGER_TYPES = {
3708        Type.INT,
3709        Type.TINYINT,
3710        Type.SMALLINT,
3711        Type.BIGINT,
3712        Type.INT128,
3713        Type.INT256,
3714        Type.BIT,
3715    }
3716
3717    FLOAT_TYPES = {
3718        Type.FLOAT,
3719        Type.DOUBLE,
3720    }
3721
3722    NUMERIC_TYPES = {
3723        *INTEGER_TYPES,
3724        *FLOAT_TYPES,
3725    }
3726
3727    TEMPORAL_TYPES = {
3728        Type.TIME,
3729        Type.TIMETZ,
3730        Type.TIMESTAMP,
3731        Type.TIMESTAMPTZ,
3732        Type.TIMESTAMPLTZ,
3733        Type.TIMESTAMP_S,
3734        Type.TIMESTAMP_MS,
3735        Type.TIMESTAMP_NS,
3736        Type.DATE,
3737        Type.DATETIME,
3738        Type.DATETIME64,
3739    }
3740
3741    @classmethod
3742    def build(
3743        cls,
3744        dtype: DATA_TYPE,
3745        dialect: DialectType = None,
3746        udt: bool = False,
3747        **kwargs,
3748    ) -> DataType:
3749        """
3750        Constructs a DataType object.
3751
3752        Args:
3753            dtype: the data type of interest.
3754            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3755            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3756                DataType, thus creating a user-defined type.
3757            kawrgs: additional arguments to pass in the constructor of DataType.
3758
3759        Returns:
3760            The constructed DataType object.
3761        """
3762        from sqlglot import parse_one
3763
3764        if isinstance(dtype, str):
3765            if dtype.upper() == "UNKNOWN":
3766                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3767
3768            try:
3769                data_type_exp = parse_one(
3770                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3771                )
3772            except ParseError:
3773                if udt:
3774                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3775                raise
3776        elif isinstance(dtype, DataType.Type):
3777            data_type_exp = DataType(this=dtype)
3778        elif isinstance(dtype, DataType):
3779            return dtype
3780        else:
3781            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3782
3783        return DataType(**{**data_type_exp.args, **kwargs})
3784
3785    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3786        """
3787        Checks whether this DataType matches one of the provided data types. Nested types or precision
3788        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3789
3790        Args:
3791            dtypes: the data types to compare this DataType to.
3792
3793        Returns:
3794            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3795        """
3796        for dtype in dtypes:
3797            other = DataType.build(dtype, udt=True)
3798
3799            if (
3800                other.expressions
3801                or self.this == DataType.Type.USERDEFINED
3802                or other.this == DataType.Type.USERDEFINED
3803            ):
3804                matches = self == other
3805            else:
3806                matches = self.this == other.this
3807
3808            if matches:
3809                return True
3810        return False
3811
3812
3813DATA_TYPE = t.Union[str, DataType, DataType.Type]
3814
3815
3816# https://www.postgresql.org/docs/15/datatype-pseudo.html
3817class PseudoType(DataType):
3818    arg_types = {"this": True}
3819
3820
3821# https://www.postgresql.org/docs/15/datatype-oid.html
3822class ObjectIdentifier(DataType):
3823    arg_types = {"this": True}
3824
3825
3826# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
3827class SubqueryPredicate(Predicate):
3828    pass
3829
3830
3831class All(SubqueryPredicate):
3832    pass
3833
3834
3835class Any(SubqueryPredicate):
3836    pass
3837
3838
3839class Exists(SubqueryPredicate):
3840    pass
3841
3842
3843# Commands to interact with the databases or engines. For most of the command
3844# expressions we parse whatever comes after the command's name as a string.
3845class Command(Expression):
3846    arg_types = {"this": True, "expression": False}
3847
3848
3849class Transaction(Expression):
3850    arg_types = {"this": False, "modes": False, "mark": False}
3851
3852
3853class Commit(Expression):
3854    arg_types = {"chain": False, "this": False, "durability": False}
3855
3856
3857class Rollback(Expression):
3858    arg_types = {"savepoint": False, "this": False}
3859
3860
3861class AlterTable(Expression):
3862    arg_types = {"this": True, "actions": True, "exists": False, "only": False}
3863
3864
3865class AddConstraint(Expression):
3866    arg_types = {"this": False, "expression": False, "enforced": False}
3867
3868
3869class DropPartition(Expression):
3870    arg_types = {"expressions": True, "exists": False}
3871
3872
3873# Binary expressions like (ADD a b)
3874class Binary(Condition):
3875    arg_types = {"this": True, "expression": True}
3876
3877    @property
3878    def left(self) -> Expression:
3879        return self.this
3880
3881    @property
3882    def right(self) -> Expression:
3883        return self.expression
3884
3885
3886class Add(Binary):
3887    pass
3888
3889
3890class Connector(Binary):
3891    pass
3892
3893
3894class And(Connector):
3895    pass
3896
3897
3898class Or(Connector):
3899    pass
3900
3901
3902class BitwiseAnd(Binary):
3903    pass
3904
3905
3906class BitwiseLeftShift(Binary):
3907    pass
3908
3909
3910class BitwiseOr(Binary):
3911    pass
3912
3913
3914class BitwiseRightShift(Binary):
3915    pass
3916
3917
3918class BitwiseXor(Binary):
3919    pass
3920
3921
3922class Div(Binary):
3923    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
3924
3925
3926class Overlaps(Binary):
3927    pass
3928
3929
3930class Dot(Binary):
3931    @property
3932    def name(self) -> str:
3933        return self.expression.name
3934
3935    @property
3936    def output_name(self) -> str:
3937        return self.name
3938
3939    @classmethod
3940    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3941        """Build a Dot object with a sequence of expressions."""
3942        if len(expressions) < 2:
3943            raise ValueError(f"Dot requires >= 2 expressions.")
3944
3945        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
3946
3947    @property
3948    def parts(self) -> t.List[Expression]:
3949        """Return the parts of a table / column in order catalog, db, table."""
3950        this, *parts = self.flatten()
3951
3952        parts.reverse()
3953
3954        for arg in ("this", "table", "db", "catalog"):
3955            part = this.args.get(arg)
3956
3957            if isinstance(part, Expression):
3958                parts.append(part)
3959
3960        parts.reverse()
3961        return parts
3962
3963
3964class DPipe(Binary):
3965    arg_types = {"this": True, "expression": True, "safe": False}
3966
3967
3968class EQ(Binary, Predicate):
3969    pass
3970
3971
3972class NullSafeEQ(Binary, Predicate):
3973    pass
3974
3975
3976class NullSafeNEQ(Binary, Predicate):
3977    pass
3978
3979
3980# Represents e.g. := in DuckDB which is mostly used for setting parameters
3981class PropertyEQ(Binary):
3982    pass
3983
3984
3985class Distance(Binary):
3986    pass
3987
3988
3989class Escape(Binary):
3990    pass
3991
3992
3993class Glob(Binary, Predicate):
3994    pass
3995
3996
3997class GT(Binary, Predicate):
3998    pass
3999
4000
4001class GTE(Binary, Predicate):
4002    pass
4003
4004
4005class ILike(Binary, Predicate):
4006    pass
4007
4008
4009class ILikeAny(Binary, Predicate):
4010    pass
4011
4012
4013class IntDiv(Binary):
4014    pass
4015
4016
4017class Is(Binary, Predicate):
4018    pass
4019
4020
4021class Kwarg(Binary):
4022    """Kwarg in special functions like func(kwarg => y)."""
4023
4024
4025class Like(Binary, Predicate):
4026    pass
4027
4028
4029class LikeAny(Binary, Predicate):
4030    pass
4031
4032
4033class LT(Binary, Predicate):
4034    pass
4035
4036
4037class LTE(Binary, Predicate):
4038    pass
4039
4040
4041class Mod(Binary):
4042    pass
4043
4044
4045class Mul(Binary):
4046    pass
4047
4048
4049class NEQ(Binary, Predicate):
4050    pass
4051
4052
4053# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
4054class Operator(Binary):
4055    arg_types = {"this": True, "operator": True, "expression": True}
4056
4057
4058class SimilarTo(Binary, Predicate):
4059    pass
4060
4061
4062class Slice(Binary):
4063    arg_types = {"this": False, "expression": False}
4064
4065
4066class Sub(Binary):
4067    pass
4068
4069
4070class ArrayOverlaps(Binary):
4071    pass
4072
4073
4074# Unary Expressions
4075# (NOT a)
4076class Unary(Condition):
4077    pass
4078
4079
4080class BitwiseNot(Unary):
4081    pass
4082
4083
4084class Not(Unary):
4085    pass
4086
4087
4088class Paren(Unary):
4089    arg_types = {"this": True, "with": False}
4090
4091    @property
4092    def output_name(self) -> str:
4093        return self.this.name
4094
4095
4096class Neg(Unary):
4097    pass
4098
4099
4100class Alias(Expression):
4101    arg_types = {"this": True, "alias": False}
4102
4103    @property
4104    def output_name(self) -> str:
4105        return self.alias
4106
4107
4108class Aliases(Expression):
4109    arg_types = {"this": True, "expressions": True}
4110
4111    @property
4112    def aliases(self):
4113        return self.expressions
4114
4115
4116# https://docs.aws.amazon.com/redshift/latest/dg/query-super.html
4117class AtIndex(Expression):
4118    arg_types = {"this": True, "expression": True}
4119
4120
4121class AtTimeZone(Expression):
4122    arg_types = {"this": True, "zone": True}
4123
4124
4125class Between(Predicate):
4126    arg_types = {"this": True, "low": True, "high": True}
4127
4128
4129class Bracket(Condition):
4130    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4131    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4132
4133    @property
4134    def output_name(self) -> str:
4135        if len(self.expressions) == 1:
4136            return self.expressions[0].output_name
4137
4138        return super().output_name
4139
4140
4141class Distinct(Expression):
4142    arg_types = {"expressions": False, "on": False}
4143
4144
4145class In(Predicate):
4146    arg_types = {
4147        "this": True,
4148        "expressions": False,
4149        "query": False,
4150        "unnest": False,
4151        "field": False,
4152        "is_global": False,
4153    }
4154
4155
4156# https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#for-in
4157class ForIn(Expression):
4158    arg_types = {"this": True, "expression": True}
4159
4160
4161class TimeUnit(Expression):
4162    """Automatically converts unit arg into a var."""
4163
4164    arg_types = {"unit": False}
4165
4166    UNABBREVIATED_UNIT_NAME = {
4167        "D": "DAY",
4168        "H": "HOUR",
4169        "M": "MINUTE",
4170        "MS": "MILLISECOND",
4171        "NS": "NANOSECOND",
4172        "Q": "QUARTER",
4173        "S": "SECOND",
4174        "US": "MICROSECOND",
4175        "W": "WEEK",
4176        "Y": "YEAR",
4177    }
4178
4179    VAR_LIKE = (Column, Literal, Var)
4180
4181    def __init__(self, **args):
4182        unit = args.get("unit")
4183        if isinstance(unit, self.VAR_LIKE):
4184            args["unit"] = Var(
4185                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4186            )
4187        elif isinstance(unit, Week):
4188            unit.set("this", Var(this=unit.this.name.upper()))
4189
4190        super().__init__(**args)
4191
4192    @property
4193    def unit(self) -> t.Optional[Var]:
4194        return self.args.get("unit")
4195
4196
4197class IntervalOp(TimeUnit):
4198    arg_types = {"unit": True, "expression": True}
4199
4200    def interval(self):
4201        return Interval(
4202            this=self.expression.copy(),
4203            unit=self.unit.copy(),
4204        )
4205
4206
4207# https://www.oracletutorial.com/oracle-basics/oracle-interval/
4208# https://trino.io/docs/current/language/types.html#interval-day-to-second
4209# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
4210class IntervalSpan(DataType):
4211    arg_types = {"this": True, "expression": True}
4212
4213
4214class Interval(TimeUnit):
4215    arg_types = {"this": False, "unit": False}
4216
4217
4218class IgnoreNulls(Expression):
4219    pass
4220
4221
4222class RespectNulls(Expression):
4223    pass
4224
4225
4226# Functions
4227class Func(Condition):
4228    """
4229    The base class for all function expressions.
4230
4231    Attributes:
4232        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4233            treated as a variable length argument and the argument's value will be stored as a list.
4234        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4235            for this function expression. These values are used to map this node to a name during parsing
4236            as well as to provide the function's name during SQL string generation. By default the SQL
4237            name is set to the expression's class name transformed to snake case.
4238    """
4239
4240    is_var_len_args = False
4241
4242    @classmethod
4243    def from_arg_list(cls, args):
4244        if cls.is_var_len_args:
4245            all_arg_keys = list(cls.arg_types)
4246            # If this function supports variable length argument treat the last argument as such.
4247            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4248            num_non_var = len(non_var_len_arg_keys)
4249
4250            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4251            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4252        else:
4253            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4254
4255        return cls(**args_dict)
4256
4257    @classmethod
4258    def sql_names(cls):
4259        if cls is Func:
4260            raise NotImplementedError(
4261                "SQL name is only supported by concrete function implementations"
4262            )
4263        if "_sql_names" not in cls.__dict__:
4264            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4265        return cls._sql_names
4266
4267    @classmethod
4268    def sql_name(cls):
4269        return cls.sql_names()[0]
4270
4271    @classmethod
4272    def default_parser_mappings(cls):
4273        return {name: cls.from_arg_list for name in cls.sql_names()}
4274
4275
4276class AggFunc(Func):
4277    pass
4278
4279
4280class ParameterizedAgg(AggFunc):
4281    arg_types = {"this": True, "expressions": True, "params": True}
4282
4283
4284class Abs(Func):
4285    pass
4286
4287
4288class ArgMax(AggFunc):
4289    arg_types = {"this": True, "expression": True, "count": False}
4290    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
4291
4292
4293class ArgMin(AggFunc):
4294    arg_types = {"this": True, "expression": True, "count": False}
4295    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
4296
4297
4298class ApproxTopK(AggFunc):
4299    arg_types = {"this": True, "expression": False, "counters": False}
4300
4301
4302class Flatten(Func):
4303    pass
4304
4305
4306# https://spark.apache.org/docs/latest/api/sql/index.html#transform
4307class Transform(Func):
4308    arg_types = {"this": True, "expression": True}
4309
4310
4311class Anonymous(Func):
4312    arg_types = {"this": True, "expressions": False}
4313    is_var_len_args = True
4314
4315
4316class AnonymousAggFunc(AggFunc):
4317    arg_types = {"this": True, "expressions": False}
4318    is_var_len_args = True
4319
4320
4321# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
4322class CombinedAggFunc(AnonymousAggFunc):
4323    arg_types = {"this": True, "expressions": False, "parts": True}
4324
4325
4326class CombinedParameterizedAgg(ParameterizedAgg):
4327    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
4328
4329
4330# https://docs.snowflake.com/en/sql-reference/functions/hll
4331# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
4332class Hll(AggFunc):
4333    arg_types = {"this": True, "expressions": False}
4334    is_var_len_args = True
4335
4336
4337class ApproxDistinct(AggFunc):
4338    arg_types = {"this": True, "accuracy": False}
4339    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
4340
4341
4342class Array(Func):
4343    arg_types = {"expressions": False}
4344    is_var_len_args = True
4345
4346
4347# https://docs.snowflake.com/en/sql-reference/functions/to_array
4348class ToArray(Func):
4349    pass
4350
4351
4352# https://docs.snowflake.com/en/sql-reference/functions/to_char
4353# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
4354class ToChar(Func):
4355    arg_types = {"this": True, "format": False, "nlsparam": False}
4356
4357
4358class GenerateSeries(Func):
4359    arg_types = {"start": True, "end": True, "step": False}
4360
4361
4362class ArrayAgg(AggFunc):
4363    pass
4364
4365
4366class ArrayUniqueAgg(AggFunc):
4367    pass
4368
4369
4370class ArrayAll(Func):
4371    arg_types = {"this": True, "expression": True}
4372
4373
4374class ArrayAny(Func):
4375    arg_types = {"this": True, "expression": True}
4376
4377
4378class ArrayConcat(Func):
4379    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4380    arg_types = {"this": True, "expressions": False}
4381    is_var_len_args = True
4382
4383
4384class ArrayContains(Binary, Func):
4385    pass
4386
4387
4388class ArrayContained(Binary):
4389    pass
4390
4391
4392class ArrayFilter(Func):
4393    arg_types = {"this": True, "expression": True}
4394    _sql_names = ["FILTER", "ARRAY_FILTER"]
4395
4396
4397class ArrayJoin(Func):
4398    arg_types = {"this": True, "expression": True, "null": False}
4399
4400
4401class ArraySize(Func):
4402    arg_types = {"this": True, "expression": False}
4403
4404
4405class ArraySort(Func):
4406    arg_types = {"this": True, "expression": False}
4407
4408
4409class ArraySum(Func):
4410    pass
4411
4412
4413class ArrayUnionAgg(AggFunc):
4414    pass
4415
4416
4417class Avg(AggFunc):
4418    pass
4419
4420
4421class AnyValue(AggFunc):
4422    arg_types = {"this": True, "having": False, "max": False, "ignore_nulls": False}
4423
4424
4425class First(Func):
4426    arg_types = {"this": True, "ignore_nulls": False}
4427
4428
4429class Last(Func):
4430    arg_types = {"this": True, "ignore_nulls": False}
4431
4432
4433class Case(Func):
4434    arg_types = {"this": False, "ifs": True, "default": False}
4435
4436    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4437        instance = maybe_copy(self, copy)
4438        instance.append(
4439            "ifs",
4440            If(
4441                this=maybe_parse(condition, copy=copy, **opts),
4442                true=maybe_parse(then, copy=copy, **opts),
4443            ),
4444        )
4445        return instance
4446
4447    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4448        instance = maybe_copy(self, copy)
4449        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4450        return instance
4451
4452
4453class Cast(Func):
4454    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4455
4456    @property
4457    def name(self) -> str:
4458        return self.this.name
4459
4460    @property
4461    def to(self) -> DataType:
4462        return self.args["to"]
4463
4464    @property
4465    def output_name(self) -> str:
4466        return self.name
4467
4468    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4469        """
4470        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4471        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4472        array<int> != array<float>.
4473
4474        Args:
4475            dtypes: the data types to compare this Cast's DataType to.
4476
4477        Returns:
4478            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4479        """
4480        return self.to.is_type(*dtypes)
4481
4482
4483class TryCast(Cast):
4484    pass
4485
4486
4487class CastToStrType(Func):
4488    arg_types = {"this": True, "to": True}
4489
4490
4491class Collate(Binary, Func):
4492    pass
4493
4494
4495class Ceil(Func):
4496    arg_types = {"this": True, "decimals": False}
4497    _sql_names = ["CEIL", "CEILING"]
4498
4499
4500class Coalesce(Func):
4501    arg_types = {"this": True, "expressions": False}
4502    is_var_len_args = True
4503    _sql_names = ["COALESCE", "IFNULL", "NVL"]
4504
4505
4506class Chr(Func):
4507    arg_types = {"this": True, "charset": False, "expressions": False}
4508    is_var_len_args = True
4509    _sql_names = ["CHR", "CHAR"]
4510
4511
4512class Concat(Func):
4513    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4514    is_var_len_args = True
4515
4516
4517class ConcatWs(Concat):
4518    _sql_names = ["CONCAT_WS"]
4519
4520
4521class Count(AggFunc):
4522    arg_types = {"this": False, "expressions": False}
4523    is_var_len_args = True
4524
4525
4526class CountIf(AggFunc):
4527    _sql_names = ["COUNT_IF", "COUNTIF"]
4528
4529
4530class CurrentDate(Func):
4531    arg_types = {"this": False}
4532
4533
4534class CurrentDatetime(Func):
4535    arg_types = {"this": False}
4536
4537
4538class CurrentTime(Func):
4539    arg_types = {"this": False}
4540
4541
4542class CurrentTimestamp(Func):
4543    arg_types = {"this": False}
4544
4545
4546class CurrentUser(Func):
4547    arg_types = {"this": False}
4548
4549
4550class DateAdd(Func, IntervalOp):
4551    arg_types = {"this": True, "expression": True, "unit": False}
4552
4553
4554class DateSub(Func, IntervalOp):
4555    arg_types = {"this": True, "expression": True, "unit": False}
4556
4557
4558class DateDiff(Func, TimeUnit):
4559    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4560    arg_types = {"this": True, "expression": True, "unit": False}
4561
4562
4563class DateTrunc(Func):
4564    arg_types = {"unit": True, "this": True, "zone": False}
4565
4566    def __init__(self, **args):
4567        unit = args.get("unit")
4568        if isinstance(unit, TimeUnit.VAR_LIKE):
4569            args["unit"] = Literal.string(
4570                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4571            )
4572        elif isinstance(unit, Week):
4573            unit.set("this", Literal.string(unit.this.name.upper()))
4574
4575        super().__init__(**args)
4576
4577    @property
4578    def unit(self) -> Expression:
4579        return self.args["unit"]
4580
4581
4582class DatetimeAdd(Func, IntervalOp):
4583    arg_types = {"this": True, "expression": True, "unit": False}
4584
4585
4586class DatetimeSub(Func, IntervalOp):
4587    arg_types = {"this": True, "expression": True, "unit": False}
4588
4589
4590class DatetimeDiff(Func, TimeUnit):
4591    arg_types = {"this": True, "expression": True, "unit": False}
4592
4593
4594class DatetimeTrunc(Func, TimeUnit):
4595    arg_types = {"this": True, "unit": True, "zone": False}
4596
4597
4598class DayOfWeek(Func):
4599    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
4600
4601
4602class DayOfMonth(Func):
4603    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
4604
4605
4606class DayOfYear(Func):
4607    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
4608
4609
4610class ToDays(Func):
4611    pass
4612
4613
4614class WeekOfYear(Func):
4615    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
4616
4617
4618class MonthsBetween(Func):
4619    arg_types = {"this": True, "expression": True, "roundoff": False}
4620
4621
4622class LastDay(Func, TimeUnit):
4623    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4624    arg_types = {"this": True, "unit": False}
4625
4626
4627class Extract(Func):
4628    arg_types = {"this": True, "expression": True}
4629
4630
4631class Timestamp(Func):
4632    arg_types = {"this": False, "expression": False}
4633
4634
4635class TimestampAdd(Func, TimeUnit):
4636    arg_types = {"this": True, "expression": True, "unit": False}
4637
4638
4639class TimestampSub(Func, TimeUnit):
4640    arg_types = {"this": True, "expression": True, "unit": False}
4641
4642
4643class TimestampDiff(Func, TimeUnit):
4644    arg_types = {"this": True, "expression": True, "unit": False}
4645
4646
4647class TimestampTrunc(Func, TimeUnit):
4648    arg_types = {"this": True, "unit": True, "zone": False}
4649
4650
4651class TimeAdd(Func, TimeUnit):
4652    arg_types = {"this": True, "expression": True, "unit": False}
4653
4654
4655class TimeSub(Func, TimeUnit):
4656    arg_types = {"this": True, "expression": True, "unit": False}
4657
4658
4659class TimeDiff(Func, TimeUnit):
4660    arg_types = {"this": True, "expression": True, "unit": False}
4661
4662
4663class TimeTrunc(Func, TimeUnit):
4664    arg_types = {"this": True, "unit": True, "zone": False}
4665
4666
4667class DateFromParts(Func):
4668    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4669    arg_types = {"year": True, "month": True, "day": True}
4670
4671
4672class TimeFromParts(Func):
4673    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4674    arg_types = {
4675        "hour": True,
4676        "min": True,
4677        "sec": True,
4678        "nano": False,
4679        "fractions": False,
4680        "precision": False,
4681    }
4682
4683
4684class DateStrToDate(Func):
4685    pass
4686
4687
4688class DateToDateStr(Func):
4689    pass
4690
4691
4692class DateToDi(Func):
4693    pass
4694
4695
4696# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
4697class Date(Func):
4698    arg_types = {"this": False, "zone": False, "expressions": False}
4699    is_var_len_args = True
4700
4701
4702class Day(Func):
4703    pass
4704
4705
4706class Decode(Func):
4707    arg_types = {"this": True, "charset": True, "replace": False}
4708
4709
4710class DiToDate(Func):
4711    pass
4712
4713
4714class Encode(Func):
4715    arg_types = {"this": True, "charset": True}
4716
4717
4718class Exp(Func):
4719    pass
4720
4721
4722# https://docs.snowflake.com/en/sql-reference/functions/flatten
4723class Explode(Func):
4724    arg_types = {"this": True, "expressions": False}
4725    is_var_len_args = True
4726
4727
4728class ExplodeOuter(Explode):
4729    pass
4730
4731
4732class Posexplode(Explode):
4733    pass
4734
4735
4736class PosexplodeOuter(Posexplode):
4737    pass
4738
4739
4740class Floor(Func):
4741    arg_types = {"this": True, "decimals": False}
4742
4743
4744class FromBase64(Func):
4745    pass
4746
4747
4748class ToBase64(Func):
4749    pass
4750
4751
4752class Greatest(Func):
4753    arg_types = {"this": True, "expressions": False}
4754    is_var_len_args = True
4755
4756
4757class GroupConcat(AggFunc):
4758    arg_types = {"this": True, "separator": False}
4759
4760
4761class Hex(Func):
4762    pass
4763
4764
4765class Xor(Connector, Func):
4766    arg_types = {"this": False, "expression": False, "expressions": False}
4767
4768
4769class If(Func):
4770    arg_types = {"this": True, "true": True, "false": False}
4771
4772
4773class Nullif(Func):
4774    arg_types = {"this": True, "expression": True}
4775
4776
4777class Initcap(Func):
4778    arg_types = {"this": True, "expression": False}
4779
4780
4781class IsNan(Func):
4782    _sql_names = ["IS_NAN", "ISNAN"]
4783
4784
4785class IsInf(Func):
4786    _sql_names = ["IS_INF", "ISINF"]
4787
4788
4789class FormatJson(Expression):
4790    pass
4791
4792
4793class JSONKeyValue(Expression):
4794    arg_types = {"this": True, "expression": True}
4795
4796
4797class JSONObject(Func):
4798    arg_types = {
4799        "expressions": False,
4800        "null_handling": False,
4801        "unique_keys": False,
4802        "return_type": False,
4803        "encoding": False,
4804    }
4805
4806
4807# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
4808class JSONArray(Func):
4809    arg_types = {
4810        "expressions": True,
4811        "null_handling": False,
4812        "return_type": False,
4813        "strict": False,
4814    }
4815
4816
4817# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
4818class JSONArrayAgg(Func):
4819    arg_types = {
4820        "this": True,
4821        "order": False,
4822        "null_handling": False,
4823        "return_type": False,
4824        "strict": False,
4825    }
4826
4827
4828# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4829# Note: parsing of JSON column definitions is currently incomplete.
4830class JSONColumnDef(Expression):
4831    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
4832
4833
4834class JSONSchema(Expression):
4835    arg_types = {"expressions": True}
4836
4837
4838# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
4839class JSONTable(Func):
4840    arg_types = {
4841        "this": True,
4842        "schema": True,
4843        "path": False,
4844        "error_handling": False,
4845        "empty_handling": False,
4846    }
4847
4848
4849class OpenJSONColumnDef(Expression):
4850    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
4851
4852
4853class OpenJSON(Func):
4854    arg_types = {"this": True, "path": False, "expressions": False}
4855
4856
4857class JSONBContains(Binary):
4858    _sql_names = ["JSONB_CONTAINS"]
4859
4860
4861class JSONExtract(Binary, Func):
4862    _sql_names = ["JSON_EXTRACT"]
4863
4864
4865class JSONExtractScalar(JSONExtract):
4866    _sql_names = ["JSON_EXTRACT_SCALAR"]
4867
4868
4869class JSONBExtract(JSONExtract):
4870    _sql_names = ["JSONB_EXTRACT"]
4871
4872
4873class JSONBExtractScalar(JSONExtract):
4874    _sql_names = ["JSONB_EXTRACT_SCALAR"]
4875
4876
4877class JSONFormat(Func):
4878    arg_types = {"this": False, "options": False}
4879    _sql_names = ["JSON_FORMAT"]
4880
4881
4882# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
4883class JSONArrayContains(Binary, Predicate, Func):
4884    _sql_names = ["JSON_ARRAY_CONTAINS"]
4885
4886
4887class ParseJSON(Func):
4888    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4889    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4890    arg_types = {"this": True, "expressions": False}
4891    is_var_len_args = True
4892
4893
4894# https://docs.snowflake.com/en/sql-reference/functions/get_path
4895class GetPath(Func):
4896    arg_types = {"this": True, "expression": True}
4897
4898    @property
4899    def output_name(self) -> str:
4900        return self.expression.output_name
4901
4902
4903class Least(Func):
4904    arg_types = {"this": True, "expressions": False}
4905    is_var_len_args = True
4906
4907
4908class Left(Func):
4909    arg_types = {"this": True, "expression": True}
4910
4911
4912class Right(Func):
4913    arg_types = {"this": True, "expression": True}
4914
4915
4916class Length(Func):
4917    _sql_names = ["LENGTH", "LEN"]
4918
4919
4920class Levenshtein(Func):
4921    arg_types = {
4922        "this": True,
4923        "expression": False,
4924        "ins_cost": False,
4925        "del_cost": False,
4926        "sub_cost": False,
4927    }
4928
4929
4930class Ln(Func):
4931    pass
4932
4933
4934class Log(Func):
4935    arg_types = {"this": True, "expression": False}
4936
4937
4938class Log2(Func):
4939    pass
4940
4941
4942class Log10(Func):
4943    pass
4944
4945
4946class LogicalOr(AggFunc):
4947    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
4948
4949
4950class LogicalAnd(AggFunc):
4951    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
4952
4953
4954class Lower(Func):
4955    _sql_names = ["LOWER", "LCASE"]
4956
4957
4958class Map(Func):
4959    arg_types = {"keys": False, "values": False}
4960
4961    @property
4962    def keys(self) -> t.List[Expression]:
4963        keys = self.args.get("keys")
4964        return keys.expressions if keys else []
4965
4966    @property
4967    def values(self) -> t.List[Expression]:
4968        values = self.args.get("values")
4969        return values.expressions if values else []
4970
4971
4972class MapFromEntries(Func):
4973    pass
4974
4975
4976class StarMap(Func):
4977    pass
4978
4979
4980class VarMap(Func):
4981    arg_types = {"keys": True, "values": True}
4982    is_var_len_args = True
4983
4984    @property
4985    def keys(self) -> t.List[Expression]:
4986        return self.args["keys"].expressions
4987
4988    @property
4989    def values(self) -> t.List[Expression]:
4990        return self.args["values"].expressions
4991
4992
4993# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
4994class MatchAgainst(Func):
4995    arg_types = {"this": True, "expressions": True, "modifier": False}
4996
4997
4998class Max(AggFunc):
4999    arg_types = {"this": True, "expressions": False}
5000    is_var_len_args = True
5001
5002
5003class MD5(Func):
5004    _sql_names = ["MD5"]
5005
5006
5007# Represents the variant of the MD5 function that returns a binary value
5008class MD5Digest(Func):
5009    _sql_names = ["MD5_DIGEST"]
5010
5011
5012class Min(AggFunc):
5013    arg_types = {"this": True, "expressions": False}
5014    is_var_len_args = True
5015
5016
5017class Month(Func):
5018    pass
5019
5020
5021class Nvl2(Func):
5022    arg_types = {"this": True, "true": True, "false": False}
5023
5024
5025# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
5026class Predict(Func):
5027    arg_types = {"this": True, "expression": True, "params_struct": False}
5028
5029
5030class Pow(Binary, Func):
5031    _sql_names = ["POWER", "POW"]
5032
5033
5034class PercentileCont(AggFunc):
5035    arg_types = {"this": True, "expression": False}
5036
5037
5038class PercentileDisc(AggFunc):
5039    arg_types = {"this": True, "expression": False}
5040
5041
5042class Quantile(AggFunc):
5043    arg_types = {"this": True, "quantile": True}
5044
5045
5046class ApproxQuantile(Quantile):
5047    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
5048
5049
5050class Rand(Func):
5051    _sql_names = ["RAND", "RANDOM"]
5052    arg_types = {"this": False}
5053
5054
5055class Randn(Func):
5056    arg_types = {"this": False}
5057
5058
5059class RangeN(Func):
5060    arg_types = {"this": True, "expressions": True, "each": False}
5061
5062
5063class ReadCSV(Func):
5064    _sql_names = ["READ_CSV"]
5065    is_var_len_args = True
5066    arg_types = {"this": True, "expressions": False}
5067
5068
5069class Reduce(Func):
5070    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
5071
5072
5073class RegexpExtract(Func):
5074    arg_types = {
5075        "this": True,
5076        "expression": True,
5077        "position": False,
5078        "occurrence": False,
5079        "parameters": False,
5080        "group": False,
5081    }
5082
5083
5084class RegexpReplace(Func):
5085    arg_types = {
5086        "this": True,
5087        "expression": True,
5088        "replacement": True,
5089        "position": False,
5090        "occurrence": False,
5091        "parameters": False,
5092        "modifiers": False,
5093    }
5094
5095
5096class RegexpLike(Binary, Func):
5097    arg_types = {"this": True, "expression": True, "flag": False}
5098
5099
5100class RegexpILike(Binary, Func):
5101    arg_types = {"this": True, "expression": True, "flag": False}
5102
5103
5104# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
5105# limit is the number of times a pattern is applied
5106class RegexpSplit(Func):
5107    arg_types = {"this": True, "expression": True, "limit": False}
5108
5109
5110class Repeat(Func):
5111    arg_types = {"this": True, "times": True}
5112
5113
5114class Round(Func):
5115    arg_types = {"this": True, "decimals": False}
5116
5117
5118class RowNumber(Func):
5119    arg_types: t.Dict[str, t.Any] = {}
5120
5121
5122class SafeDivide(Func):
5123    arg_types = {"this": True, "expression": True}
5124
5125
5126class SHA(Func):
5127    _sql_names = ["SHA", "SHA1"]
5128
5129
5130class SHA2(Func):
5131    _sql_names = ["SHA2"]
5132    arg_types = {"this": True, "length": False}
5133
5134
5135class SortArray(Func):
5136    arg_types = {"this": True, "asc": False}
5137
5138
5139class Split(Func):
5140    arg_types = {"this": True, "expression": True, "limit": False}
5141
5142
5143# Start may be omitted in the case of postgres
5144# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
5145class Substring(Func):
5146    arg_types = {"this": True, "start": False, "length": False}
5147
5148
5149class StandardHash(Func):
5150    arg_types = {"this": True, "expression": False}
5151
5152
5153class StartsWith(Func):
5154    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5155    arg_types = {"this": True, "expression": True}
5156
5157
5158class StrPosition(Func):
5159    arg_types = {
5160        "this": True,
5161        "substr": True,
5162        "position": False,
5163        "instance": False,
5164    }
5165
5166
5167class StrToDate(Func):
5168    arg_types = {"this": True, "format": True}
5169
5170
5171class StrToTime(Func):
5172    arg_types = {"this": True, "format": True, "zone": False}
5173
5174
5175# Spark allows unix_timestamp()
5176# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
5177class StrToUnix(Func):
5178    arg_types = {"this": False, "format": False}
5179
5180
5181# https://prestodb.io/docs/current/functions/string.html
5182# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
5183class StrToMap(Func):
5184    arg_types = {
5185        "this": True,
5186        "pair_delim": False,
5187        "key_value_delim": False,
5188        "duplicate_resolution_callback": False,
5189    }
5190
5191
5192class NumberToStr(Func):
5193    arg_types = {"this": True, "format": True, "culture": False}
5194
5195
5196class FromBase(Func):
5197    arg_types = {"this": True, "expression": True}
5198
5199
5200class Struct(Func):
5201    arg_types = {"expressions": False}
5202    is_var_len_args = True
5203
5204
5205class StructExtract(Func):
5206    arg_types = {"this": True, "expression": True}
5207
5208
5209# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
5210# https://docs.snowflake.com/en/sql-reference/functions/insert
5211class Stuff(Func):
5212    _sql_names = ["STUFF", "INSERT"]
5213    arg_types = {"this": True, "start": True, "length": True, "expression": True}
5214
5215
5216class Sum(AggFunc):
5217    pass
5218
5219
5220class Sqrt(Func):
5221    pass
5222
5223
5224class Stddev(AggFunc):
5225    pass
5226
5227
5228class StddevPop(AggFunc):
5229    pass
5230
5231
5232class StddevSamp(AggFunc):
5233    pass
5234
5235
5236class TimeToStr(Func):
5237    arg_types = {"this": True, "format": True, "culture": False}
5238
5239
5240class TimeToTimeStr(Func):
5241    pass
5242
5243
5244class TimeToUnix(Func):
5245    pass
5246
5247
5248class TimeStrToDate(Func):
5249    pass
5250
5251
5252class TimeStrToTime(Func):
5253    pass
5254
5255
5256class TimeStrToUnix(Func):
5257    pass
5258
5259
5260class Trim(Func):
5261    arg_types = {
5262        "this": True,
5263        "expression": False,
5264        "position": False,
5265        "collation": False,
5266    }
5267
5268
5269class TsOrDsAdd(Func, TimeUnit):
5270    # return_type is used to correctly cast the arguments of this expression when transpiling it
5271    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5272
5273    @property
5274    def return_type(self) -> DataType:
5275        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
5276
5277
5278class TsOrDsDiff(Func, TimeUnit):
5279    arg_types = {"this": True, "expression": True, "unit": False}
5280
5281
5282class TsOrDsToDateStr(Func):
5283    pass
5284
5285
5286class TsOrDsToDate(Func):
5287    arg_types = {"this": True, "format": False}
5288
5289
5290class TsOrDsToTime(Func):
5291    pass
5292
5293
5294class TsOrDiToDi(Func):
5295    pass
5296
5297
5298class Unhex(Func):
5299    pass
5300
5301
5302# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
5303class UnixDate(Func):
5304    pass
5305
5306
5307class UnixToStr(Func):
5308    arg_types = {"this": True, "format": False}
5309
5310
5311# https://prestodb.io/docs/current/functions/datetime.html
5312# presto has weird zone/hours/minutes
5313class UnixToTime(Func):
5314    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5315
5316    SECONDS = Literal.string("seconds")
5317    MILLIS = Literal.string("millis")
5318    MICROS = Literal.string("micros")
5319    NANOS = Literal.string("nanos")
5320
5321
5322class UnixToTimeStr(Func):
5323    pass
5324
5325
5326class TimestampFromParts(Func):
5327    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5328    arg_types = {
5329        "year": True,
5330        "month": True,
5331        "day": True,
5332        "hour": True,
5333        "min": True,
5334        "sec": True,
5335        "nano": False,
5336        "zone": False,
5337        "milli": False,
5338    }
5339
5340
5341class Upper(Func):
5342    _sql_names = ["UPPER", "UCASE"]
5343
5344
5345class Variance(AggFunc):
5346    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
5347
5348
5349class VariancePop(AggFunc):
5350    _sql_names = ["VARIANCE_POP", "VAR_POP"]
5351
5352
5353class Week(Func):
5354    arg_types = {"this": True, "mode": False}
5355
5356
5357class XMLTable(Func):
5358    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
5359
5360
5361class Year(Func):
5362    pass
5363
5364
5365class Use(Expression):
5366    arg_types = {"this": True, "kind": False}
5367
5368
5369class Merge(Expression):
5370    arg_types = {"this": True, "using": True, "on": True, "expressions": True, "with": False}
5371
5372
5373class When(Func):
5374    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
5375
5376
5377# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
5378# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
5379class NextValueFor(Func):
5380    arg_types = {"this": True, "order": False}
5381
5382
5383def _norm_arg(arg):
5384    return arg.lower() if type(arg) is str else arg
5385
5386
5387ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
5388FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
5389
5390
5391# Helpers
5392@t.overload
5393def maybe_parse(
5394    sql_or_expression: ExpOrStr,
5395    *,
5396    into: t.Type[E],
5397    dialect: DialectType = None,
5398    prefix: t.Optional[str] = None,
5399    copy: bool = False,
5400    **opts,
5401) -> E:
5402    ...
5403
5404
5405@t.overload
5406def maybe_parse(
5407    sql_or_expression: str | E,
5408    *,
5409    into: t.Optional[IntoType] = None,
5410    dialect: DialectType = None,
5411    prefix: t.Optional[str] = None,
5412    copy: bool = False,
5413    **opts,
5414) -> E:
5415    ...
5416
5417
5418def maybe_parse(
5419    sql_or_expression: ExpOrStr,
5420    *,
5421    into: t.Optional[IntoType] = None,
5422    dialect: DialectType = None,
5423    prefix: t.Optional[str] = None,
5424    copy: bool = False,
5425    **opts,
5426) -> Expression:
5427    """Gracefully handle a possible string or expression.
5428
5429    Example:
5430        >>> maybe_parse("1")
5431        Literal(this=1, is_string=False)
5432        >>> maybe_parse(to_identifier("x"))
5433        Identifier(this=x, quoted=False)
5434
5435    Args:
5436        sql_or_expression: the SQL code string or an expression
5437        into: the SQLGlot Expression to parse into
5438        dialect: the dialect used to parse the input expressions (in the case that an
5439            input expression is a SQL string).
5440        prefix: a string to prefix the sql with before it gets parsed
5441            (automatically includes a space)
5442        copy: whether or not to copy the expression.
5443        **opts: other options to use to parse the input expressions (again, in the case
5444            that an input expression is a SQL string).
5445
5446    Returns:
5447        Expression: the parsed or given expression.
5448    """
5449    if isinstance(sql_or_expression, Expression):
5450        if copy:
5451            return sql_or_expression.copy()
5452        return sql_or_expression
5453
5454    if sql_or_expression is None:
5455        raise ParseError(f"SQL cannot be None")
5456
5457    import sqlglot
5458
5459    sql = str(sql_or_expression)
5460    if prefix:
5461        sql = f"{prefix} {sql}"
5462
5463    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
5464
5465
5466@t.overload
5467def maybe_copy(instance: None, copy: bool = True) -> None:
5468    ...
5469
5470
5471@t.overload
5472def maybe_copy(instance: E, copy: bool = True) -> E:
5473    ...
5474
5475
5476def maybe_copy(instance, copy=True):
5477    return instance.copy() if copy and instance else instance
5478
5479
5480def _to_s(node: t.Any, verbose: bool = False, level: int = 0) -> str:
5481    """Generate a textual representation of an Expression tree"""
5482    indent = "\n" + ("  " * (level + 1))
5483    delim = f",{indent}"
5484
5485    if isinstance(node, Expression):
5486        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
5487
5488        if (node.type or verbose) and not isinstance(node, DataType):
5489            args["_type"] = node.type
5490        if node.comments or verbose:
5491            args["_comments"] = node.comments
5492
5493        if verbose:
5494            args["_id"] = id(node)
5495
5496        # Inline leaves for a more compact representation
5497        if node.is_leaf():
5498            indent = ""
5499            delim = ", "
5500
5501        items = delim.join([f"{k}={_to_s(v, verbose, level + 1)}" for k, v in args.items()])
5502        return f"{node.__class__.__name__}({indent}{items})"
5503
5504    if isinstance(node, list):
5505        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
5506        items = f"{indent}{items}" if items else ""
5507        return f"[{items}]"
5508
5509    # Indent multiline strings to match the current level
5510    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
5511
5512
5513def _is_wrong_expression(expression, into):
5514    return isinstance(expression, Expression) and not isinstance(expression, into)
5515
5516
5517def _apply_builder(
5518    expression,
5519    instance,
5520    arg,
5521    copy=True,
5522    prefix=None,
5523    into=None,
5524    dialect=None,
5525    into_arg="this",
5526    **opts,
5527):
5528    if _is_wrong_expression(expression, into):
5529        expression = into(**{into_arg: expression})
5530    instance = maybe_copy(instance, copy)
5531    expression = maybe_parse(
5532        sql_or_expression=expression,
5533        prefix=prefix,
5534        into=into,
5535        dialect=dialect,
5536        **opts,
5537    )
5538    instance.set(arg, expression)
5539    return instance
5540
5541
5542def _apply_child_list_builder(
5543    *expressions,
5544    instance,
5545    arg,
5546    append=True,
5547    copy=True,
5548    prefix=None,
5549    into=None,
5550    dialect=None,
5551    properties=None,
5552    **opts,
5553):
5554    instance = maybe_copy(instance, copy)
5555    parsed = []
5556    for expression in expressions:
5557        if expression is not None:
5558            if _is_wrong_expression(expression, into):
5559                expression = into(expressions=[expression])
5560
5561            expression = maybe_parse(
5562                expression,
5563                into=into,
5564                dialect=dialect,
5565                prefix=prefix,
5566                **opts,
5567            )
5568            parsed.extend(expression.expressions)
5569
5570    existing = instance.args.get(arg)
5571    if append and existing:
5572        parsed = existing.expressions + parsed
5573
5574    child = into(expressions=parsed)
5575    for k, v in (properties or {}).items():
5576        child.set(k, v)
5577    instance.set(arg, child)
5578
5579    return instance
5580
5581
5582def _apply_list_builder(
5583    *expressions,
5584    instance,
5585    arg,
5586    append=True,
5587    copy=True,
5588    prefix=None,
5589    into=None,
5590    dialect=None,
5591    **opts,
5592):
5593    inst = maybe_copy(instance, copy)
5594
5595    expressions = [
5596        maybe_parse(
5597            sql_or_expression=expression,
5598            into=into,
5599            prefix=prefix,
5600            dialect=dialect,
5601            **opts,
5602        )
5603        for expression in expressions
5604        if expression is not None
5605    ]
5606
5607    existing_expressions = inst.args.get(arg)
5608    if append and existing_expressions:
5609        expressions = existing_expressions + expressions
5610
5611    inst.set(arg, expressions)
5612    return inst
5613
5614
5615def _apply_conjunction_builder(
5616    *expressions,
5617    instance,
5618    arg,
5619    into=None,
5620    append=True,
5621    copy=True,
5622    dialect=None,
5623    **opts,
5624):
5625    expressions = [exp for exp in expressions if exp is not None and exp != ""]
5626    if not expressions:
5627        return instance
5628
5629    inst = maybe_copy(instance, copy)
5630
5631    existing = inst.args.get(arg)
5632    if append and existing is not None:
5633        expressions = [existing.this if into else existing] + list(expressions)
5634
5635    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
5636
5637    inst.set(arg, into(this=node) if into else node)
5638    return inst
5639
5640
5641def _apply_cte_builder(
5642    instance: E,
5643    alias: ExpOrStr,
5644    as_: ExpOrStr,
5645    recursive: t.Optional[bool] = None,
5646    append: bool = True,
5647    dialect: DialectType = None,
5648    copy: bool = True,
5649    **opts,
5650) -> E:
5651    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
5652    as_expression = maybe_parse(as_, dialect=dialect, **opts)
5653    cte = CTE(this=as_expression, alias=alias_expression)
5654    return _apply_child_list_builder(
5655        cte,
5656        instance=instance,
5657        arg="with",
5658        append=append,
5659        copy=copy,
5660        into=With,
5661        properties={"recursive": recursive or False},
5662    )
5663
5664
5665def _combine(
5666    expressions: t.Sequence[t.Optional[ExpOrStr]],
5667    operator: t.Type[Connector],
5668    dialect: DialectType = None,
5669    copy: bool = True,
5670    **opts,
5671) -> Expression:
5672    conditions = [
5673        condition(expression, dialect=dialect, copy=copy, **opts)
5674        for expression in expressions
5675        if expression is not None
5676    ]
5677
5678    this, *rest = conditions
5679    if rest:
5680        this = _wrap(this, Connector)
5681    for expression in rest:
5682        this = operator(this=this, expression=_wrap(expression, Connector))
5683
5684    return this
5685
5686
5687def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
5688    return Paren(this=expression) if isinstance(expression, kind) else expression
5689
5690
5691def union(
5692    left: ExpOrStr,
5693    right: ExpOrStr,
5694    distinct: bool = True,
5695    dialect: DialectType = None,
5696    copy: bool = True,
5697    **opts,
5698) -> Union:
5699    """
5700    Initializes a syntax tree from one UNION expression.
5701
5702    Example:
5703        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5704        'SELECT * FROM foo UNION SELECT * FROM bla'
5705
5706    Args:
5707        left: the SQL code string corresponding to the left-hand side.
5708            If an `Expression` instance is passed, it will be used as-is.
5709        right: the SQL code string corresponding to the right-hand side.
5710            If an `Expression` instance is passed, it will be used as-is.
5711        distinct: set the DISTINCT flag if and only if this is true.
5712        dialect: the dialect used to parse the input expression.
5713        copy: whether or not to copy the expression.
5714        opts: other options to use to parse the input expressions.
5715
5716    Returns:
5717        The new Union instance.
5718    """
5719    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5720    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5721
5722    return Union(this=left, expression=right, distinct=distinct)
5723
5724
5725def intersect(
5726    left: ExpOrStr,
5727    right: ExpOrStr,
5728    distinct: bool = True,
5729    dialect: DialectType = None,
5730    copy: bool = True,
5731    **opts,
5732) -> Intersect:
5733    """
5734    Initializes a syntax tree from one INTERSECT expression.
5735
5736    Example:
5737        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5738        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5739
5740    Args:
5741        left: the SQL code string corresponding to the left-hand side.
5742            If an `Expression` instance is passed, it will be used as-is.
5743        right: the SQL code string corresponding to the right-hand side.
5744            If an `Expression` instance is passed, it will be used as-is.
5745        distinct: set the DISTINCT flag if and only if this is true.
5746        dialect: the dialect used to parse the input expression.
5747        copy: whether or not to copy the expression.
5748        opts: other options to use to parse the input expressions.
5749
5750    Returns:
5751        The new Intersect instance.
5752    """
5753    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5754    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5755
5756    return Intersect(this=left, expression=right, distinct=distinct)
5757
5758
5759def except_(
5760    left: ExpOrStr,
5761    right: ExpOrStr,
5762    distinct: bool = True,
5763    dialect: DialectType = None,
5764    copy: bool = True,
5765    **opts,
5766) -> Except:
5767    """
5768    Initializes a syntax tree from one EXCEPT expression.
5769
5770    Example:
5771        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5772        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5773
5774    Args:
5775        left: the SQL code string corresponding to the left-hand side.
5776            If an `Expression` instance is passed, it will be used as-is.
5777        right: the SQL code string corresponding to the right-hand side.
5778            If an `Expression` instance is passed, it will be used as-is.
5779        distinct: set the DISTINCT flag if and only if this is true.
5780        dialect: the dialect used to parse the input expression.
5781        copy: whether or not to copy the expression.
5782        opts: other options to use to parse the input expressions.
5783
5784    Returns:
5785        The new Except instance.
5786    """
5787    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5788    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5789
5790    return Except(this=left, expression=right, distinct=distinct)
5791
5792
5793def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5794    """
5795    Initializes a syntax tree from one or multiple SELECT expressions.
5796
5797    Example:
5798        >>> select("col1", "col2").from_("tbl").sql()
5799        'SELECT col1, col2 FROM tbl'
5800
5801    Args:
5802        *expressions: the SQL code string to parse as the expressions of a
5803            SELECT statement. If an Expression instance is passed, this is used as-is.
5804        dialect: the dialect used to parse the input expressions (in the case that an
5805            input expression is a SQL string).
5806        **opts: other options to use to parse the input expressions (again, in the case
5807            that an input expression is a SQL string).
5808
5809    Returns:
5810        Select: the syntax tree for the SELECT statement.
5811    """
5812    return Select().select(*expressions, dialect=dialect, **opts)
5813
5814
5815def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5816    """
5817    Initializes a syntax tree from a FROM expression.
5818
5819    Example:
5820        >>> from_("tbl").select("col1", "col2").sql()
5821        'SELECT col1, col2 FROM tbl'
5822
5823    Args:
5824        *expression: the SQL code string to parse as the FROM expressions of a
5825            SELECT statement. If an Expression instance is passed, this is used as-is.
5826        dialect: the dialect used to parse the input expression (in the case that the
5827            input expression is a SQL string).
5828        **opts: other options to use to parse the input expressions (again, in the case
5829            that the input expression is a SQL string).
5830
5831    Returns:
5832        Select: the syntax tree for the SELECT statement.
5833    """
5834    return Select().from_(expression, dialect=dialect, **opts)
5835
5836
5837def update(
5838    table: str | Table,
5839    properties: dict,
5840    where: t.Optional[ExpOrStr] = None,
5841    from_: t.Optional[ExpOrStr] = None,
5842    dialect: DialectType = None,
5843    **opts,
5844) -> Update:
5845    """
5846    Creates an update statement.
5847
5848    Example:
5849        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5850        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5851
5852    Args:
5853        *properties: dictionary of properties to set which are
5854            auto converted to sql objects eg None -> NULL
5855        where: sql conditional parsed into a WHERE statement
5856        from_: sql statement parsed into a FROM statement
5857        dialect: the dialect used to parse the input expressions.
5858        **opts: other options to use to parse the input expressions.
5859
5860    Returns:
5861        Update: the syntax tree for the UPDATE statement.
5862    """
5863    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5864    update_expr.set(
5865        "expressions",
5866        [
5867            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5868            for k, v in properties.items()
5869        ],
5870    )
5871    if from_:
5872        update_expr.set(
5873            "from",
5874            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5875        )
5876    if isinstance(where, Condition):
5877        where = Where(this=where)
5878    if where:
5879        update_expr.set(
5880            "where",
5881            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5882        )
5883    return update_expr
5884
5885
5886def delete(
5887    table: ExpOrStr,
5888    where: t.Optional[ExpOrStr] = None,
5889    returning: t.Optional[ExpOrStr] = None,
5890    dialect: DialectType = None,
5891    **opts,
5892) -> Delete:
5893    """
5894    Builds a delete statement.
5895
5896    Example:
5897        >>> delete("my_table", where="id > 1").sql()
5898        'DELETE FROM my_table WHERE id > 1'
5899
5900    Args:
5901        where: sql conditional parsed into a WHERE statement
5902        returning: sql conditional parsed into a RETURNING statement
5903        dialect: the dialect used to parse the input expressions.
5904        **opts: other options to use to parse the input expressions.
5905
5906    Returns:
5907        Delete: the syntax tree for the DELETE statement.
5908    """
5909    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5910    if where:
5911        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5912    if returning:
5913        delete_expr = t.cast(
5914            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5915        )
5916    return delete_expr
5917
5918
5919def insert(
5920    expression: ExpOrStr,
5921    into: ExpOrStr,
5922    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5923    overwrite: t.Optional[bool] = None,
5924    returning: t.Optional[ExpOrStr] = None,
5925    dialect: DialectType = None,
5926    copy: bool = True,
5927    **opts,
5928) -> Insert:
5929    """
5930    Builds an INSERT statement.
5931
5932    Example:
5933        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5934        'INSERT INTO tbl VALUES (1, 2, 3)'
5935
5936    Args:
5937        expression: the sql string or expression of the INSERT statement
5938        into: the tbl to insert data to.
5939        columns: optionally the table's column names.
5940        overwrite: whether to INSERT OVERWRITE or not.
5941        returning: sql conditional parsed into a RETURNING statement
5942        dialect: the dialect used to parse the input expressions.
5943        copy: whether or not to copy the expression.
5944        **opts: other options to use to parse the input expressions.
5945
5946    Returns:
5947        Insert: the syntax tree for the INSERT statement.
5948    """
5949    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5950    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5951
5952    if columns:
5953        this = _apply_list_builder(
5954            *columns,
5955            instance=Schema(this=this),
5956            arg="expressions",
5957            into=Identifier,
5958            copy=False,
5959            dialect=dialect,
5960            **opts,
5961        )
5962
5963    insert = Insert(this=this, expression=expr, overwrite=overwrite)
5964
5965    if returning:
5966        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
5967
5968    return insert
5969
5970
5971def condition(
5972    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5973) -> Condition:
5974    """
5975    Initialize a logical condition expression.
5976
5977    Example:
5978        >>> condition("x=1").sql()
5979        'x = 1'
5980
5981        This is helpful for composing larger logical syntax trees:
5982        >>> where = condition("x=1")
5983        >>> where = where.and_("y=1")
5984        >>> Select().from_("tbl").select("*").where(where).sql()
5985        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5986
5987    Args:
5988        *expression: the SQL code string to parse.
5989            If an Expression instance is passed, this is used as-is.
5990        dialect: the dialect used to parse the input expression (in the case that the
5991            input expression is a SQL string).
5992        copy: Whether or not to copy `expression` (only applies to expressions).
5993        **opts: other options to use to parse the input expressions (again, in the case
5994            that the input expression is a SQL string).
5995
5996    Returns:
5997        The new Condition instance
5998    """
5999    return maybe_parse(
6000        expression,
6001        into=Condition,
6002        dialect=dialect,
6003        copy=copy,
6004        **opts,
6005    )
6006
6007
6008def and_(
6009    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6010) -> Condition:
6011    """
6012    Combine multiple conditions with an AND logical operator.
6013
6014    Example:
6015        >>> and_("x=1", and_("y=1", "z=1")).sql()
6016        'x = 1 AND (y = 1 AND z = 1)'
6017
6018    Args:
6019        *expressions: the SQL code strings to parse.
6020            If an Expression instance is passed, this is used as-is.
6021        dialect: the dialect used to parse the input expression.
6022        copy: whether or not to copy `expressions` (only applies to Expressions).
6023        **opts: other options to use to parse the input expressions.
6024
6025    Returns:
6026        And: the new condition
6027    """
6028    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
6029
6030
6031def or_(
6032    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6033) -> Condition:
6034    """
6035    Combine multiple conditions with an OR logical operator.
6036
6037    Example:
6038        >>> or_("x=1", or_("y=1", "z=1")).sql()
6039        'x = 1 OR (y = 1 OR z = 1)'
6040
6041    Args:
6042        *expressions: the SQL code strings to parse.
6043            If an Expression instance is passed, this is used as-is.
6044        dialect: the dialect used to parse the input expression.
6045        copy: whether or not to copy `expressions` (only applies to Expressions).
6046        **opts: other options to use to parse the input expressions.
6047
6048    Returns:
6049        Or: the new condition
6050    """
6051    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
6052
6053
6054def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6055    """
6056    Wrap a condition with a NOT operator.
6057
6058    Example:
6059        >>> not_("this_suit='black'").sql()
6060        "NOT this_suit = 'black'"
6061
6062    Args:
6063        expression: the SQL code string to parse.
6064            If an Expression instance is passed, this is used as-is.
6065        dialect: the dialect used to parse the input expression.
6066        copy: whether to copy the expression or not.
6067        **opts: other options to use to parse the input expressions.
6068
6069    Returns:
6070        The new condition.
6071    """
6072    this = condition(
6073        expression,
6074        dialect=dialect,
6075        copy=copy,
6076        **opts,
6077    )
6078    return Not(this=_wrap(this, Connector))
6079
6080
6081def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6082    """
6083    Wrap an expression in parentheses.
6084
6085    Example:
6086        >>> paren("5 + 3").sql()
6087        '(5 + 3)'
6088
6089    Args:
6090        expression: the SQL code string to parse.
6091            If an Expression instance is passed, this is used as-is.
6092        copy: whether to copy the expression or not.
6093
6094    Returns:
6095        The wrapped expression.
6096    """
6097    return Paren(this=maybe_parse(expression, copy=copy))
6098
6099
6100SAFE_IDENTIFIER_RE = re.compile(r"^[_a-zA-Z][\w]*$")
6101
6102
6103@t.overload
6104def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None:
6105    ...
6106
6107
6108@t.overload
6109def to_identifier(
6110    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
6111) -> Identifier:
6112    ...
6113
6114
6115def to_identifier(name, quoted=None, copy=True):
6116    """Builds an identifier.
6117
6118    Args:
6119        name: The name to turn into an identifier.
6120        quoted: Whether or not force quote the identifier.
6121        copy: Whether or not to copy name if it's an Identifier.
6122
6123    Returns:
6124        The identifier ast node.
6125    """
6126
6127    if name is None:
6128        return None
6129
6130    if isinstance(name, Identifier):
6131        identifier = maybe_copy(name, copy)
6132    elif isinstance(name, str):
6133        identifier = Identifier(
6134            this=name,
6135            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6136        )
6137    else:
6138        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6139    return identifier
6140
6141
6142def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6143    """
6144    Parses a given string into an identifier.
6145
6146    Args:
6147        name: The name to parse into an identifier.
6148        dialect: The dialect to parse against.
6149
6150    Returns:
6151        The identifier ast node.
6152    """
6153    try:
6154        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6155    except ParseError:
6156        expression = to_identifier(name)
6157
6158    return expression
6159
6160
6161INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
6162
6163
6164def to_interval(interval: str | Literal) -> Interval:
6165    """Builds an interval expression from a string like '1 day' or '5 months'."""
6166    if isinstance(interval, Literal):
6167        if not interval.is_string:
6168            raise ValueError("Invalid interval string.")
6169
6170        interval = interval.this
6171
6172    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6173
6174    if not interval_parts:
6175        raise ValueError("Invalid interval string.")
6176
6177    return Interval(
6178        this=Literal.string(interval_parts.group(1)),
6179        unit=Var(this=interval_parts.group(2).upper()),
6180    )
6181
6182
6183@t.overload
6184def to_table(sql_path: str | Table, **kwargs) -> Table:
6185    ...
6186
6187
6188@t.overload
6189def to_table(sql_path: None, **kwargs) -> None:
6190    ...
6191
6192
6193def to_table(
6194    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6195) -> t.Optional[Table]:
6196    """
6197    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6198    If a table is passed in then that table is returned.
6199
6200    Args:
6201        sql_path: a `[catalog].[schema].[table]` string.
6202        dialect: the source dialect according to which the table name will be parsed.
6203        copy: Whether or not to copy a table if it is passed in.
6204        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6205
6206    Returns:
6207        A table expression.
6208    """
6209    if sql_path is None or isinstance(sql_path, Table):
6210        return maybe_copy(sql_path, copy=copy)
6211    if not isinstance(sql_path, str):
6212        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6213
6214    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6215    if table:
6216        for k, v in kwargs.items():
6217            table.set(k, v)
6218
6219    return table
6220
6221
6222def to_column(sql_path: str | Column, **kwargs) -> Column:
6223    """
6224    Create a column from a `[table].[column]` sql path. Schema is optional.
6225
6226    If a column is passed in then that column is returned.
6227
6228    Args:
6229        sql_path: `[table].[column]` string
6230    Returns:
6231        Table: A column expression
6232    """
6233    if sql_path is None or isinstance(sql_path, Column):
6234        return sql_path
6235    if not isinstance(sql_path, str):
6236        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6237    return column(*reversed(sql_path.split(".")), **kwargs)  # type: ignore
6238
6239
6240def alias_(
6241    expression: ExpOrStr,
6242    alias: str | Identifier,
6243    table: bool | t.Sequence[str | Identifier] = False,
6244    quoted: t.Optional[bool] = None,
6245    dialect: DialectType = None,
6246    copy: bool = True,
6247    **opts,
6248):
6249    """Create an Alias expression.
6250
6251    Example:
6252        >>> alias_('foo', 'bar').sql()
6253        'foo AS bar'
6254
6255        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6256        '(SELECT 1, 2) AS bar(a, b)'
6257
6258    Args:
6259        expression: the SQL code strings to parse.
6260            If an Expression instance is passed, this is used as-is.
6261        alias: the alias name to use. If the name has
6262            special characters it is quoted.
6263        table: Whether or not to create a table alias, can also be a list of columns.
6264        quoted: whether or not to quote the alias
6265        dialect: the dialect used to parse the input expression.
6266        copy: Whether or not to copy the expression.
6267        **opts: other options to use to parse the input expressions.
6268
6269    Returns:
6270        Alias: the aliased expression
6271    """
6272    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6273    alias = to_identifier(alias, quoted=quoted)
6274
6275    if table:
6276        table_alias = TableAlias(this=alias)
6277        exp.set("alias", table_alias)
6278
6279        if not isinstance(table, bool):
6280            for column in table:
6281                table_alias.append("columns", to_identifier(column, quoted=quoted))
6282
6283        return exp
6284
6285    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6286    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6287    # for the complete Window expression.
6288    #
6289    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6290
6291    if "alias" in exp.arg_types and not isinstance(exp, Window):
6292        exp.set("alias", alias)
6293        return exp
6294    return Alias(this=exp, alias=alias)
6295
6296
6297def subquery(
6298    expression: ExpOrStr,
6299    alias: t.Optional[Identifier | str] = None,
6300    dialect: DialectType = None,
6301    **opts,
6302) -> Select:
6303    """
6304    Build a subquery expression.
6305
6306    Example:
6307        >>> subquery('select x from tbl', 'bar').select('x').sql()
6308        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6309
6310    Args:
6311        expression: the SQL code strings to parse.
6312            If an Expression instance is passed, this is used as-is.
6313        alias: the alias name to use.
6314        dialect: the dialect used to parse the input expression.
6315        **opts: other options to use to parse the input expressions.
6316
6317    Returns:
6318        A new Select instance with the subquery expression included.
6319    """
6320
6321    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6322    return Select().from_(expression, dialect=dialect, **opts)
6323
6324
6325def column(
6326    col: str | Identifier,
6327    table: t.Optional[str | Identifier] = None,
6328    db: t.Optional[str | Identifier] = None,
6329    catalog: t.Optional[str | Identifier] = None,
6330    *fields: t.Union[str, Identifier],
6331    quoted: t.Optional[bool] = None,
6332    copy: bool = True,
6333) -> Column | Dot:
6334    """
6335    Build a Column.
6336
6337    Args:
6338        col: Column name.
6339        table: Table name.
6340        db: Database name.
6341        catalog: Catalog name.
6342        fields: Additional fields using dots.
6343        quoted: Whether to force quotes on the column's identifiers.
6344        copy: Whether or not to copy identifiers if passed in.
6345
6346    Returns:
6347        The new Column instance.
6348    """
6349    this: t.Union[Column, Dot] = Column(
6350        this=to_identifier(col, quoted=quoted, copy=copy),
6351        table=to_identifier(table, quoted=quoted, copy=copy),
6352        db=to_identifier(db, quoted=quoted, copy=copy),
6353        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6354    )
6355
6356    if fields:
6357        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6358    return this
6359
6360
6361def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6362    """Cast an expression to a data type.
6363
6364    Example:
6365        >>> cast('x + 1', 'int').sql()
6366        'CAST(x + 1 AS INT)'
6367
6368    Args:
6369        expression: The expression to cast.
6370        to: The datatype to cast to.
6371
6372    Returns:
6373        The new Cast instance.
6374    """
6375    expression = maybe_parse(expression, **opts)
6376    data_type = DataType.build(to, **opts)
6377    expression = Cast(this=expression, to=data_type)
6378    expression.type = data_type
6379    return expression
6380
6381
6382def table_(
6383    table: Identifier | str,
6384    db: t.Optional[Identifier | str] = None,
6385    catalog: t.Optional[Identifier | str] = None,
6386    quoted: t.Optional[bool] = None,
6387    alias: t.Optional[Identifier | str] = None,
6388) -> Table:
6389    """Build a Table.
6390
6391    Args:
6392        table: Table name.
6393        db: Database name.
6394        catalog: Catalog name.
6395        quote: Whether to force quotes on the table's identifiers.
6396        alias: Table's alias.
6397
6398    Returns:
6399        The new Table instance.
6400    """
6401    return Table(
6402        this=to_identifier(table, quoted=quoted) if table else None,
6403        db=to_identifier(db, quoted=quoted) if db else None,
6404        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6405        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6406    )
6407
6408
6409def values(
6410    values: t.Iterable[t.Tuple[t.Any, ...]],
6411    alias: t.Optional[str] = None,
6412    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6413) -> Values:
6414    """Build VALUES statement.
6415
6416    Example:
6417        >>> values([(1, '2')]).sql()
6418        "VALUES (1, '2')"
6419
6420    Args:
6421        values: values statements that will be converted to SQL
6422        alias: optional alias
6423        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6424         If either are provided then an alias is also required.
6425
6426    Returns:
6427        Values: the Values expression object
6428    """
6429    if columns and not alias:
6430        raise ValueError("Alias is required when providing columns")
6431
6432    return Values(
6433        expressions=[convert(tup) for tup in values],
6434        alias=(
6435            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6436            if columns
6437            else (TableAlias(this=to_identifier(alias)) if alias else None)
6438        ),
6439    )
6440
6441
6442def var(name: t.Optional[ExpOrStr]) -> Var:
6443    """Build a SQL variable.
6444
6445    Example:
6446        >>> repr(var('x'))
6447        'Var(this=x)'
6448
6449        >>> repr(var(column('x', table='y')))
6450        'Var(this=x)'
6451
6452    Args:
6453        name: The name of the var or an expression who's name will become the var.
6454
6455    Returns:
6456        The new variable node.
6457    """
6458    if not name:
6459        raise ValueError("Cannot convert empty name into var.")
6460
6461    if isinstance(name, Expression):
6462        name = name.name
6463    return Var(this=name)
6464
6465
6466def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6467    """Build ALTER TABLE... RENAME... expression
6468
6469    Args:
6470        old_name: The old name of the table
6471        new_name: The new name of the table
6472
6473    Returns:
6474        Alter table expression
6475    """
6476    old_table = to_table(old_name)
6477    new_table = to_table(new_name)
6478    return AlterTable(
6479        this=old_table,
6480        actions=[
6481            RenameTable(this=new_table),
6482        ],
6483    )
6484
6485
6486def convert(value: t.Any, copy: bool = False) -> Expression:
6487    """Convert a python value into an expression object.
6488
6489    Raises an error if a conversion is not possible.
6490
6491    Args:
6492        value: A python object.
6493        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6494
6495    Returns:
6496        Expression: the equivalent expression object.
6497    """
6498    if isinstance(value, Expression):
6499        return maybe_copy(value, copy)
6500    if isinstance(value, str):
6501        return Literal.string(value)
6502    if isinstance(value, bool):
6503        return Boolean(this=value)
6504    if value is None or (isinstance(value, float) and math.isnan(value)):
6505        return NULL
6506    if isinstance(value, numbers.Number):
6507        return Literal.number(value)
6508    if isinstance(value, datetime.datetime):
6509        datetime_literal = Literal.string(
6510            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6511        )
6512        return TimeStrToTime(this=datetime_literal)
6513    if isinstance(value, datetime.date):
6514        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6515        return DateStrToDate(this=date_literal)
6516    if isinstance(value, tuple):
6517        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6518    if isinstance(value, list):
6519        return Array(expressions=[convert(v, copy=copy) for v in value])
6520    if isinstance(value, dict):
6521        return Map(
6522            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6523            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6524        )
6525    raise ValueError(f"Cannot convert {value}")
6526
6527
6528def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6529    """
6530    Replace children of an expression with the result of a lambda fun(child) -> exp.
6531    """
6532    for k, v in expression.args.items():
6533        is_list_arg = type(v) is list
6534
6535        child_nodes = v if is_list_arg else [v]
6536        new_child_nodes = []
6537
6538        for cn in child_nodes:
6539            if isinstance(cn, Expression):
6540                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6541                    new_child_nodes.append(child_node)
6542                    child_node.parent = expression
6543                    child_node.arg_key = k
6544            else:
6545                new_child_nodes.append(cn)
6546
6547        expression.args[k] = new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0)
6548
6549
6550def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6551    """
6552    Return all table names referenced through columns in an expression.
6553
6554    Example:
6555        >>> import sqlglot
6556        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6557        ['a', 'c']
6558
6559    Args:
6560        expression: expression to find table names.
6561        exclude: a table name to exclude
6562
6563    Returns:
6564        A list of unique names.
6565    """
6566    return {
6567        table
6568        for table in (column.table for column in expression.find_all(Column))
6569        if table and table != exclude
6570    }
6571
6572
6573def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6574    """Get the full name of a table as a string.
6575
6576    Args:
6577        table: Table expression node or string.
6578        dialect: The dialect to generate the table name for.
6579        identify: Determines when an identifier should be quoted. Possible values are:
6580            False (default): Never quote, except in cases where it's mandatory by the dialect.
6581            True: Always quote.
6582
6583    Examples:
6584        >>> from sqlglot import exp, parse_one
6585        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6586        'a.b.c'
6587
6588    Returns:
6589        The table name.
6590    """
6591
6592    table = maybe_parse(table, into=Table, dialect=dialect)
6593
6594    if not table:
6595        raise ValueError(f"Cannot parse {table}")
6596
6597    return ".".join(
6598        part.sql(dialect=dialect, identify=True, copy=False)
6599        if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6600        else part.name
6601        for part in table.parts
6602    )
6603
6604
6605def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6606    """Returns a case normalized table name without quotes.
6607
6608    Args:
6609        table: the table to normalize
6610        dialect: the dialect to use for normalization rules
6611        copy: whether or not to copy the expression.
6612
6613    Examples:
6614        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6615        'A-B.c'
6616    """
6617    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6618
6619    return ".".join(
6620        p.name
6621        for p in normalize_identifiers(
6622            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6623        ).parts
6624    )
6625
6626
6627def replace_tables(
6628    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6629) -> E:
6630    """Replace all tables in expression according to the mapping.
6631
6632    Args:
6633        expression: expression node to be transformed and replaced.
6634        mapping: mapping of table names.
6635        dialect: the dialect of the mapping table
6636        copy: whether or not to copy the expression.
6637
6638    Examples:
6639        >>> from sqlglot import exp, parse_one
6640        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6641        'SELECT * FROM c /* a.b */'
6642
6643    Returns:
6644        The mapped expression.
6645    """
6646
6647    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6648
6649    def _replace_tables(node: Expression) -> Expression:
6650        if isinstance(node, Table):
6651            original = normalize_table_name(node, dialect=dialect)
6652            new_name = mapping.get(original)
6653
6654            if new_name:
6655                table = to_table(
6656                    new_name,
6657                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6658                )
6659                table.add_comments([original])
6660                return table
6661        return node
6662
6663    return expression.transform(_replace_tables, copy=copy)
6664
6665
6666def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6667    """Replace placeholders in an expression.
6668
6669    Args:
6670        expression: expression node to be transformed and replaced.
6671        args: positional names that will substitute unnamed placeholders in the given order.
6672        kwargs: keyword arguments that will substitute named placeholders.
6673
6674    Examples:
6675        >>> from sqlglot import exp, parse_one
6676        >>> replace_placeholders(
6677        ...     parse_one("select * from :tbl where ? = ?"),
6678        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6679        ... ).sql()
6680        "SELECT * FROM foo WHERE str_col = 'b'"
6681
6682    Returns:
6683        The mapped expression.
6684    """
6685
6686    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6687        if isinstance(node, Placeholder):
6688            if node.name:
6689                new_name = kwargs.get(node.name)
6690                if new_name:
6691                    return convert(new_name)
6692            else:
6693                try:
6694                    return convert(next(args))
6695                except StopIteration:
6696                    pass
6697        return node
6698
6699    return expression.transform(_replace_placeholders, iter(args), **kwargs)
6700
6701
6702def expand(
6703    expression: Expression,
6704    sources: t.Dict[str, Subqueryable],
6705    dialect: DialectType = None,
6706    copy: bool = True,
6707) -> Expression:
6708    """Transforms an expression by expanding all referenced sources into subqueries.
6709
6710    Examples:
6711        >>> from sqlglot import parse_one
6712        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6713        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6714
6715        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6716        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6717
6718    Args:
6719        expression: The expression to expand.
6720        sources: A dictionary of name to Subqueryables.
6721        dialect: The dialect of the sources dict.
6722        copy: Whether or not to copy the expression during transformation. Defaults to True.
6723
6724    Returns:
6725        The transformed expression.
6726    """
6727    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6728
6729    def _expand(node: Expression):
6730        if isinstance(node, Table):
6731            name = normalize_table_name(node, dialect=dialect)
6732            source = sources.get(name)
6733            if source:
6734                subquery = source.subquery(node.alias or name)
6735                subquery.comments = [f"source: {name}"]
6736                return subquery.transform(_expand, copy=False)
6737        return node
6738
6739    return expression.transform(_expand, copy=copy)
6740
6741
6742def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
6743    """
6744    Returns a Func expression.
6745
6746    Examples:
6747        >>> func("abs", 5).sql()
6748        'ABS(5)'
6749
6750        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6751        'CAST(5 AS DOUBLE)'
6752
6753    Args:
6754        name: the name of the function to build.
6755        args: the args used to instantiate the function of interest.
6756        copy: whether or not to copy the argument expressions.
6757        dialect: the source dialect.
6758        kwargs: the kwargs used to instantiate the function of interest.
6759
6760    Note:
6761        The arguments `args` and `kwargs` are mutually exclusive.
6762
6763    Returns:
6764        An instance of the function of interest, or an anonymous function, if `name` doesn't
6765        correspond to an existing `sqlglot.expressions.Func` class.
6766    """
6767    if args and kwargs:
6768        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6769
6770    from sqlglot.dialects.dialect import Dialect
6771
6772    dialect = Dialect.get_or_raise(dialect)
6773
6774    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
6775    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
6776
6777    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
6778    if constructor:
6779        if converted:
6780            if "dialect" in constructor.__code__.co_varnames:
6781                function = constructor(converted, dialect=dialect)
6782            else:
6783                function = constructor(converted)
6784        elif constructor.__name__ == "from_arg_list":
6785            function = constructor.__self__(**kwargs)  # type: ignore
6786        else:
6787            constructor = FUNCTION_BY_NAME.get(name.upper())
6788            if constructor:
6789                function = constructor(**kwargs)
6790            else:
6791                raise ValueError(
6792                    f"Unable to convert '{name}' into a Func. Either manually construct "
6793                    "the Func expression of interest or parse the function call."
6794                )
6795    else:
6796        kwargs = kwargs or {"expressions": converted}
6797        function = Anonymous(this=name, **kwargs)
6798
6799    for error_message in function.error_messages(converted):
6800        raise ValueError(error_message)
6801
6802    return function
6803
6804
6805def case(
6806    expression: t.Optional[ExpOrStr] = None,
6807    **opts,
6808) -> Case:
6809    """
6810    Initialize a CASE statement.
6811
6812    Example:
6813        case().when("a = 1", "foo").else_("bar")
6814
6815    Args:
6816        expression: Optionally, the input expression (not all dialects support this)
6817        **opts: Extra keyword arguments for parsing `expression`
6818    """
6819    if expression is not None:
6820        this = maybe_parse(expression, **opts)
6821    else:
6822        this = None
6823    return Case(this=this, ifs=[])
6824
6825
6826def cast_unless(
6827    expression: ExpOrStr,
6828    to: DATA_TYPE,
6829    *types: DATA_TYPE,
6830    **opts: t.Any,
6831) -> Expression | Cast:
6832    """
6833    Cast an expression to a data type unless it is a specified type.
6834
6835    Args:
6836        expression: The expression to cast.
6837        to: The data type to cast to.
6838        **types: The types to exclude from casting.
6839        **opts: Extra keyword arguments for parsing `expression`
6840    """
6841    expr = maybe_parse(expression, **opts)
6842    if expr.is_type(*types):
6843        return expr
6844    return cast(expr, to, **opts)
6845
6846
6847def true() -> Boolean:
6848    """
6849    Returns a true Boolean expression.
6850    """
6851    return Boolean(this=True)
6852
6853
6854def false() -> Boolean:
6855    """
6856    Returns a false Boolean expression.
6857    """
6858    return Boolean(this=False)
6859
6860
6861def null() -> Null:
6862    """
6863    Returns a Null expression.
6864    """
6865    return Null()
6866
6867
6868# TODO: deprecate this
6869TRUE = Boolean(this=True)
6870FALSE = Boolean(this=False)
6871NULL = 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 = {
1930        "this": True,
1931        "view": False,
1932        "outer": False,
1933        "alias": False,
1934        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
1935    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
1938class MatchRecognize(Expression):
1939    arg_types = {
1940        "partition_by": False,
1941        "order": False,
1942        "measures": False,
1943        "rows": False,
1944        "after": False,
1945        "pattern": False,
1946        "define": False,
1947        "alias": False,
1948    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
1953class Final(Expression):
1954    pass
key = 'final'
class Offset(Expression):
1957class Offset(Expression):
1958    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'offset'
class Order(Expression):
1961class Order(Expression):
1962    arg_types = {"this": False, "expressions": True, "interpolate": False}
arg_types = {'this': False, 'expressions': True, 'interpolate': False}
key = 'order'
class WithFill(Expression):
1966class WithFill(Expression):
1967    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
1972class Cluster(Order):
1973    pass
key = 'cluster'
class Distribute(Order):
1976class Distribute(Order):
1977    pass
key = 'distribute'
class Sort(Order):
1980class Sort(Order):
1981    pass
key = 'sort'
class Ordered(Expression):
1984class Ordered(Expression):
1985    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):
1988class Property(Expression):
1989    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
1992class AlgorithmProperty(Property):
1993    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
1996class AutoIncrementProperty(Property):
1997    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2001class AutoRefreshProperty(Property):
2002    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BlockCompressionProperty(Property):
2005class BlockCompressionProperty(Property):
2006    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):
2009class CharacterSetProperty(Property):
2010    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2013class ChecksumProperty(Property):
2014    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2017class CollateProperty(Property):
2018    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2021class CopyGrantsProperty(Property):
2022    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2025class DataBlocksizeProperty(Property):
2026    arg_types = {
2027        "size": False,
2028        "units": False,
2029        "minimum": False,
2030        "maximum": False,
2031        "default": False,
2032    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2035class DefinerProperty(Property):
2036    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2039class DistKeyProperty(Property):
2040    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2043class DistStyleProperty(Property):
2044    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2047class EngineProperty(Property):
2048    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2051class HeapProperty(Property):
2052    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2055class ToTableProperty(Property):
2056    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2059class ExecuteAsProperty(Property):
2060    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2063class ExternalProperty(Property):
2064    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2067class FallbackProperty(Property):
2068    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2071class FileFormatProperty(Property):
2072    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2075class FreespaceProperty(Property):
2076    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InputModelProperty(Property):
2079class InputModelProperty(Property):
2080    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2083class OutputModelProperty(Property):
2084    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2087class IsolatedLoadingProperty(Property):
2088    arg_types = {
2089        "no": True,
2090        "concurrent": True,
2091        "for_all": True,
2092        "for_insert": True,
2093        "for_none": True,
2094    }
arg_types = {'no': True, 'concurrent': True, 'for_all': True, 'for_insert': True, 'for_none': True}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2097class JournalProperty(Property):
2098    arg_types = {
2099        "no": False,
2100        "dual": False,
2101        "before": False,
2102        "local": False,
2103        "after": False,
2104    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2107class LanguageProperty(Property):
2108    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2112class ClusteredByProperty(Property):
2113    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2116class DictProperty(Property):
2117    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2120class DictSubProperty(Property):
2121    pass
key = 'dictsubproperty'
class DictRange(Property):
2124class DictRange(Property):
2125    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2130class OnCluster(Property):
2131    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2134class LikeProperty(Property):
2135    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2138class LocationProperty(Property):
2139    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockingProperty(Property):
2142class LockingProperty(Property):
2143    arg_types = {
2144        "this": False,
2145        "kind": True,
2146        "for_or_in": False,
2147        "lock_type": True,
2148        "override": False,
2149    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2152class LogProperty(Property):
2153    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2156class MaterializedProperty(Property):
2157    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2160class MergeBlockRatioProperty(Property):
2161    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):
2164class NoPrimaryIndexProperty(Property):
2165    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2168class OnProperty(Property):
2169    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2172class OnCommitProperty(Property):
2173    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2176class PartitionedByProperty(Property):
2177    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2181class PartitionBoundSpec(Expression):
2182    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2183    arg_types = {
2184        "this": False,
2185        "expression": False,
2186        "from_expressions": False,
2187        "to_expressions": False,
2188    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2191class PartitionedOfProperty(Property):
2192    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2193    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2196class RemoteWithConnectionModelProperty(Property):
2197    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2200class ReturnsProperty(Property):
2201    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2204class RowFormatProperty(Property):
2205    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2208class RowFormatDelimitedProperty(Property):
2209    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2210    arg_types = {
2211        "fields": False,
2212        "escaped": False,
2213        "collection_items": False,
2214        "map_keys": False,
2215        "lines": False,
2216        "null": False,
2217        "serde": False,
2218    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2221class RowFormatSerdeProperty(Property):
2222    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2226class QueryTransform(Expression):
2227    arg_types = {
2228        "expressions": True,
2229        "command_script": True,
2230        "schema": False,
2231        "row_format_before": False,
2232        "record_writer": False,
2233        "row_format_after": False,
2234        "record_reader": False,
2235    }
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):
2238class SampleProperty(Property):
2239    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2242class SchemaCommentProperty(Property):
2243    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2246class SerdeProperties(Property):
2247    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2250class SetProperty(Property):
2251    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SettingsProperty(Property):
2254class SettingsProperty(Property):
2255    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2258class SortKeyProperty(Property):
2259    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlSecurityProperty(Property):
2262class SqlSecurityProperty(Property):
2263    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2266class StabilityProperty(Property):
2267    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2270class TemporaryProperty(Property):
2271    arg_types = {}
arg_types = {}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2274class TransformModelProperty(Property):
2275    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2278class TransientProperty(Property):
2279    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2282class VolatileProperty(Property):
2283    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2286class WithDataProperty(Property):
2287    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2290class WithJournalTableProperty(Property):
2291    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2294class WithSystemVersioningProperty(Property):
2295    # this -> history table name, expression -> data consistency check
2296    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2299class Properties(Expression):
2300    arg_types = {"expressions": True}
2301
2302    NAME_TO_PROPERTY = {
2303        "ALGORITHM": AlgorithmProperty,
2304        "AUTO_INCREMENT": AutoIncrementProperty,
2305        "CHARACTER SET": CharacterSetProperty,
2306        "CLUSTERED_BY": ClusteredByProperty,
2307        "COLLATE": CollateProperty,
2308        "COMMENT": SchemaCommentProperty,
2309        "DEFINER": DefinerProperty,
2310        "DISTKEY": DistKeyProperty,
2311        "DISTSTYLE": DistStyleProperty,
2312        "ENGINE": EngineProperty,
2313        "EXECUTE AS": ExecuteAsProperty,
2314        "FORMAT": FileFormatProperty,
2315        "LANGUAGE": LanguageProperty,
2316        "LOCATION": LocationProperty,
2317        "PARTITIONED_BY": PartitionedByProperty,
2318        "RETURNS": ReturnsProperty,
2319        "ROW_FORMAT": RowFormatProperty,
2320        "SORTKEY": SortKeyProperty,
2321    }
2322
2323    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2324
2325    # CREATE property locations
2326    # Form: schema specified
2327    #   create [POST_CREATE]
2328    #     table a [POST_NAME]
2329    #     (b int) [POST_SCHEMA]
2330    #     with ([POST_WITH])
2331    #     index (b) [POST_INDEX]
2332    #
2333    # Form: alias selection
2334    #   create [POST_CREATE]
2335    #     table a [POST_NAME]
2336    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2337    #     index (c) [POST_INDEX]
2338    class Location(AutoName):
2339        POST_CREATE = auto()
2340        POST_NAME = auto()
2341        POST_SCHEMA = auto()
2342        POST_WITH = auto()
2343        POST_ALIAS = auto()
2344        POST_EXPRESSION = auto()
2345        POST_INDEX = auto()
2346        UNSUPPORTED = auto()
2347
2348    @classmethod
2349    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2350        expressions = []
2351        for key, value in properties_dict.items():
2352            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2353            if property_cls:
2354                expressions.append(property_cls(this=convert(value)))
2355            else:
2356                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2357
2358        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:
2348    @classmethod
2349    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2350        expressions = []
2351        for key, value in properties_dict.items():
2352            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2353            if property_cls:
2354                expressions.append(property_cls(this=convert(value)))
2355            else:
2356                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2357
2358        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2338    class Location(AutoName):
2339        POST_CREATE = auto()
2340        POST_NAME = auto()
2341        POST_SCHEMA = auto()
2342        POST_WITH = auto()
2343        POST_ALIAS = auto()
2344        POST_EXPRESSION = auto()
2345        POST_INDEX = auto()
2346        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):
2361class Qualify(Expression):
2362    pass
key = 'qualify'
class InputOutputFormat(Expression):
2365class InputOutputFormat(Expression):
2366    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2370class Return(Expression):
2371    pass
key = 'return'
class Reference(Expression):
2374class Reference(Expression):
2375    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2378class Tuple(Expression):
2379    arg_types = {"expressions": False}
2380
2381    def isin(
2382        self,
2383        *expressions: t.Any,
2384        query: t.Optional[ExpOrStr] = None,
2385        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2386        copy: bool = True,
2387        **opts,
2388    ) -> In:
2389        return In(
2390            this=maybe_copy(self, copy),
2391            expressions=[convert(e, copy=copy) for e in expressions],
2392            query=maybe_parse(query, copy=copy, **opts) if query else None,
2393            unnest=Unnest(
2394                expressions=[
2395                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2396                ]
2397            )
2398            if unnest
2399            else None,
2400        )
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:
2381    def isin(
2382        self,
2383        *expressions: t.Any,
2384        query: t.Optional[ExpOrStr] = None,
2385        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2386        copy: bool = True,
2387        **opts,
2388    ) -> In:
2389        return In(
2390            this=maybe_copy(self, copy),
2391            expressions=[convert(e, copy=copy) for e in expressions],
2392            query=maybe_parse(query, copy=copy, **opts) if query else None,
2393            unnest=Unnest(
2394                expressions=[
2395                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2396                ]
2397            )
2398            if unnest
2399            else None,
2400        )
key = 'tuple'
class Subqueryable(Unionable):
2403class Subqueryable(Unionable):
2404    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2405        """
2406        Convert this expression to an aliased expression that can be used as a Subquery.
2407
2408        Example:
2409            >>> subquery = Select().select("x").from_("tbl").subquery()
2410            >>> Select().select("x").from_(subquery).sql()
2411            'SELECT x FROM (SELECT x FROM tbl)'
2412
2413        Args:
2414            alias (str | Identifier): an optional alias for the subquery
2415            copy (bool): if `False`, modify this expression instance in-place.
2416
2417        Returns:
2418            Alias: the subquery
2419        """
2420        instance = maybe_copy(self, copy)
2421        if not isinstance(alias, Expression):
2422            alias = TableAlias(this=to_identifier(alias)) if alias else None
2423
2424        return Subquery(this=instance, alias=alias)
2425
2426    def limit(
2427        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2428    ) -> Select:
2429        raise NotImplementedError
2430
2431    @property
2432    def ctes(self):
2433        with_ = self.args.get("with")
2434        if not with_:
2435            return []
2436        return with_.expressions
2437
2438    @property
2439    def selects(self) -> t.List[Expression]:
2440        raise NotImplementedError("Subqueryable objects must implement `selects`")
2441
2442    @property
2443    def named_selects(self) -> t.List[str]:
2444        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2445
2446    def select(
2447        self,
2448        *expressions: t.Optional[ExpOrStr],
2449        append: bool = True,
2450        dialect: DialectType = None,
2451        copy: bool = True,
2452        **opts,
2453    ) -> Subqueryable:
2454        raise NotImplementedError("Subqueryable objects must implement `select`")
2455
2456    def with_(
2457        self,
2458        alias: ExpOrStr,
2459        as_: ExpOrStr,
2460        recursive: t.Optional[bool] = None,
2461        append: bool = True,
2462        dialect: DialectType = None,
2463        copy: bool = True,
2464        **opts,
2465    ) -> Subqueryable:
2466        """
2467        Append to or set the common table expressions.
2468
2469        Example:
2470            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2471            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2472
2473        Args:
2474            alias: the SQL code string to parse as the table name.
2475                If an `Expression` instance is passed, this is used as-is.
2476            as_: the SQL code string to parse as the table expression.
2477                If an `Expression` instance is passed, it will be used as-is.
2478            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2479            append: if `True`, add to any existing expressions.
2480                Otherwise, this resets the expressions.
2481            dialect: the dialect used to parse the input expression.
2482            copy: if `False`, modify this expression instance in-place.
2483            opts: other options to use to parse the input expressions.
2484
2485        Returns:
2486            The modified expression.
2487        """
2488        return _apply_cte_builder(
2489            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2490        )
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
2404    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2405        """
2406        Convert this expression to an aliased expression that can be used as a Subquery.
2407
2408        Example:
2409            >>> subquery = Select().select("x").from_("tbl").subquery()
2410            >>> Select().select("x").from_(subquery).sql()
2411            'SELECT x FROM (SELECT x FROM tbl)'
2412
2413        Args:
2414            alias (str | Identifier): an optional alias for the subquery
2415            copy (bool): if `False`, modify this expression instance in-place.
2416
2417        Returns:
2418            Alias: the subquery
2419        """
2420        instance = maybe_copy(self, copy)
2421        if not isinstance(alias, Expression):
2422            alias = TableAlias(this=to_identifier(alias)) if alias else None
2423
2424        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:
2426    def limit(
2427        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2428    ) -> Select:
2429        raise NotImplementedError
ctes
2431    @property
2432    def ctes(self):
2433        with_ = self.args.get("with")
2434        if not with_:
2435            return []
2436        return with_.expressions
selects: List[Expression]
2438    @property
2439    def selects(self) -> t.List[Expression]:
2440        raise NotImplementedError("Subqueryable objects must implement `selects`")
named_selects: List[str]
2442    @property
2443    def named_selects(self) -> t.List[str]:
2444        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:
2446    def select(
2447        self,
2448        *expressions: t.Optional[ExpOrStr],
2449        append: bool = True,
2450        dialect: DialectType = None,
2451        copy: bool = True,
2452        **opts,
2453    ) -> Subqueryable:
2454        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:
2456    def with_(
2457        self,
2458        alias: ExpOrStr,
2459        as_: ExpOrStr,
2460        recursive: t.Optional[bool] = None,
2461        append: bool = True,
2462        dialect: DialectType = None,
2463        copy: bool = True,
2464        **opts,
2465    ) -> Subqueryable:
2466        """
2467        Append to or set the common table expressions.
2468
2469        Example:
2470            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2471            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2472
2473        Args:
2474            alias: the SQL code string to parse as the table name.
2475                If an `Expression` instance is passed, this is used as-is.
2476            as_: the SQL code string to parse as the table expression.
2477                If an `Expression` instance is passed, it will be used as-is.
2478            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2479            append: if `True`, add to any existing expressions.
2480                Otherwise, this resets the expressions.
2481            dialect: the dialect used to parse the input expression.
2482            copy: if `False`, modify this expression instance in-place.
2483            opts: other options to use to parse the input expressions.
2484
2485        Returns:
2486            The modified expression.
2487        """
2488        return _apply_cte_builder(
2489            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2490        )

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

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

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

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

Checks whether an expression is a star.

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

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

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

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

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

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

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

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:
3026    def select(
3027        self,
3028        *expressions: t.Optional[ExpOrStr],
3029        append: bool = True,
3030        dialect: DialectType = None,
3031        copy: bool = True,
3032        **opts,
3033    ) -> Select:
3034        """
3035        Append to or set the SELECT expressions.
3036
3037        Example:
3038            >>> Select().select("x", "y").sql()
3039            'SELECT x, y'
3040
3041        Args:
3042            *expressions: the SQL code strings to parse.
3043                If an `Expression` instance is passed, it will be used as-is.
3044            append: if `True`, add to any existing expressions.
3045                Otherwise, this resets the expressions.
3046            dialect: the dialect used to parse the input expressions.
3047            copy: if `False`, modify this expression instance in-place.
3048            opts: other options to use to parse the input expressions.
3049
3050        Returns:
3051            The modified Select expression.
3052        """
3053        return _apply_list_builder(
3054            *expressions,
3055            instance=self,
3056            arg="expressions",
3057            append=append,
3058            dialect=dialect,
3059            copy=copy,
3060            **opts,
3061        )

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

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

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

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

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

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

Checks whether an expression is a star.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
3460    def unwrap(self) -> Subquery:
3461        expression = self
3462        while expression.same_parent and expression.is_wrapper:
3463            expression = t.cast(Subquery, expression.parent)
3464        return expression
is_wrapper: bool
3466    @property
3467    def is_wrapper(self) -> bool:
3468        """
3469        Whether this Subquery acts as a simple wrapper around another expression.
3470
3471        SELECT * FROM (((SELECT * FROM t)))
3472                      ^
3473                      This corresponds to a "wrapper" Subquery node
3474        """
3475        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
3477    @property
3478    def is_star(self) -> bool:
3479        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3481    @property
3482    def output_name(self) -> str:
3483        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):
3486class TableSample(Expression):
3487    arg_types = {
3488        "this": False,
3489        "expressions": False,
3490        "method": False,
3491        "bucket_numerator": False,
3492        "bucket_denominator": False,
3493        "bucket_field": False,
3494        "percent": False,
3495        "rows": False,
3496        "size": False,
3497        "seed": False,
3498    }
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):
3501class Tag(Expression):
3502    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3503
3504    arg_types = {
3505        "this": False,
3506        "prefix": False,
3507        "postfix": False,
3508    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3513class Pivot(Expression):
3514    arg_types = {
3515        "this": False,
3516        "alias": False,
3517        "expressions": False,
3518        "field": False,
3519        "unpivot": False,
3520        "using": False,
3521        "group": False,
3522        "columns": False,
3523        "include_nulls": False,
3524    }
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):
3527class Window(Condition):
3528    arg_types = {
3529        "this": True,
3530        "partition_by": False,
3531        "order": False,
3532        "spec": False,
3533        "alias": False,
3534        "over": False,
3535        "first": False,
3536    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3539class WindowSpec(Expression):
3540    arg_types = {
3541        "kind": False,
3542        "start": False,
3543        "start_side": False,
3544        "end": False,
3545        "end_side": False,
3546    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3549class Where(Expression):
3550    pass
key = 'where'
class Star(Expression):
3553class Star(Expression):
3554    arg_types = {"except": False, "replace": False}
3555
3556    @property
3557    def name(self) -> str:
3558        return "*"
3559
3560    @property
3561    def output_name(self) -> str:
3562        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3556    @property
3557    def name(self) -> str:
3558        return "*"
output_name: str
3560    @property
3561    def output_name(self) -> str:
3562        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):
3565class Parameter(Condition):
3566    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3569class SessionParameter(Condition):
3570    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3573class Placeholder(Condition):
3574    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3577class Null(Condition):
3578    arg_types: t.Dict[str, t.Any] = {}
3579
3580    @property
3581    def name(self) -> str:
3582        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3580    @property
3581    def name(self) -> str:
3582        return "NULL"
key = 'null'
class Boolean(Condition):
3585class Boolean(Condition):
3586    pass
key = 'boolean'
class DataTypeParam(Expression):
3589class DataTypeParam(Expression):
3590    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3593class DataType(Expression):
3594    arg_types = {
3595        "this": True,
3596        "expressions": False,
3597        "nested": False,
3598        "values": False,
3599        "prefix": False,
3600        "kind": False,
3601    }
3602
3603    class Type(AutoName):
3604        ARRAY = auto()
3605        BIGDECIMAL = auto()
3606        BIGINT = auto()
3607        BIGSERIAL = auto()
3608        BINARY = auto()
3609        BIT = auto()
3610        BOOLEAN = auto()
3611        CHAR = auto()
3612        DATE = auto()
3613        DATEMULTIRANGE = auto()
3614        DATERANGE = auto()
3615        DATETIME = auto()
3616        DATETIME64 = auto()
3617        DECIMAL = auto()
3618        DOUBLE = auto()
3619        ENUM = auto()
3620        ENUM8 = auto()
3621        ENUM16 = auto()
3622        FIXEDSTRING = auto()
3623        FLOAT = auto()
3624        GEOGRAPHY = auto()
3625        GEOMETRY = auto()
3626        HLLSKETCH = auto()
3627        HSTORE = auto()
3628        IMAGE = auto()
3629        INET = auto()
3630        INT = auto()
3631        INT128 = auto()
3632        INT256 = auto()
3633        INT4MULTIRANGE = auto()
3634        INT4RANGE = auto()
3635        INT8MULTIRANGE = auto()
3636        INT8RANGE = auto()
3637        INTERVAL = auto()
3638        IPADDRESS = auto()
3639        IPPREFIX = auto()
3640        JSON = auto()
3641        JSONB = auto()
3642        LONGBLOB = auto()
3643        LONGTEXT = auto()
3644        LOWCARDINALITY = auto()
3645        MAP = auto()
3646        MEDIUMBLOB = auto()
3647        MEDIUMINT = auto()
3648        MEDIUMTEXT = auto()
3649        MONEY = auto()
3650        NCHAR = auto()
3651        NESTED = auto()
3652        NULL = auto()
3653        NULLABLE = auto()
3654        NUMMULTIRANGE = auto()
3655        NUMRANGE = auto()
3656        NVARCHAR = auto()
3657        OBJECT = auto()
3658        ROWVERSION = auto()
3659        SERIAL = auto()
3660        SET = auto()
3661        SMALLINT = auto()
3662        SMALLMONEY = auto()
3663        SMALLSERIAL = auto()
3664        STRUCT = auto()
3665        SUPER = auto()
3666        TEXT = auto()
3667        TINYBLOB = auto()
3668        TINYTEXT = auto()
3669        TIME = auto()
3670        TIMETZ = auto()
3671        TIMESTAMP = auto()
3672        TIMESTAMPLTZ = auto()
3673        TIMESTAMPTZ = auto()
3674        TIMESTAMP_S = auto()
3675        TIMESTAMP_MS = auto()
3676        TIMESTAMP_NS = auto()
3677        TINYINT = auto()
3678        TSMULTIRANGE = auto()
3679        TSRANGE = auto()
3680        TSTZMULTIRANGE = auto()
3681        TSTZRANGE = auto()
3682        UBIGINT = auto()
3683        UINT = auto()
3684        UINT128 = auto()
3685        UINT256 = auto()
3686        UMEDIUMINT = auto()
3687        UDECIMAL = auto()
3688        UNIQUEIDENTIFIER = auto()
3689        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3690        USERDEFINED = "USER-DEFINED"
3691        USMALLINT = auto()
3692        UTINYINT = auto()
3693        UUID = auto()
3694        VARBINARY = auto()
3695        VARCHAR = auto()
3696        VARIANT = auto()
3697        XML = auto()
3698        YEAR = auto()
3699
3700    TEXT_TYPES = {
3701        Type.CHAR,
3702        Type.NCHAR,
3703        Type.VARCHAR,
3704        Type.NVARCHAR,
3705        Type.TEXT,
3706    }
3707
3708    INTEGER_TYPES = {
3709        Type.INT,
3710        Type.TINYINT,
3711        Type.SMALLINT,
3712        Type.BIGINT,
3713        Type.INT128,
3714        Type.INT256,
3715        Type.BIT,
3716    }
3717
3718    FLOAT_TYPES = {
3719        Type.FLOAT,
3720        Type.DOUBLE,
3721    }
3722
3723    NUMERIC_TYPES = {
3724        *INTEGER_TYPES,
3725        *FLOAT_TYPES,
3726    }
3727
3728    TEMPORAL_TYPES = {
3729        Type.TIME,
3730        Type.TIMETZ,
3731        Type.TIMESTAMP,
3732        Type.TIMESTAMPTZ,
3733        Type.TIMESTAMPLTZ,
3734        Type.TIMESTAMP_S,
3735        Type.TIMESTAMP_MS,
3736        Type.TIMESTAMP_NS,
3737        Type.DATE,
3738        Type.DATETIME,
3739        Type.DATETIME64,
3740    }
3741
3742    @classmethod
3743    def build(
3744        cls,
3745        dtype: DATA_TYPE,
3746        dialect: DialectType = None,
3747        udt: bool = False,
3748        **kwargs,
3749    ) -> DataType:
3750        """
3751        Constructs a DataType object.
3752
3753        Args:
3754            dtype: the data type of interest.
3755            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3756            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3757                DataType, thus creating a user-defined type.
3758            kawrgs: additional arguments to pass in the constructor of DataType.
3759
3760        Returns:
3761            The constructed DataType object.
3762        """
3763        from sqlglot import parse_one
3764
3765        if isinstance(dtype, str):
3766            if dtype.upper() == "UNKNOWN":
3767                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3768
3769            try:
3770                data_type_exp = parse_one(
3771                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3772                )
3773            except ParseError:
3774                if udt:
3775                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3776                raise
3777        elif isinstance(dtype, DataType.Type):
3778            data_type_exp = DataType(this=dtype)
3779        elif isinstance(dtype, DataType):
3780            return dtype
3781        else:
3782            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3783
3784        return DataType(**{**data_type_exp.args, **kwargs})
3785
3786    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3787        """
3788        Checks whether this DataType matches one of the provided data types. Nested types or precision
3789        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3790
3791        Args:
3792            dtypes: the data types to compare this DataType to.
3793
3794        Returns:
3795            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3796        """
3797        for dtype in dtypes:
3798            other = DataType.build(dtype, udt=True)
3799
3800            if (
3801                other.expressions
3802                or self.this == DataType.Type.USERDEFINED
3803                or other.this == DataType.Type.USERDEFINED
3804            ):
3805                matches = self == other
3806            else:
3807                matches = self.this == other.this
3808
3809            if matches:
3810                return True
3811        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NCHAR: 'NCHAR'>}
INTEGER_TYPES = {<Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.BIT: 'BIT'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.BIT: 'BIT'>, <Type.INT128: 'INT128'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.DOUBLE: 'DOUBLE'>}
TEMPORAL_TYPES = {<Type.TIME: 'TIME'>, <Type.DATETIME: 'DATETIME'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <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:
3742    @classmethod
3743    def build(
3744        cls,
3745        dtype: DATA_TYPE,
3746        dialect: DialectType = None,
3747        udt: bool = False,
3748        **kwargs,
3749    ) -> DataType:
3750        """
3751        Constructs a DataType object.
3752
3753        Args:
3754            dtype: the data type of interest.
3755            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3756            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3757                DataType, thus creating a user-defined type.
3758            kawrgs: additional arguments to pass in the constructor of DataType.
3759
3760        Returns:
3761            The constructed DataType object.
3762        """
3763        from sqlglot import parse_one
3764
3765        if isinstance(dtype, str):
3766            if dtype.upper() == "UNKNOWN":
3767                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3768
3769            try:
3770                data_type_exp = parse_one(
3771                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3772                )
3773            except ParseError:
3774                if udt:
3775                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3776                raise
3777        elif isinstance(dtype, DataType.Type):
3778            data_type_exp = DataType(this=dtype)
3779        elif isinstance(dtype, DataType):
3780            return dtype
3781        else:
3782            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3783
3784        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:
3786    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3787        """
3788        Checks whether this DataType matches one of the provided data types. Nested types or precision
3789        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3790
3791        Args:
3792            dtypes: the data types to compare this DataType to.
3793
3794        Returns:
3795            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3796        """
3797        for dtype in dtypes:
3798            other = DataType.build(dtype, udt=True)
3799
3800            if (
3801                other.expressions
3802                or self.this == DataType.Type.USERDEFINED
3803                or other.this == DataType.Type.USERDEFINED
3804            ):
3805                matches = self == other
3806            else:
3807                matches = self.this == other.this
3808
3809            if matches:
3810                return True
3811        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):
3603    class Type(AutoName):
3604        ARRAY = auto()
3605        BIGDECIMAL = auto()
3606        BIGINT = auto()
3607        BIGSERIAL = auto()
3608        BINARY = auto()
3609        BIT = auto()
3610        BOOLEAN = auto()
3611        CHAR = auto()
3612        DATE = auto()
3613        DATEMULTIRANGE = auto()
3614        DATERANGE = auto()
3615        DATETIME = auto()
3616        DATETIME64 = auto()
3617        DECIMAL = auto()
3618        DOUBLE = auto()
3619        ENUM = auto()
3620        ENUM8 = auto()
3621        ENUM16 = auto()
3622        FIXEDSTRING = auto()
3623        FLOAT = auto()
3624        GEOGRAPHY = auto()
3625        GEOMETRY = auto()
3626        HLLSKETCH = auto()
3627        HSTORE = auto()
3628        IMAGE = auto()
3629        INET = auto()
3630        INT = auto()
3631        INT128 = auto()
3632        INT256 = auto()
3633        INT4MULTIRANGE = auto()
3634        INT4RANGE = auto()
3635        INT8MULTIRANGE = auto()
3636        INT8RANGE = auto()
3637        INTERVAL = auto()
3638        IPADDRESS = auto()
3639        IPPREFIX = auto()
3640        JSON = auto()
3641        JSONB = auto()
3642        LONGBLOB = auto()
3643        LONGTEXT = auto()
3644        LOWCARDINALITY = auto()
3645        MAP = auto()
3646        MEDIUMBLOB = auto()
3647        MEDIUMINT = auto()
3648        MEDIUMTEXT = auto()
3649        MONEY = auto()
3650        NCHAR = auto()
3651        NESTED = auto()
3652        NULL = auto()
3653        NULLABLE = auto()
3654        NUMMULTIRANGE = auto()
3655        NUMRANGE = auto()
3656        NVARCHAR = auto()
3657        OBJECT = auto()
3658        ROWVERSION = auto()
3659        SERIAL = auto()
3660        SET = auto()
3661        SMALLINT = auto()
3662        SMALLMONEY = auto()
3663        SMALLSERIAL = auto()
3664        STRUCT = auto()
3665        SUPER = auto()
3666        TEXT = auto()
3667        TINYBLOB = auto()
3668        TINYTEXT = auto()
3669        TIME = auto()
3670        TIMETZ = auto()
3671        TIMESTAMP = auto()
3672        TIMESTAMPLTZ = auto()
3673        TIMESTAMPTZ = auto()
3674        TIMESTAMP_S = auto()
3675        TIMESTAMP_MS = auto()
3676        TIMESTAMP_NS = auto()
3677        TINYINT = auto()
3678        TSMULTIRANGE = auto()
3679        TSRANGE = auto()
3680        TSTZMULTIRANGE = auto()
3681        TSTZRANGE = auto()
3682        UBIGINT = auto()
3683        UINT = auto()
3684        UINT128 = auto()
3685        UINT256 = auto()
3686        UMEDIUMINT = auto()
3687        UDECIMAL = auto()
3688        UNIQUEIDENTIFIER = auto()
3689        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3690        USERDEFINED = "USER-DEFINED"
3691        USMALLINT = auto()
3692        UTINYINT = auto()
3693        UUID = auto()
3694        VARBINARY = auto()
3695        VARCHAR = auto()
3696        VARIANT = auto()
3697        XML = auto()
3698        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):
3818class PseudoType(DataType):
3819    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3823class ObjectIdentifier(DataType):
3824    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3828class SubqueryPredicate(Predicate):
3829    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3832class All(SubqueryPredicate):
3833    pass
key = 'all'
class Any(SubqueryPredicate):
3836class Any(SubqueryPredicate):
3837    pass
key = 'any'
class Exists(SubqueryPredicate):
3840class Exists(SubqueryPredicate):
3841    pass
key = 'exists'
class Command(Expression):
3846class Command(Expression):
3847    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3850class Transaction(Expression):
3851    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3854class Commit(Expression):
3855    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3858class Rollback(Expression):
3859    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3862class AlterTable(Expression):
3863    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):
3866class AddConstraint(Expression):
3867    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3870class DropPartition(Expression):
3871    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3875class Binary(Condition):
3876    arg_types = {"this": True, "expression": True}
3877
3878    @property
3879    def left(self) -> Expression:
3880        return self.this
3881
3882    @property
3883    def right(self) -> Expression:
3884        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
3878    @property
3879    def left(self) -> Expression:
3880        return self.this
right: Expression
3882    @property
3883    def right(self) -> Expression:
3884        return self.expression
key = 'binary'
class Add(Binary):
3887class Add(Binary):
3888    pass
key = 'add'
class Connector(Binary):
3891class Connector(Binary):
3892    pass
key = 'connector'
class And(Connector):
3895class And(Connector):
3896    pass
key = 'and'
class Or(Connector):
3899class Or(Connector):
3900    pass
key = 'or'
class BitwiseAnd(Binary):
3903class BitwiseAnd(Binary):
3904    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3907class BitwiseLeftShift(Binary):
3908    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3911class BitwiseOr(Binary):
3912    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3915class BitwiseRightShift(Binary):
3916    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3919class BitwiseXor(Binary):
3920    pass
key = 'bitwisexor'
class Div(Binary):
3923class Div(Binary):
3924    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):
3927class Overlaps(Binary):
3928    pass
key = 'overlaps'
class Dot(Binary):
3931class Dot(Binary):
3932    @property
3933    def name(self) -> str:
3934        return self.expression.name
3935
3936    @property
3937    def output_name(self) -> str:
3938        return self.name
3939
3940    @classmethod
3941    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3942        """Build a Dot object with a sequence of expressions."""
3943        if len(expressions) < 2:
3944            raise ValueError(f"Dot requires >= 2 expressions.")
3945
3946        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
3947
3948    @property
3949    def parts(self) -> t.List[Expression]:
3950        """Return the parts of a table / column in order catalog, db, table."""
3951        this, *parts = self.flatten()
3952
3953        parts.reverse()
3954
3955        for arg in ("this", "table", "db", "catalog"):
3956            part = this.args.get(arg)
3957
3958            if isinstance(part, Expression):
3959                parts.append(part)
3960
3961        parts.reverse()
3962        return parts
name: str
3932    @property
3933    def name(self) -> str:
3934        return self.expression.name
output_name: str
3936    @property
3937    def output_name(self) -> str:
3938        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:
3940    @classmethod
3941    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3942        """Build a Dot object with a sequence of expressions."""
3943        if len(expressions) < 2:
3944            raise ValueError(f"Dot requires >= 2 expressions.")
3945
3946        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]
3948    @property
3949    def parts(self) -> t.List[Expression]:
3950        """Return the parts of a table / column in order catalog, db, table."""
3951        this, *parts = self.flatten()
3952
3953        parts.reverse()
3954
3955        for arg in ("this", "table", "db", "catalog"):
3956            part = this.args.get(arg)
3957
3958            if isinstance(part, Expression):
3959                parts.append(part)
3960
3961        parts.reverse()
3962        return parts

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

key = 'dot'
class DPipe(Binary):
3965class DPipe(Binary):
3966    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
3969class EQ(Binary, Predicate):
3970    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
3973class NullSafeEQ(Binary, Predicate):
3974    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
3977class NullSafeNEQ(Binary, Predicate):
3978    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
3982class PropertyEQ(Binary):
3983    pass
key = 'propertyeq'
class Distance(Binary):
3986class Distance(Binary):
3987    pass
key = 'distance'
class Escape(Binary):
3990class Escape(Binary):
3991    pass
key = 'escape'
class Glob(Binary, Predicate):
3994class Glob(Binary, Predicate):
3995    pass
key = 'glob'
class GT(Binary, Predicate):
3998class GT(Binary, Predicate):
3999    pass
key = 'gt'
class GTE(Binary, Predicate):
4002class GTE(Binary, Predicate):
4003    pass
key = 'gte'
class ILike(Binary, Predicate):
4006class ILike(Binary, Predicate):
4007    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4010class ILikeAny(Binary, Predicate):
4011    pass
key = 'ilikeany'
class IntDiv(Binary):
4014class IntDiv(Binary):
4015    pass
key = 'intdiv'
class Is(Binary, Predicate):
4018class Is(Binary, Predicate):
4019    pass
key = 'is'
class Kwarg(Binary):
4022class Kwarg(Binary):
4023    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4026class Like(Binary, Predicate):
4027    pass
key = 'like'
class LikeAny(Binary, Predicate):
4030class LikeAny(Binary, Predicate):
4031    pass
key = 'likeany'
class LT(Binary, Predicate):
4034class LT(Binary, Predicate):
4035    pass
key = 'lt'
class LTE(Binary, Predicate):
4038class LTE(Binary, Predicate):
4039    pass
key = 'lte'
class Mod(Binary):
4042class Mod(Binary):
4043    pass
key = 'mod'
class Mul(Binary):
4046class Mul(Binary):
4047    pass
key = 'mul'
class NEQ(Binary, Predicate):
4050class NEQ(Binary, Predicate):
4051    pass
key = 'neq'
class Operator(Binary):
4055class Operator(Binary):
4056    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4059class SimilarTo(Binary, Predicate):
4060    pass
key = 'similarto'
class Slice(Binary):
4063class Slice(Binary):
4064    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4067class Sub(Binary):
4068    pass
key = 'sub'
class ArrayOverlaps(Binary):
4071class ArrayOverlaps(Binary):
4072    pass
key = 'arrayoverlaps'
class Unary(Condition):
4077class Unary(Condition):
4078    pass
key = 'unary'
class BitwiseNot(Unary):
4081class BitwiseNot(Unary):
4082    pass
key = 'bitwisenot'
class Not(Unary):
4085class Not(Unary):
4086    pass
key = 'not'
class Paren(Unary):
4089class Paren(Unary):
4090    arg_types = {"this": True, "with": False}
4091
4092    @property
4093    def output_name(self) -> str:
4094        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4092    @property
4093    def output_name(self) -> str:
4094        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):
4097class Neg(Unary):
4098    pass
key = 'neg'
class Alias(Expression):
4101class Alias(Expression):
4102    arg_types = {"this": True, "alias": False}
4103
4104    @property
4105    def output_name(self) -> str:
4106        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4104    @property
4105    def output_name(self) -> str:
4106        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):
4109class Aliases(Expression):
4110    arg_types = {"this": True, "expressions": True}
4111
4112    @property
4113    def aliases(self):
4114        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4112    @property
4113    def aliases(self):
4114        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4118class AtIndex(Expression):
4119    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4122class AtTimeZone(Expression):
4123    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
4126class Between(Predicate):
4127    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4130class Bracket(Condition):
4131    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4132    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4133
4134    @property
4135    def output_name(self) -> str:
4136        if len(self.expressions) == 1:
4137            return self.expressions[0].output_name
4138
4139        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4134    @property
4135    def output_name(self) -> str:
4136        if len(self.expressions) == 1:
4137            return self.expressions[0].output_name
4138
4139        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):
4142class Distinct(Expression):
4143    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4146class In(Predicate):
4147    arg_types = {
4148        "this": True,
4149        "expressions": False,
4150        "query": False,
4151        "unnest": False,
4152        "field": False,
4153        "is_global": False,
4154    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4158class ForIn(Expression):
4159    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4162class TimeUnit(Expression):
4163    """Automatically converts unit arg into a var."""
4164
4165    arg_types = {"unit": False}
4166
4167    UNABBREVIATED_UNIT_NAME = {
4168        "D": "DAY",
4169        "H": "HOUR",
4170        "M": "MINUTE",
4171        "MS": "MILLISECOND",
4172        "NS": "NANOSECOND",
4173        "Q": "QUARTER",
4174        "S": "SECOND",
4175        "US": "MICROSECOND",
4176        "W": "WEEK",
4177        "Y": "YEAR",
4178    }
4179
4180    VAR_LIKE = (Column, Literal, Var)
4181
4182    def __init__(self, **args):
4183        unit = args.get("unit")
4184        if isinstance(unit, self.VAR_LIKE):
4185            args["unit"] = Var(
4186                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4187            )
4188        elif isinstance(unit, Week):
4189            unit.set("this", Var(this=unit.this.name.upper()))
4190
4191        super().__init__(**args)
4192
4193    @property
4194    def unit(self) -> t.Optional[Var]:
4195        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4182    def __init__(self, **args):
4183        unit = args.get("unit")
4184        if isinstance(unit, self.VAR_LIKE):
4185            args["unit"] = Var(
4186                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4187            )
4188        elif isinstance(unit, Week):
4189            unit.set("this", Var(this=unit.this.name.upper()))
4190
4191        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]
4193    @property
4194    def unit(self) -> t.Optional[Var]:
4195        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4198class IntervalOp(TimeUnit):
4199    arg_types = {"unit": True, "expression": True}
4200
4201    def interval(self):
4202        return Interval(
4203            this=self.expression.copy(),
4204            unit=self.unit.copy(),
4205        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4201    def interval(self):
4202        return Interval(
4203            this=self.expression.copy(),
4204            unit=self.unit.copy(),
4205        )
key = 'intervalop'
class IntervalSpan(DataType):
4211class IntervalSpan(DataType):
4212    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4215class Interval(TimeUnit):
4216    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4219class IgnoreNulls(Expression):
4220    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4223class RespectNulls(Expression):
4224    pass
key = 'respectnulls'
class Func(Condition):
4228class Func(Condition):
4229    """
4230    The base class for all function expressions.
4231
4232    Attributes:
4233        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4234            treated as a variable length argument and the argument's value will be stored as a list.
4235        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4236            for this function expression. These values are used to map this node to a name during parsing
4237            as well as to provide the function's name during SQL string generation. By default the SQL
4238            name is set to the expression's class name transformed to snake case.
4239    """
4240
4241    is_var_len_args = False
4242
4243    @classmethod
4244    def from_arg_list(cls, args):
4245        if cls.is_var_len_args:
4246            all_arg_keys = list(cls.arg_types)
4247            # If this function supports variable length argument treat the last argument as such.
4248            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4249            num_non_var = len(non_var_len_arg_keys)
4250
4251            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4252            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4253        else:
4254            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4255
4256        return cls(**args_dict)
4257
4258    @classmethod
4259    def sql_names(cls):
4260        if cls is Func:
4261            raise NotImplementedError(
4262                "SQL name is only supported by concrete function implementations"
4263            )
4264        if "_sql_names" not in cls.__dict__:
4265            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4266        return cls._sql_names
4267
4268    @classmethod
4269    def sql_name(cls):
4270        return cls.sql_names()[0]
4271
4272    @classmethod
4273    def default_parser_mappings(cls):
4274        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):
4243    @classmethod
4244    def from_arg_list(cls, args):
4245        if cls.is_var_len_args:
4246            all_arg_keys = list(cls.arg_types)
4247            # If this function supports variable length argument treat the last argument as such.
4248            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4249            num_non_var = len(non_var_len_arg_keys)
4250
4251            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4252            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4253        else:
4254            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4255
4256        return cls(**args_dict)
@classmethod
def sql_names(cls):
4258    @classmethod
4259    def sql_names(cls):
4260        if cls is Func:
4261            raise NotImplementedError(
4262                "SQL name is only supported by concrete function implementations"
4263            )
4264        if "_sql_names" not in cls.__dict__:
4265            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4266        return cls._sql_names
@classmethod
def sql_name(cls):
4268    @classmethod
4269    def sql_name(cls):
4270        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4272    @classmethod
4273    def default_parser_mappings(cls):
4274        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4277class AggFunc(Func):
4278    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4281class ParameterizedAgg(AggFunc):
4282    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4285class Abs(Func):
4286    pass
key = 'abs'
class ArgMax(AggFunc):
4289class ArgMax(AggFunc):
4290    arg_types = {"this": True, "expression": True, "count": False}
4291    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4294class ArgMin(AggFunc):
4295    arg_types = {"this": True, "expression": True, "count": False}
4296    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4299class ApproxTopK(AggFunc):
4300    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4303class Flatten(Func):
4304    pass
key = 'flatten'
class Transform(Func):
4308class Transform(Func):
4309    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4312class Anonymous(Func):
4313    arg_types = {"this": True, "expressions": False}
4314    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4317class AnonymousAggFunc(AggFunc):
4318    arg_types = {"this": True, "expressions": False}
4319    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4323class CombinedAggFunc(AnonymousAggFunc):
4324    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4327class CombinedParameterizedAgg(ParameterizedAgg):
4328    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):
4333class Hll(AggFunc):
4334    arg_types = {"this": True, "expressions": False}
4335    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4338class ApproxDistinct(AggFunc):
4339    arg_types = {"this": True, "accuracy": False}
4340    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4343class Array(Func):
4344    arg_types = {"expressions": False}
4345    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4349class ToArray(Func):
4350    pass
key = 'toarray'
class ToChar(Func):
4355class ToChar(Func):
4356    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4359class GenerateSeries(Func):
4360    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4363class ArrayAgg(AggFunc):
4364    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4367class ArrayUniqueAgg(AggFunc):
4368    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4371class ArrayAll(Func):
4372    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4375class ArrayAny(Func):
4376    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4379class ArrayConcat(Func):
4380    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4381    arg_types = {"this": True, "expressions": False}
4382    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4385class ArrayContains(Binary, Func):
4386    pass
key = 'arraycontains'
class ArrayContained(Binary):
4389class ArrayContained(Binary):
4390    pass
key = 'arraycontained'
class ArrayFilter(Func):
4393class ArrayFilter(Func):
4394    arg_types = {"this": True, "expression": True}
4395    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4398class ArrayJoin(Func):
4399    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4402class ArraySize(Func):
4403    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4406class ArraySort(Func):
4407    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4410class ArraySum(Func):
4411    pass
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4414class ArrayUnionAgg(AggFunc):
4415    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4418class Avg(AggFunc):
4419    pass
key = 'avg'
class AnyValue(AggFunc):
4422class AnyValue(AggFunc):
4423    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):
4426class First(Func):
4427    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4430class Last(Func):
4431    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4434class Case(Func):
4435    arg_types = {"this": False, "ifs": True, "default": False}
4436
4437    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4438        instance = maybe_copy(self, copy)
4439        instance.append(
4440            "ifs",
4441            If(
4442                this=maybe_parse(condition, copy=copy, **opts),
4443                true=maybe_parse(then, copy=copy, **opts),
4444            ),
4445        )
4446        return instance
4447
4448    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4449        instance = maybe_copy(self, copy)
4450        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4451        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:
4437    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4438        instance = maybe_copy(self, copy)
4439        instance.append(
4440            "ifs",
4441            If(
4442                this=maybe_parse(condition, copy=copy, **opts),
4443                true=maybe_parse(then, copy=copy, **opts),
4444            ),
4445        )
4446        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4448    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4449        instance = maybe_copy(self, copy)
4450        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4451        return instance
key = 'case'
class Cast(Func):
4454class Cast(Func):
4455    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4456
4457    @property
4458    def name(self) -> str:
4459        return self.this.name
4460
4461    @property
4462    def to(self) -> DataType:
4463        return self.args["to"]
4464
4465    @property
4466    def output_name(self) -> str:
4467        return self.name
4468
4469    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4470        """
4471        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4472        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4473        array<int> != array<float>.
4474
4475        Args:
4476            dtypes: the data types to compare this Cast's DataType to.
4477
4478        Returns:
4479            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4480        """
4481        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4457    @property
4458    def name(self) -> str:
4459        return self.this.name
to: DataType
4461    @property
4462    def to(self) -> DataType:
4463        return self.args["to"]
output_name: str
4465    @property
4466    def output_name(self) -> str:
4467        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:
4469    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4470        """
4471        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4472        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4473        array<int> != array<float>.
4474
4475        Args:
4476            dtypes: the data types to compare this Cast's DataType to.
4477
4478        Returns:
4479            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4480        """
4481        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):
4484class TryCast(Cast):
4485    pass
key = 'trycast'
class CastToStrType(Func):
4488class CastToStrType(Func):
4489    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4492class Collate(Binary, Func):
4493    pass
key = 'collate'
class Ceil(Func):
4496class Ceil(Func):
4497    arg_types = {"this": True, "decimals": False}
4498    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4501class Coalesce(Func):
4502    arg_types = {"this": True, "expressions": False}
4503    is_var_len_args = True
4504    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4507class Chr(Func):
4508    arg_types = {"this": True, "charset": False, "expressions": False}
4509    is_var_len_args = True
4510    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4513class Concat(Func):
4514    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4515    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4518class ConcatWs(Concat):
4519    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4522class Count(AggFunc):
4523    arg_types = {"this": False, "expressions": False}
4524    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4527class CountIf(AggFunc):
4528    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class CurrentDate(Func):
4531class CurrentDate(Func):
4532    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4535class CurrentDatetime(Func):
4536    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4539class CurrentTime(Func):
4540    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4543class CurrentTimestamp(Func):
4544    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4547class CurrentUser(Func):
4548    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4551class DateAdd(Func, IntervalOp):
4552    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4555class DateSub(Func, IntervalOp):
4556    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4559class DateDiff(Func, TimeUnit):
4560    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4561    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4564class DateTrunc(Func):
4565    arg_types = {"unit": True, "this": True, "zone": False}
4566
4567    def __init__(self, **args):
4568        unit = args.get("unit")
4569        if isinstance(unit, TimeUnit.VAR_LIKE):
4570            args["unit"] = Literal.string(
4571                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4572            )
4573        elif isinstance(unit, Week):
4574            unit.set("this", Literal.string(unit.this.name.upper()))
4575
4576        super().__init__(**args)
4577
4578    @property
4579    def unit(self) -> Expression:
4580        return self.args["unit"]
DateTrunc(**args)
4567    def __init__(self, **args):
4568        unit = args.get("unit")
4569        if isinstance(unit, TimeUnit.VAR_LIKE):
4570            args["unit"] = Literal.string(
4571                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4572            )
4573        elif isinstance(unit, Week):
4574            unit.set("this", Literal.string(unit.this.name.upper()))
4575
4576        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4578    @property
4579    def unit(self) -> Expression:
4580        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4583class DatetimeAdd(Func, IntervalOp):
4584    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4587class DatetimeSub(Func, IntervalOp):
4588    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4591class DatetimeDiff(Func, TimeUnit):
4592    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4595class DatetimeTrunc(Func, TimeUnit):
4596    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4599class DayOfWeek(Func):
4600    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4603class DayOfMonth(Func):
4604    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4607class DayOfYear(Func):
4608    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4611class ToDays(Func):
4612    pass
key = 'todays'
class WeekOfYear(Func):
4615class WeekOfYear(Func):
4616    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4619class MonthsBetween(Func):
4620    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4623class LastDay(Func, TimeUnit):
4624    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4625    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4628class Extract(Func):
4629    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4632class Timestamp(Func):
4633    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4636class TimestampAdd(Func, TimeUnit):
4637    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4640class TimestampSub(Func, TimeUnit):
4641    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4644class TimestampDiff(Func, TimeUnit):
4645    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4648class TimestampTrunc(Func, TimeUnit):
4649    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4652class TimeAdd(Func, TimeUnit):
4653    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4656class TimeSub(Func, TimeUnit):
4657    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4660class TimeDiff(Func, TimeUnit):
4661    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4664class TimeTrunc(Func, TimeUnit):
4665    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4668class DateFromParts(Func):
4669    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4670    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4673class TimeFromParts(Func):
4674    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4675    arg_types = {
4676        "hour": True,
4677        "min": True,
4678        "sec": True,
4679        "nano": False,
4680        "fractions": False,
4681        "precision": False,
4682    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4685class DateStrToDate(Func):
4686    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4689class DateToDateStr(Func):
4690    pass
key = 'datetodatestr'
class DateToDi(Func):
4693class DateToDi(Func):
4694    pass
key = 'datetodi'
class Date(Func):
4698class Date(Func):
4699    arg_types = {"this": False, "zone": False, "expressions": False}
4700    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4703class Day(Func):
4704    pass
key = 'day'
class Decode(Func):
4707class Decode(Func):
4708    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4711class DiToDate(Func):
4712    pass
key = 'ditodate'
class Encode(Func):
4715class Encode(Func):
4716    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4719class Exp(Func):
4720    pass
key = 'exp'
class Explode(Func):
4724class Explode(Func):
4725    arg_types = {"this": True, "expressions": False}
4726    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4729class ExplodeOuter(Explode):
4730    pass
key = 'explodeouter'
class Posexplode(Explode):
4733class Posexplode(Explode):
4734    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4737class PosexplodeOuter(Posexplode):
4738    pass
key = 'posexplodeouter'
class Floor(Func):
4741class Floor(Func):
4742    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4745class FromBase64(Func):
4746    pass
key = 'frombase64'
class ToBase64(Func):
4749class ToBase64(Func):
4750    pass
key = 'tobase64'
class Greatest(Func):
4753class Greatest(Func):
4754    arg_types = {"this": True, "expressions": False}
4755    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4758class GroupConcat(AggFunc):
4759    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4762class Hex(Func):
4763    pass
key = 'hex'
class Xor(Connector, Func):
4766class Xor(Connector, Func):
4767    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4770class If(Func):
4771    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4774class Nullif(Func):
4775    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4778class Initcap(Func):
4779    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4782class IsNan(Func):
4783    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4786class IsInf(Func):
4787    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class FormatJson(Expression):
4790class FormatJson(Expression):
4791    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4794class JSONKeyValue(Expression):
4795    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4798class JSONObject(Func):
4799    arg_types = {
4800        "expressions": False,
4801        "null_handling": False,
4802        "unique_keys": False,
4803        "return_type": False,
4804        "encoding": False,
4805    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONArray(Func):
4809class JSONArray(Func):
4810    arg_types = {
4811        "expressions": True,
4812        "null_handling": False,
4813        "return_type": False,
4814        "strict": False,
4815    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4819class JSONArrayAgg(Func):
4820    arg_types = {
4821        "this": True,
4822        "order": False,
4823        "null_handling": False,
4824        "return_type": False,
4825        "strict": False,
4826    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4831class JSONColumnDef(Expression):
4832    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):
4835class JSONSchema(Expression):
4836    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4840class JSONTable(Func):
4841    arg_types = {
4842        "this": True,
4843        "schema": True,
4844        "path": False,
4845        "error_handling": False,
4846        "empty_handling": False,
4847    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4850class OpenJSONColumnDef(Expression):
4851    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):
4854class OpenJSON(Func):
4855    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4858class JSONBContains(Binary):
4859    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4862class JSONExtract(Binary, Func):
4863    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4866class JSONExtractScalar(JSONExtract):
4867    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4870class JSONBExtract(JSONExtract):
4871    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4874class JSONBExtractScalar(JSONExtract):
4875    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4878class JSONFormat(Func):
4879    arg_types = {"this": False, "options": False}
4880    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4884class JSONArrayContains(Binary, Predicate, Func):
4885    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4888class ParseJSON(Func):
4889    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4890    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4891    arg_types = {"this": True, "expressions": False}
4892    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class GetPath(Func):
4896class GetPath(Func):
4897    arg_types = {"this": True, "expression": True}
4898
4899    @property
4900    def output_name(self) -> str:
4901        return self.expression.output_name
arg_types = {'this': True, 'expression': True}
output_name: str
4899    @property
4900    def output_name(self) -> str:
4901        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):
4904class Least(Func):
4905    arg_types = {"this": True, "expressions": False}
4906    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4909class Left(Func):
4910    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4917class Length(Func):
4918    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4921class Levenshtein(Func):
4922    arg_types = {
4923        "this": True,
4924        "expression": False,
4925        "ins_cost": False,
4926        "del_cost": False,
4927        "sub_cost": False,
4928    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4931class Ln(Func):
4932    pass
key = 'ln'
class Log(Func):
4935class Log(Func):
4936    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4939class Log2(Func):
4940    pass
key = 'log2'
class Log10(Func):
4943class Log10(Func):
4944    pass
key = 'log10'
class LogicalOr(AggFunc):
4947class LogicalOr(AggFunc):
4948    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
4951class LogicalAnd(AggFunc):
4952    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
4955class Lower(Func):
4956    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
4959class Map(Func):
4960    arg_types = {"keys": False, "values": False}
4961
4962    @property
4963    def keys(self) -> t.List[Expression]:
4964        keys = self.args.get("keys")
4965        return keys.expressions if keys else []
4966
4967    @property
4968    def values(self) -> t.List[Expression]:
4969        values = self.args.get("values")
4970        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
4962    @property
4963    def keys(self) -> t.List[Expression]:
4964        keys = self.args.get("keys")
4965        return keys.expressions if keys else []
values: List[Expression]
4967    @property
4968    def values(self) -> t.List[Expression]:
4969        values = self.args.get("values")
4970        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
4973class MapFromEntries(Func):
4974    pass
key = 'mapfromentries'
class StarMap(Func):
4977class StarMap(Func):
4978    pass
key = 'starmap'
class VarMap(Func):
4981class VarMap(Func):
4982    arg_types = {"keys": True, "values": True}
4983    is_var_len_args = True
4984
4985    @property
4986    def keys(self) -> t.List[Expression]:
4987        return self.args["keys"].expressions
4988
4989    @property
4990    def values(self) -> t.List[Expression]:
4991        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
4985    @property
4986    def keys(self) -> t.List[Expression]:
4987        return self.args["keys"].expressions
values: List[Expression]
4989    @property
4990    def values(self) -> t.List[Expression]:
4991        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
4995class MatchAgainst(Func):
4996    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
4999class Max(AggFunc):
5000    arg_types = {"this": True, "expressions": False}
5001    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5004class MD5(Func):
5005    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5009class MD5Digest(Func):
5010    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5013class Min(AggFunc):
5014    arg_types = {"this": True, "expressions": False}
5015    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5018class Month(Func):
5019    pass
key = 'month'
class Nvl2(Func):
5022class Nvl2(Func):
5023    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5027class Predict(Func):
5028    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5031class Pow(Binary, Func):
5032    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5035class PercentileCont(AggFunc):
5036    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5039class PercentileDisc(AggFunc):
5040    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5043class Quantile(AggFunc):
5044    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5047class ApproxQuantile(Quantile):
5048    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):
5051class Rand(Func):
5052    _sql_names = ["RAND", "RANDOM"]
5053    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5056class Randn(Func):
5057    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5060class RangeN(Func):
5061    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5064class ReadCSV(Func):
5065    _sql_names = ["READ_CSV"]
5066    is_var_len_args = True
5067    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5070class Reduce(Func):
5071    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):
5074class RegexpExtract(Func):
5075    arg_types = {
5076        "this": True,
5077        "expression": True,
5078        "position": False,
5079        "occurrence": False,
5080        "parameters": False,
5081        "group": False,
5082    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5085class RegexpReplace(Func):
5086    arg_types = {
5087        "this": True,
5088        "expression": True,
5089        "replacement": True,
5090        "position": False,
5091        "occurrence": False,
5092        "parameters": False,
5093        "modifiers": False,
5094    }
arg_types = {'this': True, 'expression': True, 'replacement': True, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5097class RegexpLike(Binary, Func):
5098    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5101class RegexpILike(Binary, Func):
5102    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5107class RegexpSplit(Func):
5108    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5111class Repeat(Func):
5112    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5115class Round(Func):
5116    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'round'
class RowNumber(Func):
5119class RowNumber(Func):
5120    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5123class SafeDivide(Func):
5124    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5127class SHA(Func):
5128    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5131class SHA2(Func):
5132    _sql_names = ["SHA2"]
5133    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5136class SortArray(Func):
5137    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5140class Split(Func):
5141    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5146class Substring(Func):
5147    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5150class StandardHash(Func):
5151    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5154class StartsWith(Func):
5155    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5156    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5159class StrPosition(Func):
5160    arg_types = {
5161        "this": True,
5162        "substr": True,
5163        "position": False,
5164        "instance": False,
5165    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5168class StrToDate(Func):
5169    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5172class StrToTime(Func):
5173    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5178class StrToUnix(Func):
5179    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5184class StrToMap(Func):
5185    arg_types = {
5186        "this": True,
5187        "pair_delim": False,
5188        "key_value_delim": False,
5189        "duplicate_resolution_callback": False,
5190    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5193class NumberToStr(Func):
5194    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5197class FromBase(Func):
5198    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5201class Struct(Func):
5202    arg_types = {"expressions": False}
5203    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5206class StructExtract(Func):
5207    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5212class Stuff(Func):
5213    _sql_names = ["STUFF", "INSERT"]
5214    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):
5217class Sum(AggFunc):
5218    pass
key = 'sum'
class Sqrt(Func):
5221class Sqrt(Func):
5222    pass
key = 'sqrt'
class Stddev(AggFunc):
5225class Stddev(AggFunc):
5226    pass
key = 'stddev'
class StddevPop(AggFunc):
5229class StddevPop(AggFunc):
5230    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5233class StddevSamp(AggFunc):
5234    pass
key = 'stddevsamp'
class TimeToStr(Func):
5237class TimeToStr(Func):
5238    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5241class TimeToTimeStr(Func):
5242    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5245class TimeToUnix(Func):
5246    pass
key = 'timetounix'
class TimeStrToDate(Func):
5249class TimeStrToDate(Func):
5250    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5253class TimeStrToTime(Func):
5254    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5257class TimeStrToUnix(Func):
5258    pass
key = 'timestrtounix'
class Trim(Func):
5261class Trim(Func):
5262    arg_types = {
5263        "this": True,
5264        "expression": False,
5265        "position": False,
5266        "collation": False,
5267    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5270class TsOrDsAdd(Func, TimeUnit):
5271    # return_type is used to correctly cast the arguments of this expression when transpiling it
5272    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5273
5274    @property
5275    def return_type(self) -> DataType:
5276        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
5274    @property
5275    def return_type(self) -> DataType:
5276        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5279class TsOrDsDiff(Func, TimeUnit):
5280    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5283class TsOrDsToDateStr(Func):
5284    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5287class TsOrDsToDate(Func):
5288    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5291class TsOrDsToTime(Func):
5292    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5295class TsOrDiToDi(Func):
5296    pass
key = 'tsorditodi'
class Unhex(Func):
5299class Unhex(Func):
5300    pass
key = 'unhex'
class UnixDate(Func):
5304class UnixDate(Func):
5305    pass
key = 'unixdate'
class UnixToStr(Func):
5308class UnixToStr(Func):
5309    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5314class UnixToTime(Func):
5315    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5316
5317    SECONDS = Literal.string("seconds")
5318    MILLIS = Literal.string("millis")
5319    MICROS = Literal.string("micros")
5320    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):
5323class UnixToTimeStr(Func):
5324    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5327class TimestampFromParts(Func):
5328    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5329    arg_types = {
5330        "year": True,
5331        "month": True,
5332        "day": True,
5333        "hour": True,
5334        "min": True,
5335        "sec": True,
5336        "nano": False,
5337        "zone": False,
5338        "milli": False,
5339    }
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):
5342class Upper(Func):
5343    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5346class Variance(AggFunc):
5347    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5350class VariancePop(AggFunc):
5351    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5354class Week(Func):
5355    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5358class XMLTable(Func):
5359    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):
5362class Year(Func):
5363    pass
key = 'year'
class Use(Expression):
5366class Use(Expression):
5367    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5370class Merge(Expression):
5371    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):
5374class When(Func):
5375    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):
5380class NextValueFor(Func):
5381    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:
5419def maybe_parse(
5420    sql_or_expression: ExpOrStr,
5421    *,
5422    into: t.Optional[IntoType] = None,
5423    dialect: DialectType = None,
5424    prefix: t.Optional[str] = None,
5425    copy: bool = False,
5426    **opts,
5427) -> Expression:
5428    """Gracefully handle a possible string or expression.
5429
5430    Example:
5431        >>> maybe_parse("1")
5432        Literal(this=1, is_string=False)
5433        >>> maybe_parse(to_identifier("x"))
5434        Identifier(this=x, quoted=False)
5435
5436    Args:
5437        sql_or_expression: the SQL code string or an expression
5438        into: the SQLGlot Expression to parse into
5439        dialect: the dialect used to parse the input expressions (in the case that an
5440            input expression is a SQL string).
5441        prefix: a string to prefix the sql with before it gets parsed
5442            (automatically includes a space)
5443        copy: whether or not to copy the expression.
5444        **opts: other options to use to parse the input expressions (again, in the case
5445            that an input expression is a SQL string).
5446
5447    Returns:
5448        Expression: the parsed or given expression.
5449    """
5450    if isinstance(sql_or_expression, Expression):
5451        if copy:
5452            return sql_or_expression.copy()
5453        return sql_or_expression
5454
5455    if sql_or_expression is None:
5456        raise ParseError(f"SQL cannot be None")
5457
5458    import sqlglot
5459
5460    sql = str(sql_or_expression)
5461    if prefix:
5462        sql = f"{prefix} {sql}"
5463
5464    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):
5477def maybe_copy(instance, copy=True):
5478    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:
5692def union(
5693    left: ExpOrStr,
5694    right: ExpOrStr,
5695    distinct: bool = True,
5696    dialect: DialectType = None,
5697    copy: bool = True,
5698    **opts,
5699) -> Union:
5700    """
5701    Initializes a syntax tree from one UNION expression.
5702
5703    Example:
5704        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5705        'SELECT * FROM foo UNION SELECT * FROM bla'
5706
5707    Args:
5708        left: the SQL code string corresponding to the left-hand side.
5709            If an `Expression` instance is passed, it will be used as-is.
5710        right: the SQL code string corresponding to the right-hand side.
5711            If an `Expression` instance is passed, it will be used as-is.
5712        distinct: set the DISTINCT flag if and only if this is true.
5713        dialect: the dialect used to parse the input expression.
5714        copy: whether or not to copy the expression.
5715        opts: other options to use to parse the input expressions.
5716
5717    Returns:
5718        The new Union instance.
5719    """
5720    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5721    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5722
5723    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:
5726def intersect(
5727    left: ExpOrStr,
5728    right: ExpOrStr,
5729    distinct: bool = True,
5730    dialect: DialectType = None,
5731    copy: bool = True,
5732    **opts,
5733) -> Intersect:
5734    """
5735    Initializes a syntax tree from one INTERSECT expression.
5736
5737    Example:
5738        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5739        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5740
5741    Args:
5742        left: the SQL code string corresponding to the left-hand side.
5743            If an `Expression` instance is passed, it will be used as-is.
5744        right: the SQL code string corresponding to the right-hand side.
5745            If an `Expression` instance is passed, it will be used as-is.
5746        distinct: set the DISTINCT flag if and only if this is true.
5747        dialect: the dialect used to parse the input expression.
5748        copy: whether or not to copy the expression.
5749        opts: other options to use to parse the input expressions.
5750
5751    Returns:
5752        The new Intersect instance.
5753    """
5754    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5755    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5756
5757    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:
5760def except_(
5761    left: ExpOrStr,
5762    right: ExpOrStr,
5763    distinct: bool = True,
5764    dialect: DialectType = None,
5765    copy: bool = True,
5766    **opts,
5767) -> Except:
5768    """
5769    Initializes a syntax tree from one EXCEPT expression.
5770
5771    Example:
5772        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5773        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5774
5775    Args:
5776        left: the SQL code string corresponding to the left-hand side.
5777            If an `Expression` instance is passed, it will be used as-is.
5778        right: the SQL code string corresponding to the right-hand side.
5779            If an `Expression` instance is passed, it will be used as-is.
5780        distinct: set the DISTINCT flag if and only if this is true.
5781        dialect: the dialect used to parse the input expression.
5782        copy: whether or not to copy the expression.
5783        opts: other options to use to parse the input expressions.
5784
5785    Returns:
5786        The new Except instance.
5787    """
5788    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5789    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5790
5791    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:
5794def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5795    """
5796    Initializes a syntax tree from one or multiple SELECT expressions.
5797
5798    Example:
5799        >>> select("col1", "col2").from_("tbl").sql()
5800        'SELECT col1, col2 FROM tbl'
5801
5802    Args:
5803        *expressions: the SQL code string to parse as the expressions of a
5804            SELECT statement. If an Expression instance is passed, this is used as-is.
5805        dialect: the dialect used to parse the input expressions (in the case that an
5806            input expression is a SQL string).
5807        **opts: other options to use to parse the input expressions (again, in the case
5808            that an input expression is a SQL string).
5809
5810    Returns:
5811        Select: the syntax tree for the SELECT statement.
5812    """
5813    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:
5816def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5817    """
5818    Initializes a syntax tree from a FROM expression.
5819
5820    Example:
5821        >>> from_("tbl").select("col1", "col2").sql()
5822        'SELECT col1, col2 FROM tbl'
5823
5824    Args:
5825        *expression: the SQL code string to parse as the FROM expressions of a
5826            SELECT statement. If an Expression instance is passed, this is used as-is.
5827        dialect: the dialect used to parse the input expression (in the case that the
5828            input expression is a SQL string).
5829        **opts: other options to use to parse the input expressions (again, in the case
5830            that the input expression is a SQL string).
5831
5832    Returns:
5833        Select: the syntax tree for the SELECT statement.
5834    """
5835    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:
5838def update(
5839    table: str | Table,
5840    properties: dict,
5841    where: t.Optional[ExpOrStr] = None,
5842    from_: t.Optional[ExpOrStr] = None,
5843    dialect: DialectType = None,
5844    **opts,
5845) -> Update:
5846    """
5847    Creates an update statement.
5848
5849    Example:
5850        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5851        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5852
5853    Args:
5854        *properties: dictionary of properties to set which are
5855            auto converted to sql objects eg None -> NULL
5856        where: sql conditional parsed into a WHERE statement
5857        from_: sql statement parsed into a FROM statement
5858        dialect: the dialect used to parse the input expressions.
5859        **opts: other options to use to parse the input expressions.
5860
5861    Returns:
5862        Update: the syntax tree for the UPDATE statement.
5863    """
5864    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5865    update_expr.set(
5866        "expressions",
5867        [
5868            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5869            for k, v in properties.items()
5870        ],
5871    )
5872    if from_:
5873        update_expr.set(
5874            "from",
5875            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5876        )
5877    if isinstance(where, Condition):
5878        where = Where(this=where)
5879    if where:
5880        update_expr.set(
5881            "where",
5882            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5883        )
5884    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:
5887def delete(
5888    table: ExpOrStr,
5889    where: t.Optional[ExpOrStr] = None,
5890    returning: t.Optional[ExpOrStr] = None,
5891    dialect: DialectType = None,
5892    **opts,
5893) -> Delete:
5894    """
5895    Builds a delete statement.
5896
5897    Example:
5898        >>> delete("my_table", where="id > 1").sql()
5899        'DELETE FROM my_table WHERE id > 1'
5900
5901    Args:
5902        where: sql conditional parsed into a WHERE statement
5903        returning: sql conditional parsed into a RETURNING statement
5904        dialect: the dialect used to parse the input expressions.
5905        **opts: other options to use to parse the input expressions.
5906
5907    Returns:
5908        Delete: the syntax tree for the DELETE statement.
5909    """
5910    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5911    if where:
5912        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5913    if returning:
5914        delete_expr = t.cast(
5915            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5916        )
5917    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:
5920def insert(
5921    expression: ExpOrStr,
5922    into: ExpOrStr,
5923    columns: t.Optional[t.Sequence[ExpOrStr]] = None,
5924    overwrite: t.Optional[bool] = None,
5925    returning: t.Optional[ExpOrStr] = None,
5926    dialect: DialectType = None,
5927    copy: bool = True,
5928    **opts,
5929) -> Insert:
5930    """
5931    Builds an INSERT statement.
5932
5933    Example:
5934        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5935        'INSERT INTO tbl VALUES (1, 2, 3)'
5936
5937    Args:
5938        expression: the sql string or expression of the INSERT statement
5939        into: the tbl to insert data to.
5940        columns: optionally the table's column names.
5941        overwrite: whether to INSERT OVERWRITE or not.
5942        returning: sql conditional parsed into a RETURNING statement
5943        dialect: the dialect used to parse the input expressions.
5944        copy: whether or not to copy the expression.
5945        **opts: other options to use to parse the input expressions.
5946
5947    Returns:
5948        Insert: the syntax tree for the INSERT statement.
5949    """
5950    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
5951    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
5952
5953    if columns:
5954        this = _apply_list_builder(
5955            *columns,
5956            instance=Schema(this=this),
5957            arg="expressions",
5958            into=Identifier,
5959            copy=False,
5960            dialect=dialect,
5961            **opts,
5962        )
5963
5964    insert = Insert(this=this, expression=expr, overwrite=overwrite)
5965
5966    if returning:
5967        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
5968
5969    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:
5972def condition(
5973    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
5974) -> Condition:
5975    """
5976    Initialize a logical condition expression.
5977
5978    Example:
5979        >>> condition("x=1").sql()
5980        'x = 1'
5981
5982        This is helpful for composing larger logical syntax trees:
5983        >>> where = condition("x=1")
5984        >>> where = where.and_("y=1")
5985        >>> Select().from_("tbl").select("*").where(where).sql()
5986        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
5987
5988    Args:
5989        *expression: the SQL code string to parse.
5990            If an Expression instance is passed, this is used as-is.
5991        dialect: the dialect used to parse the input expression (in the case that the
5992            input expression is a SQL string).
5993        copy: Whether or not to copy `expression` (only applies to expressions).
5994        **opts: other options to use to parse the input expressions (again, in the case
5995            that the input expression is a SQL string).
5996
5997    Returns:
5998        The new Condition instance
5999    """
6000    return maybe_parse(
6001        expression,
6002        into=Condition,
6003        dialect=dialect,
6004        copy=copy,
6005        **opts,
6006    )

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:
6009def and_(
6010    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6011) -> Condition:
6012    """
6013    Combine multiple conditions with an AND logical operator.
6014
6015    Example:
6016        >>> and_("x=1", and_("y=1", "z=1")).sql()
6017        'x = 1 AND (y = 1 AND z = 1)'
6018
6019    Args:
6020        *expressions: the SQL code strings to parse.
6021            If an Expression instance is passed, this is used as-is.
6022        dialect: the dialect used to parse the input expression.
6023        copy: whether or not to copy `expressions` (only applies to Expressions).
6024        **opts: other options to use to parse the input expressions.
6025
6026    Returns:
6027        And: the new condition
6028    """
6029    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:
6032def or_(
6033    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6034) -> Condition:
6035    """
6036    Combine multiple conditions with an OR logical operator.
6037
6038    Example:
6039        >>> or_("x=1", or_("y=1", "z=1")).sql()
6040        'x = 1 OR (y = 1 OR z = 1)'
6041
6042    Args:
6043        *expressions: the SQL code strings to parse.
6044            If an Expression instance is passed, this is used as-is.
6045        dialect: the dialect used to parse the input expression.
6046        copy: whether or not to copy `expressions` (only applies to Expressions).
6047        **opts: other options to use to parse the input expressions.
6048
6049    Returns:
6050        Or: the new condition
6051    """
6052    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:
6055def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6056    """
6057    Wrap a condition with a NOT operator.
6058
6059    Example:
6060        >>> not_("this_suit='black'").sql()
6061        "NOT this_suit = 'black'"
6062
6063    Args:
6064        expression: the SQL code string to parse.
6065            If an Expression instance is passed, this is used as-is.
6066        dialect: the dialect used to parse the input expression.
6067        copy: whether to copy the expression or not.
6068        **opts: other options to use to parse the input expressions.
6069
6070    Returns:
6071        The new condition.
6072    """
6073    this = condition(
6074        expression,
6075        dialect=dialect,
6076        copy=copy,
6077        **opts,
6078    )
6079    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:
6082def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6083    """
6084    Wrap an expression in parentheses.
6085
6086    Example:
6087        >>> paren("5 + 3").sql()
6088        '(5 + 3)'
6089
6090    Args:
6091        expression: the SQL code string to parse.
6092            If an Expression instance is passed, this is used as-is.
6093        copy: whether to copy the expression or not.
6094
6095    Returns:
6096        The wrapped expression.
6097    """
6098    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):
6116def to_identifier(name, quoted=None, copy=True):
6117    """Builds an identifier.
6118
6119    Args:
6120        name: The name to turn into an identifier.
6121        quoted: Whether or not force quote the identifier.
6122        copy: Whether or not to copy name if it's an Identifier.
6123
6124    Returns:
6125        The identifier ast node.
6126    """
6127
6128    if name is None:
6129        return None
6130
6131    if isinstance(name, Identifier):
6132        identifier = maybe_copy(name, copy)
6133    elif isinstance(name, str):
6134        identifier = Identifier(
6135            this=name,
6136            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6137        )
6138    else:
6139        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6140    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:
6143def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6144    """
6145    Parses a given string into an identifier.
6146
6147    Args:
6148        name: The name to parse into an identifier.
6149        dialect: The dialect to parse against.
6150
6151    Returns:
6152        The identifier ast node.
6153    """
6154    try:
6155        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6156    except ParseError:
6157        expression = to_identifier(name)
6158
6159    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:
6165def to_interval(interval: str | Literal) -> Interval:
6166    """Builds an interval expression from a string like '1 day' or '5 months'."""
6167    if isinstance(interval, Literal):
6168        if not interval.is_string:
6169            raise ValueError("Invalid interval string.")
6170
6171        interval = interval.this
6172
6173    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6174
6175    if not interval_parts:
6176        raise ValueError("Invalid interval string.")
6177
6178    return Interval(
6179        this=Literal.string(interval_parts.group(1)),
6180        unit=Var(this=interval_parts.group(2).upper()),
6181    )

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]:
6194def to_table(
6195    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6196) -> t.Optional[Table]:
6197    """
6198    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6199    If a table is passed in then that table is returned.
6200
6201    Args:
6202        sql_path: a `[catalog].[schema].[table]` string.
6203        dialect: the source dialect according to which the table name will be parsed.
6204        copy: Whether or not to copy a table if it is passed in.
6205        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6206
6207    Returns:
6208        A table expression.
6209    """
6210    if sql_path is None or isinstance(sql_path, Table):
6211        return maybe_copy(sql_path, copy=copy)
6212    if not isinstance(sql_path, str):
6213        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6214
6215    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6216    if table:
6217        for k, v in kwargs.items():
6218            table.set(k, v)
6219
6220    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:
6223def to_column(sql_path: str | Column, **kwargs) -> Column:
6224    """
6225    Create a column from a `[table].[column]` sql path. Schema is optional.
6226
6227    If a column is passed in then that column is returned.
6228
6229    Args:
6230        sql_path: `[table].[column]` string
6231    Returns:
6232        Table: A column expression
6233    """
6234    if sql_path is None or isinstance(sql_path, Column):
6235        return sql_path
6236    if not isinstance(sql_path, str):
6237        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6238    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):
6241def alias_(
6242    expression: ExpOrStr,
6243    alias: str | Identifier,
6244    table: bool | t.Sequence[str | Identifier] = False,
6245    quoted: t.Optional[bool] = None,
6246    dialect: DialectType = None,
6247    copy: bool = True,
6248    **opts,
6249):
6250    """Create an Alias expression.
6251
6252    Example:
6253        >>> alias_('foo', 'bar').sql()
6254        'foo AS bar'
6255
6256        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6257        '(SELECT 1, 2) AS bar(a, b)'
6258
6259    Args:
6260        expression: the SQL code strings to parse.
6261            If an Expression instance is passed, this is used as-is.
6262        alias: the alias name to use. If the name has
6263            special characters it is quoted.
6264        table: Whether or not to create a table alias, can also be a list of columns.
6265        quoted: whether or not to quote the alias
6266        dialect: the dialect used to parse the input expression.
6267        copy: Whether or not to copy the expression.
6268        **opts: other options to use to parse the input expressions.
6269
6270    Returns:
6271        Alias: the aliased expression
6272    """
6273    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6274    alias = to_identifier(alias, quoted=quoted)
6275
6276    if table:
6277        table_alias = TableAlias(this=alias)
6278        exp.set("alias", table_alias)
6279
6280        if not isinstance(table, bool):
6281            for column in table:
6282                table_alias.append("columns", to_identifier(column, quoted=quoted))
6283
6284        return exp
6285
6286    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6287    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6288    # for the complete Window expression.
6289    #
6290    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6291
6292    if "alias" in exp.arg_types and not isinstance(exp, Window):
6293        exp.set("alias", alias)
6294        return exp
6295    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:
6298def subquery(
6299    expression: ExpOrStr,
6300    alias: t.Optional[Identifier | str] = None,
6301    dialect: DialectType = None,
6302    **opts,
6303) -> Select:
6304    """
6305    Build a subquery expression.
6306
6307    Example:
6308        >>> subquery('select x from tbl', 'bar').select('x').sql()
6309        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6310
6311    Args:
6312        expression: the SQL code strings to parse.
6313            If an Expression instance is passed, this is used as-is.
6314        alias: the alias name to use.
6315        dialect: the dialect used to parse the input expression.
6316        **opts: other options to use to parse the input expressions.
6317
6318    Returns:
6319        A new Select instance with the subquery expression included.
6320    """
6321
6322    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6323    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:
6326def column(
6327    col: str | Identifier,
6328    table: t.Optional[str | Identifier] = None,
6329    db: t.Optional[str | Identifier] = None,
6330    catalog: t.Optional[str | Identifier] = None,
6331    *fields: t.Union[str, Identifier],
6332    quoted: t.Optional[bool] = None,
6333    copy: bool = True,
6334) -> Column | Dot:
6335    """
6336    Build a Column.
6337
6338    Args:
6339        col: Column name.
6340        table: Table name.
6341        db: Database name.
6342        catalog: Catalog name.
6343        fields: Additional fields using dots.
6344        quoted: Whether to force quotes on the column's identifiers.
6345        copy: Whether or not to copy identifiers if passed in.
6346
6347    Returns:
6348        The new Column instance.
6349    """
6350    this: t.Union[Column, Dot] = Column(
6351        this=to_identifier(col, quoted=quoted, copy=copy),
6352        table=to_identifier(table, quoted=quoted, copy=copy),
6353        db=to_identifier(db, quoted=quoted, copy=copy),
6354        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6355    )
6356
6357    if fields:
6358        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6359    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:
6362def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6363    """Cast an expression to a data type.
6364
6365    Example:
6366        >>> cast('x + 1', 'int').sql()
6367        'CAST(x + 1 AS INT)'
6368
6369    Args:
6370        expression: The expression to cast.
6371        to: The datatype to cast to.
6372
6373    Returns:
6374        The new Cast instance.
6375    """
6376    expression = maybe_parse(expression, **opts)
6377    data_type = DataType.build(to, **opts)
6378    expression = Cast(this=expression, to=data_type)
6379    expression.type = data_type
6380    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:
6383def table_(
6384    table: Identifier | str,
6385    db: t.Optional[Identifier | str] = None,
6386    catalog: t.Optional[Identifier | str] = None,
6387    quoted: t.Optional[bool] = None,
6388    alias: t.Optional[Identifier | str] = None,
6389) -> Table:
6390    """Build a Table.
6391
6392    Args:
6393        table: Table name.
6394        db: Database name.
6395        catalog: Catalog name.
6396        quote: Whether to force quotes on the table's identifiers.
6397        alias: Table's alias.
6398
6399    Returns:
6400        The new Table instance.
6401    """
6402    return Table(
6403        this=to_identifier(table, quoted=quoted) if table else None,
6404        db=to_identifier(db, quoted=quoted) if db else None,
6405        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6406        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6407    )

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

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

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

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

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:
6606def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6607    """Returns a case normalized table name without quotes.
6608
6609    Args:
6610        table: the table to normalize
6611        dialect: the dialect to use for normalization rules
6612        copy: whether or not to copy the expression.
6613
6614    Examples:
6615        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6616        'A-B.c'
6617    """
6618    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6619
6620    return ".".join(
6621        p.name
6622        for p in normalize_identifiers(
6623            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6624        ).parts
6625    )

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:
6628def replace_tables(
6629    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6630) -> E:
6631    """Replace all tables in expression according to the mapping.
6632
6633    Args:
6634        expression: expression node to be transformed and replaced.
6635        mapping: mapping of table names.
6636        dialect: the dialect of the mapping table
6637        copy: whether or not to copy the expression.
6638
6639    Examples:
6640        >>> from sqlglot import exp, parse_one
6641        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6642        'SELECT * FROM c /* a.b */'
6643
6644    Returns:
6645        The mapped expression.
6646    """
6647
6648    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6649
6650    def _replace_tables(node: Expression) -> Expression:
6651        if isinstance(node, Table):
6652            original = normalize_table_name(node, dialect=dialect)
6653            new_name = mapping.get(original)
6654
6655            if new_name:
6656                table = to_table(
6657                    new_name,
6658                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6659                )
6660                table.add_comments([original])
6661                return table
6662        return node
6663
6664    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:
6667def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6668    """Replace placeholders in an expression.
6669
6670    Args:
6671        expression: expression node to be transformed and replaced.
6672        args: positional names that will substitute unnamed placeholders in the given order.
6673        kwargs: keyword arguments that will substitute named placeholders.
6674
6675    Examples:
6676        >>> from sqlglot import exp, parse_one
6677        >>> replace_placeholders(
6678        ...     parse_one("select * from :tbl where ? = ?"),
6679        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6680        ... ).sql()
6681        "SELECT * FROM foo WHERE str_col = 'b'"
6682
6683    Returns:
6684        The mapped expression.
6685    """
6686
6687    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6688        if isinstance(node, Placeholder):
6689            if node.name:
6690                new_name = kwargs.get(node.name)
6691                if new_name:
6692                    return convert(new_name)
6693            else:
6694                try:
6695                    return convert(next(args))
6696                except StopIteration:
6697                    pass
6698        return node
6699
6700    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:
6703def expand(
6704    expression: Expression,
6705    sources: t.Dict[str, Subqueryable],
6706    dialect: DialectType = None,
6707    copy: bool = True,
6708) -> Expression:
6709    """Transforms an expression by expanding all referenced sources into subqueries.
6710
6711    Examples:
6712        >>> from sqlglot import parse_one
6713        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6714        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6715
6716        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6717        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6718
6719    Args:
6720        expression: The expression to expand.
6721        sources: A dictionary of name to Subqueryables.
6722        dialect: The dialect of the sources dict.
6723        copy: Whether or not to copy the expression during transformation. Defaults to True.
6724
6725    Returns:
6726        The transformed expression.
6727    """
6728    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6729
6730    def _expand(node: Expression):
6731        if isinstance(node, Table):
6732            name = normalize_table_name(node, dialect=dialect)
6733            source = sources.get(name)
6734            if source:
6735                subquery = source.subquery(node.alias or name)
6736                subquery.comments = [f"source: {name}"]
6737                return subquery.transform(_expand, copy=False)
6738        return node
6739
6740    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:
6743def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
6744    """
6745    Returns a Func expression.
6746
6747    Examples:
6748        >>> func("abs", 5).sql()
6749        'ABS(5)'
6750
6751        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6752        'CAST(5 AS DOUBLE)'
6753
6754    Args:
6755        name: the name of the function to build.
6756        args: the args used to instantiate the function of interest.
6757        copy: whether or not to copy the argument expressions.
6758        dialect: the source dialect.
6759        kwargs: the kwargs used to instantiate the function of interest.
6760
6761    Note:
6762        The arguments `args` and `kwargs` are mutually exclusive.
6763
6764    Returns:
6765        An instance of the function of interest, or an anonymous function, if `name` doesn't
6766        correspond to an existing `sqlglot.expressions.Func` class.
6767    """
6768    if args and kwargs:
6769        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6770
6771    from sqlglot.dialects.dialect import Dialect
6772
6773    dialect = Dialect.get_or_raise(dialect)
6774
6775    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
6776    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
6777
6778    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
6779    if constructor:
6780        if converted:
6781            if "dialect" in constructor.__code__.co_varnames:
6782                function = constructor(converted, dialect=dialect)
6783            else:
6784                function = constructor(converted)
6785        elif constructor.__name__ == "from_arg_list":
6786            function = constructor.__self__(**kwargs)  # type: ignore
6787        else:
6788            constructor = FUNCTION_BY_NAME.get(name.upper())
6789            if constructor:
6790                function = constructor(**kwargs)
6791            else:
6792                raise ValueError(
6793                    f"Unable to convert '{name}' into a Func. Either manually construct "
6794                    "the Func expression of interest or parse the function call."
6795                )
6796    else:
6797        kwargs = kwargs or {"expressions": converted}
6798        function = Anonymous(this=name, **kwargs)
6799
6800    for error_message in function.error_messages(converted):
6801        raise ValueError(error_message)
6802
6803    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:
6806def case(
6807    expression: t.Optional[ExpOrStr] = None,
6808    **opts,
6809) -> Case:
6810    """
6811    Initialize a CASE statement.
6812
6813    Example:
6814        case().when("a = 1", "foo").else_("bar")
6815
6816    Args:
6817        expression: Optionally, the input expression (not all dialects support this)
6818        **opts: Extra keyword arguments for parsing `expression`
6819    """
6820    if expression is not None:
6821        this = maybe_parse(expression, **opts)
6822    else:
6823        this = None
6824    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:
6827def cast_unless(
6828    expression: ExpOrStr,
6829    to: DATA_TYPE,
6830    *types: DATA_TYPE,
6831    **opts: t.Any,
6832) -> Expression | Cast:
6833    """
6834    Cast an expression to a data type unless it is a specified type.
6835
6836    Args:
6837        expression: The expression to cast.
6838        to: The data type to cast to.
6839        **types: The types to exclude from casting.
6840        **opts: Extra keyword arguments for parsing `expression`
6841    """
6842    expr = maybe_parse(expression, **opts)
6843    if expr.is_type(*types):
6844        return expr
6845    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:
6848def true() -> Boolean:
6849    """
6850    Returns a true Boolean expression.
6851    """
6852    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
6855def false() -> Boolean:
6856    """
6857    Returns a false Boolean expression.
6858    """
6859    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6862def null() -> Null:
6863    """
6864    Returns a Null expression.
6865    """
6866    return Null()

Returns a Null expression.

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