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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

def text(self, key) -> str:
148    def text(self, key) -> str:
149        """
150        Returns a textual representation of the argument corresponding to "key". This can only be used
151        for args that are strings or leaf Expression instances, such as identifiers and literals.
152        """
153        field = self.args.get(key)
154        if isinstance(field, str):
155            return field
156        if isinstance(field, (Identifier, Literal, Var)):
157            return field.this
158        if isinstance(field, (Star, Null)):
159            return field.name
160        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
162    @property
163    def is_string(self) -> bool:
164        """
165        Checks whether a Literal expression is a string.
166        """
167        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Checks whether a Literal expression is an integer.

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

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
203    @property
204    def alias_column_names(self) -> t.List[str]:
205        table_alias = self.args.get("alias")
206        if not table_alias:
207            return []
208        return [c.name for c in table_alias.args.get("columns") or []]
name: str
210    @property
211    def name(self) -> str:
212        return self.text("this")
alias_or_name: str
214    @property
215    def alias_or_name(self) -> str:
216        return self.alias or self.name
output_name: str
218    @property
219    def output_name(self) -> str:
220        """
221        Name of the output column if this expression is a selection.
222
223        If the Expression has no output name, an empty string is returned.
224
225        Example:
226            >>> from sqlglot import parse_one
227            >>> parse_one("SELECT a").expressions[0].output_name
228            'a'
229            >>> parse_one("SELECT b AS c").expressions[0].output_name
230            'c'
231            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
232            ''
233        """
234        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]
236    @property
237    def type(self) -> t.Optional[DataType]:
238        return self._type
def is_type(self, *dtypes) -> bool:
246    def is_type(self, *dtypes) -> bool:
247        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
249    def is_leaf(self) -> bool:
250        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
252    @property
253    def meta(self) -> t.Dict[str, t.Any]:
254        if self._meta is None:
255            self._meta = {}
256        return self._meta
def copy(self):
271    def copy(self):
272        """
273        Returns a deep copy of the expression.
274        """
275        new = deepcopy(self)
276        new.parent = self.parent
277        return new

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]]) -> None:
279    def add_comments(self, comments: t.Optional[t.List[str]]) -> None:
280        if self.comments is None:
281            self.comments = []
282        if comments:
283            for comment in comments:
284                _, *meta = comment.split(SQLGLOT_META)
285                if meta:
286                    for kv in "".join(meta).split(","):
287                        k, *v = kv.split("=")
288                        value = v[0].strip() if v else True
289                        self.meta[k.strip()] = value
290                self.comments.append(comment)
def append(self, arg_key: str, value: Any) -> None:
292    def append(self, arg_key: str, value: t.Any) -> None:
293        """
294        Appends value to arg_key if it's a list or sets it as a new list.
295
296        Args:
297            arg_key (str): name of the list expression arg
298            value (Any): value to append to the list
299        """
300        if not isinstance(self.args.get(arg_key), list):
301            self.args[arg_key] = []
302        self.args[arg_key].append(value)
303        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:
305    def set(self, arg_key: str, value: t.Any) -> None:
306        """
307        Sets arg_key to value.
308
309        Args:
310            arg_key: name of the expression arg.
311            value: value to set the arg to.
312        """
313        if value is None:
314            self.args.pop(arg_key, None)
315            return
316
317        self.args[arg_key] = value
318        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
330    @property
331    def depth(self) -> int:
332        """
333        Returns the depth of this tree.
334        """
335        if self.parent:
336            return self.parent.depth + 1
337        return 0

Returns the depth of this tree.

def iter_expressions(self) -> Iterator[Tuple[str, Expression]]:
339    def iter_expressions(self) -> t.Iterator[t.Tuple[str, Expression]]:
340        """Yields the key and expression for all arguments, exploding list args."""
341        for k, vs in self.args.items():
342            if type(vs) is list:
343                for v in vs:
344                    if hasattr(v, "parent"):
345                        yield k, v
346            else:
347                if hasattr(vs, "parent"):
348                    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]:
350    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
351        """
352        Returns the first node in this tree which matches at least one of
353        the specified types.
354
355        Args:
356            expression_types: the expression type(s) to match.
357            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
358
359        Returns:
360            The node which matches the criteria or None if no such node was found.
361        """
362        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]:
364    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
365        """
366        Returns a generator object which visits all nodes in this tree and only
367        yields those that match at least one of the specified expression types.
368
369        Args:
370            expression_types: the expression type(s) to match.
371            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
372
373        Returns:
374            The generator object.
375        """
376        for expression, *_ in self.walk(bfs=bfs):
377            if isinstance(expression, expression_types):
378                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]:
380    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
381        """
382        Returns a nearest parent matching expression_types.
383
384        Args:
385            expression_types: the expression type(s) to match.
386
387        Returns:
388            The parent node.
389        """
390        ancestor = self.parent
391        while ancestor and not isinstance(ancestor, expression_types):
392            ancestor = ancestor.parent
393        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]
395    @property
396    def parent_select(self) -> t.Optional[Select]:
397        """
398        Returns the parent select statement.
399        """
400        return self.find_ancestor(Select)

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

def walk(self, bfs=True, prune=None):
416    def walk(self, bfs=True, prune=None):
417        """
418        Returns a generator object which visits all nodes in this tree.
419
420        Args:
421            bfs (bool): if set to True the BFS traversal order will be applied,
422                otherwise the DFS traversal will be used instead.
423            prune ((node, parent, arg_key) -> bool): callable that returns True if
424                the generator should stop traversing this branch of the tree.
425
426        Returns:
427            the generator object.
428        """
429        if bfs:
430            yield from self.bfs(prune=prune)
431        else:
432            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):
434    def dfs(self, parent=None, key=None, prune=None):
435        """
436        Returns a generator object which visits all nodes in this tree in
437        the DFS (Depth-first) order.
438
439        Returns:
440            The generator object.
441        """
442        parent = parent or self.parent
443        yield self, parent, key
444        if prune and prune(self, parent, key):
445            return
446
447        for k, v in self.iter_expressions():
448            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):
450    def bfs(self, prune=None):
451        """
452        Returns a generator object which visits all nodes in this tree in
453        the BFS (Breadth-first) order.
454
455        Returns:
456            The generator object.
457        """
458        queue = deque([(self, self.parent, None)])
459
460        while queue:
461            item, parent, key = queue.popleft()
462
463            yield item, parent, key
464            if prune and prune(item, parent, key):
465                continue
466
467            for k, v in item.iter_expressions():
468                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):
470    def unnest(self):
471        """
472        Returns the first non parenthesis child or self.
473        """
474        expression = self
475        while type(expression) is Paren:
476            expression = expression.this
477        return expression

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
493    def flatten(self, unnest=True):
494        """
495        Returns a generator which yields child nodes whose parents are the same class.
496
497        A AND B AND C -> [A, B, C]
498        """
499        for node, _, _ in self.dfs(prune=lambda n, p, *_: p and not type(n) is self.__class__):
500            if not type(node) is self.__class__:
501                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:
509    def to_s(self) -> str:
510        """
511        Same as __repr__, but includes additional information which can be useful
512        for debugging, like empty or missing args and the AST nodes' object IDs.
513        """
514        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:
516    def sql(self, dialect: DialectType = None, **opts) -> str:
517        """
518        Returns SQL string representation of this tree.
519
520        Args:
521            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
522            opts: other `sqlglot.generator.Generator` options.
523
524        Returns:
525            The SQL string.
526        """
527        from sqlglot.dialects import Dialect
528
529        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):
531    def transform(self, fun, *args, copy=True, **kwargs):
532        """
533        Recursively visits all tree nodes (excluding already transformed ones)
534        and applies the given transformation function to each node.
535
536        Args:
537            fun (function): a function which takes a node as an argument and returns a
538                new transformed node or the same node without modifications. If the function
539                returns None, then the corresponding node will be removed from the syntax tree.
540            copy (bool): if set to True a new tree instance is constructed, otherwise the tree is
541                modified in place.
542
543        Returns:
544            The transformed tree.
545        """
546        node = self.copy() if copy else self
547        new_node = fun(node, *args, **kwargs)
548
549        if new_node is None or not isinstance(new_node, Expression):
550            return new_node
551        if new_node is not node:
552            new_node.parent = node.parent
553            return new_node
554
555        replace_children(new_node, lambda child: child.transform(fun, *args, copy=False, **kwargs))
556        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):
566    def replace(self, expression):
567        """
568        Swap out this expression with a new expression.
569
570        For example::
571
572            >>> tree = Select().select("x").from_("tbl")
573            >>> tree.find(Column).replace(column("y"))
574            Column(
575              this=Identifier(this=y, quoted=False))
576            >>> tree.sql()
577            'SELECT y FROM tbl'
578
579        Args:
580            expression: new node
581
582        Returns:
583            The new expression or expressions.
584        """
585        if not self.parent:
586            return expression
587
588        parent = self.parent
589        self.parent = None
590
591        replace_children(parent, lambda child: expression if child is self else child)
592        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:
594    def pop(self: E) -> E:
595        """
596        Remove this expression from its AST.
597
598        Returns:
599            The popped expression.
600        """
601        self.replace(None)
602        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
604    def assert_is(self, type_: t.Type[E]) -> E:
605        """
606        Assert that this `Expression` is an instance of `type_`.
607
608        If it is NOT an instance of `type_`, this raises an assertion error.
609        Otherwise, this returns this expression.
610
611        Examples:
612            This is useful for type security in chained expressions:
613
614            >>> import sqlglot
615            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
616            'SELECT x, z FROM y'
617        """
618        assert isinstance(self, type_)
619        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]:
621    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
622        """
623        Checks if this expression is valid (e.g. all mandatory args are set).
624
625        Args:
626            args: a sequence of values that were used to instantiate a Func expression. This is used
627                to check that the provided arguments don't exceed the function argument limit.
628
629        Returns:
630            A list of error messages for all possible errors that were found.
631        """
632        errors: t.List[str] = []
633
634        for k in self.args:
635            if k not in self.arg_types:
636                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
637        for k, mandatory in self.arg_types.items():
638            v = self.args.get(k)
639            if mandatory and (v is None or (isinstance(v, list) and not v)):
640                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
641
642        if (
643            args
644            and isinstance(self, Func)
645            and len(args) > len(self.arg_types)
646            and not self.is_var_len_args
647        ):
648            errors.append(
649                f"The number of provided arguments ({len(args)}) is greater than "
650                f"the maximum number of supported arguments ({len(self.arg_types)})"
651            )
652
653        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):
655    def dump(self):
656        """
657        Dump this Expression to a JSON-serializable dict.
658        """
659        from sqlglot.serde import dump
660
661        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
663    @classmethod
664    def load(cls, obj):
665        """
666        Load a dict (as returned by `Expression.dump`) into an Expression instance.
667        """
668        from sqlglot.serde import load
669
670        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:
672    def and_(
673        self,
674        *expressions: t.Optional[ExpOrStr],
675        dialect: DialectType = None,
676        copy: bool = True,
677        **opts,
678    ) -> Condition:
679        """
680        AND this condition with one or multiple expressions.
681
682        Example:
683            >>> condition("x=1").and_("y=1").sql()
684            'x = 1 AND y = 1'
685
686        Args:
687            *expressions: the SQL code strings to parse.
688                If an `Expression` instance is passed, it will be used as-is.
689            dialect: the dialect used to parse the input expression.
690            copy: whether or not to copy the involved expressions (only applies to Expressions).
691            opts: other options to use to parse the input expressions.
692
693        Returns:
694            The new And condition.
695        """
696        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:
698    def or_(
699        self,
700        *expressions: t.Optional[ExpOrStr],
701        dialect: DialectType = None,
702        copy: bool = True,
703        **opts,
704    ) -> Condition:
705        """
706        OR this condition with one or multiple expressions.
707
708        Example:
709            >>> condition("x=1").or_("y=1").sql()
710            'x = 1 OR y = 1'
711
712        Args:
713            *expressions: the SQL code strings to parse.
714                If an `Expression` instance is passed, it will be used as-is.
715            dialect: the dialect used to parse the input expression.
716            copy: whether or not to copy the involved expressions (only applies to Expressions).
717            opts: other options to use to parse the input expressions.
718
719        Returns:
720            The new Or condition.
721        """
722        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):
724    def not_(self, copy: bool = True):
725        """
726        Wrap this condition with NOT.
727
728        Example:
729            >>> condition("x=1").not_().sql()
730            'NOT x = 1'
731
732        Args:
733            copy: whether or not to copy this object.
734
735        Returns:
736            The new Not instance.
737        """
738        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:
740    def as_(
741        self,
742        alias: str | Identifier,
743        quoted: t.Optional[bool] = None,
744        dialect: DialectType = None,
745        copy: bool = True,
746        **opts,
747    ) -> Alias:
748        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:
773    def isin(
774        self,
775        *expressions: t.Any,
776        query: t.Optional[ExpOrStr] = None,
777        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
778        copy: bool = True,
779        **opts,
780    ) -> In:
781        return In(
782            this=maybe_copy(self, copy),
783            expressions=[convert(e, copy=copy) for e in expressions],
784            query=maybe_parse(query, copy=copy, **opts) if query else None,
785            unnest=Unnest(
786                expressions=[
787                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
788                ]
789            )
790            if unnest
791            else None,
792        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
794    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
795        return Between(
796            this=maybe_copy(self, copy),
797            low=convert(low, copy=copy, **opts),
798            high=convert(high, copy=copy, **opts),
799        )
def is_( self, other: Union[str, Expression]) -> Is:
801    def is_(self, other: ExpOrStr) -> Is:
802        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
804    def like(self, other: ExpOrStr) -> Like:
805        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
807    def ilike(self, other: ExpOrStr) -> ILike:
808        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
810    def eq(self, other: t.Any) -> EQ:
811        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
813    def neq(self, other: t.Any) -> NEQ:
814        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
816    def rlike(self, other: ExpOrStr) -> RegexpLike:
817        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
819    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
820        div = self._binop(Div, other)
821        div.args["typed"] = typed
822        div.args["safe"] = safe
823        return div
def desc(self, nulls_first: bool = False) -> Ordered:
825    def desc(self, nulls_first: bool = False) -> Ordered:
826        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
909class Condition(Expression):
910    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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):
1080class Create(DDL):
1081    arg_types = {
1082        "with": False,
1083        "this": True,
1084        "kind": True,
1085        "expression": False,
1086        "exists": False,
1087        "properties": False,
1088        "replace": False,
1089        "unique": False,
1090        "indexes": False,
1091        "no_schema_binding": False,
1092        "begin": False,
1093        "end": False,
1094        "clone": False,
1095    }
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):
1101class Clone(Expression):
1102    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1105class Describe(Expression):
1106    arg_types = {"this": True, "extended": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'extended': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1109class Kill(Expression):
1110    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1113class Pragma(Expression):
1114    pass
key = 'pragma'
class Set(Expression):
1117class Set(Expression):
1118    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1121class Heredoc(Expression):
1122    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1125class SetItem(Expression):
1126    arg_types = {
1127        "this": False,
1128        "expressions": False,
1129        "kind": False,
1130        "collate": False,  # MySQL SET NAMES statement
1131        "global": False,
1132    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1135class Show(Expression):
1136    arg_types = {
1137        "this": True,
1138        "target": False,
1139        "offset": False,
1140        "limit": False,
1141        "like": False,
1142        "where": False,
1143        "db": False,
1144        "scope": False,
1145        "scope_kind": False,
1146        "full": False,
1147        "mutex": False,
1148        "query": False,
1149        "channel": False,
1150        "global": False,
1151        "log": False,
1152        "position": False,
1153        "types": False,
1154    }
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):
1157class UserDefinedFunction(Expression):
1158    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1161class CharacterSet(Expression):
1162    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1165class With(Expression):
1166    arg_types = {"expressions": True, "recursive": False}
1167
1168    @property
1169    def recursive(self) -> bool:
1170        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1168    @property
1169    def recursive(self) -> bool:
1170        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1173class WithinGroup(Expression):
1174    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1179class CTE(DerivedTable):
1180    arg_types = {"this": True, "alias": True, "scalar": False}
arg_types = {'this': True, 'alias': True, 'scalar': False}
key = 'cte'
class TableAlias(Expression):
1183class TableAlias(Expression):
1184    arg_types = {"this": False, "columns": False}
1185
1186    @property
1187    def columns(self):
1188        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1186    @property
1187    def columns(self):
1188        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1191class BitString(Condition):
1192    pass
key = 'bitstring'
class HexString(Condition):
1195class HexString(Condition):
1196    pass
key = 'hexstring'
class ByteString(Condition):
1199class ByteString(Condition):
1200    pass
key = 'bytestring'
class RawString(Condition):
1203class RawString(Condition):
1204    pass
key = 'rawstring'
class UnicodeString(Condition):
1207class UnicodeString(Condition):
1208    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1211class Column(Condition):
1212    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1213
1214    @property
1215    def table(self) -> str:
1216        return self.text("table")
1217
1218    @property
1219    def db(self) -> str:
1220        return self.text("db")
1221
1222    @property
1223    def catalog(self) -> str:
1224        return self.text("catalog")
1225
1226    @property
1227    def output_name(self) -> str:
1228        return self.name
1229
1230    @property
1231    def parts(self) -> t.List[Identifier]:
1232        """Return the parts of a column in order catalog, db, table, name."""
1233        return [
1234            t.cast(Identifier, self.args[part])
1235            for part in ("catalog", "db", "table", "this")
1236            if self.args.get(part)
1237        ]
1238
1239    def to_dot(self) -> Dot | Identifier:
1240        """Converts the column into a dot expression."""
1241        parts = self.parts
1242        parent = self.parent
1243
1244        while parent:
1245            if isinstance(parent, Dot):
1246                parts.append(parent.expression)
1247            parent = parent.parent
1248
1249        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
1214    @property
1215    def table(self) -> str:
1216        return self.text("table")
db: str
1218    @property
1219    def db(self) -> str:
1220        return self.text("db")
catalog: str
1222    @property
1223    def catalog(self) -> str:
1224        return self.text("catalog")
output_name: str
1226    @property
1227    def output_name(self) -> str:
1228        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]
1230    @property
1231    def parts(self) -> t.List[Identifier]:
1232        """Return the parts of a column in order catalog, db, table, name."""
1233        return [
1234            t.cast(Identifier, self.args[part])
1235            for part in ("catalog", "db", "table", "this")
1236            if self.args.get(part)
1237        ]

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

def to_dot(self) -> Dot | Identifier:
1239    def to_dot(self) -> Dot | Identifier:
1240        """Converts the column into a dot expression."""
1241        parts = self.parts
1242        parent = self.parent
1243
1244        while parent:
1245            if isinstance(parent, Dot):
1246                parts.append(parent.expression)
1247            parent = parent.parent
1248
1249        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1252class ColumnPosition(Expression):
1253    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1256class ColumnDef(Expression):
1257    arg_types = {
1258        "this": True,
1259        "kind": False,
1260        "constraints": False,
1261        "exists": False,
1262        "position": False,
1263    }
1264
1265    @property
1266    def constraints(self) -> t.List[ColumnConstraint]:
1267        return self.args.get("constraints") or []
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1265    @property
1266    def constraints(self) -> t.List[ColumnConstraint]:
1267        return self.args.get("constraints") or []
key = 'columndef'
class AlterColumn(Expression):
1270class AlterColumn(Expression):
1271    arg_types = {
1272        "this": True,
1273        "dtype": False,
1274        "collate": False,
1275        "using": False,
1276        "default": False,
1277        "drop": False,
1278    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False}
key = 'altercolumn'
class RenameTable(Expression):
1281class RenameTable(Expression):
1282    pass
key = 'renametable'
class SwapTable(Expression):
1285class SwapTable(Expression):
1286    pass
key = 'swaptable'
class Comment(Expression):
1289class Comment(Expression):
1290    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):
1293class Comprehension(Expression):
1294    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):
1298class MergeTreeTTLAction(Expression):
1299    arg_types = {
1300        "this": True,
1301        "delete": False,
1302        "recompress": False,
1303        "to_disk": False,
1304        "to_volume": False,
1305    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1309class MergeTreeTTL(Expression):
1310    arg_types = {
1311        "expressions": True,
1312        "where": False,
1313        "group": False,
1314        "aggregates": False,
1315    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1319class IndexConstraintOption(Expression):
1320    arg_types = {
1321        "key_block_size": False,
1322        "using": False,
1323        "parser": False,
1324        "comment": False,
1325        "visible": False,
1326        "engine_attr": False,
1327        "secondary_engine_attr": False,
1328    }
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):
1331class ColumnConstraint(Expression):
1332    arg_types = {"this": False, "kind": True}
1333
1334    @property
1335    def kind(self) -> ColumnConstraintKind:
1336        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1334    @property
1335    def kind(self) -> ColumnConstraintKind:
1336        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1339class ColumnConstraintKind(Expression):
1340    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1343class AutoIncrementColumnConstraint(ColumnConstraintKind):
1344    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1347class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1348    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1351class CaseSpecificColumnConstraint(ColumnConstraintKind):
1352    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1355class CharacterSetColumnConstraint(ColumnConstraintKind):
1356    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1359class CheckColumnConstraint(ColumnConstraintKind):
1360    pass
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1363class ClusteredColumnConstraint(ColumnConstraintKind):
1364    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1367class CollateColumnConstraint(ColumnConstraintKind):
1368    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1371class CommentColumnConstraint(ColumnConstraintKind):
1372    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1375class CompressColumnConstraint(ColumnConstraintKind):
1376    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1379class DateFormatColumnConstraint(ColumnConstraintKind):
1380    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1383class DefaultColumnConstraint(ColumnConstraintKind):
1384    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1387class EncodeColumnConstraint(ColumnConstraintKind):
1388    pass
key = 'encodecolumnconstraint'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1391class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1392    # this: True -> ALWAYS, this: False -> BY DEFAULT
1393    arg_types = {
1394        "this": False,
1395        "expression": False,
1396        "on_null": False,
1397        "start": False,
1398        "increment": False,
1399        "minvalue": False,
1400        "maxvalue": False,
1401        "cycle": False,
1402    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1405class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1406    arg_types = {"start": True, "hidden": False}
arg_types = {'start': True, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1410class IndexColumnConstraint(ColumnConstraintKind):
1411    arg_types = {
1412        "this": False,
1413        "schema": True,
1414        "kind": False,
1415        "index_type": False,
1416        "options": False,
1417    }
arg_types = {'this': False, 'schema': True, 'kind': False, 'index_type': False, 'options': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1420class InlineLengthColumnConstraint(ColumnConstraintKind):
1421    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1424class NonClusteredColumnConstraint(ColumnConstraintKind):
1425    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1428class NotForReplicationColumnConstraint(ColumnConstraintKind):
1429    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1432class NotNullColumnConstraint(ColumnConstraintKind):
1433    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1437class OnUpdateColumnConstraint(ColumnConstraintKind):
1438    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1442class TransformColumnConstraint(ColumnConstraintKind):
1443    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1446class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1447    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1450class TitleColumnConstraint(ColumnConstraintKind):
1451    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1454class UniqueColumnConstraint(ColumnConstraintKind):
1455    arg_types = {"this": False, "index_type": False}
arg_types = {'this': False, 'index_type': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1458class UppercaseColumnConstraint(ColumnConstraintKind):
1459    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1462class PathColumnConstraint(ColumnConstraintKind):
1463    pass
key = 'pathcolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1468class ComputedColumnConstraint(ColumnConstraintKind):
1469    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1472class Constraint(Expression):
1473    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1476class Delete(DML):
1477    arg_types = {
1478        "with": False,
1479        "this": False,
1480        "using": False,
1481        "where": False,
1482        "returning": False,
1483        "limit": False,
1484        "tables": False,  # Multiple-Table Syntax (MySQL)
1485    }
1486
1487    def delete(
1488        self,
1489        table: ExpOrStr,
1490        dialect: DialectType = None,
1491        copy: bool = True,
1492        **opts,
1493    ) -> Delete:
1494        """
1495        Create a DELETE expression or replace the table on an existing DELETE expression.
1496
1497        Example:
1498            >>> delete("tbl").sql()
1499            'DELETE FROM tbl'
1500
1501        Args:
1502            table: the table from which to delete.
1503            dialect: the dialect used to parse the input expression.
1504            copy: if `False`, modify this expression instance in-place.
1505            opts: other options to use to parse the input expressions.
1506
1507        Returns:
1508            Delete: the modified expression.
1509        """
1510        return _apply_builder(
1511            expression=table,
1512            instance=self,
1513            arg="this",
1514            dialect=dialect,
1515            into=Table,
1516            copy=copy,
1517            **opts,
1518        )
1519
1520    def where(
1521        self,
1522        *expressions: t.Optional[ExpOrStr],
1523        append: bool = True,
1524        dialect: DialectType = None,
1525        copy: bool = True,
1526        **opts,
1527    ) -> Delete:
1528        """
1529        Append to or set the WHERE expressions.
1530
1531        Example:
1532            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1533            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1534
1535        Args:
1536            *expressions: the SQL code strings to parse.
1537                If an `Expression` instance is passed, it will be used as-is.
1538                Multiple expressions are combined with an AND operator.
1539            append: if `True`, AND the new expressions to any existing expression.
1540                Otherwise, this resets the expression.
1541            dialect: the dialect used to parse the input expressions.
1542            copy: if `False`, modify this expression instance in-place.
1543            opts: other options to use to parse the input expressions.
1544
1545        Returns:
1546            Delete: the modified expression.
1547        """
1548        return _apply_conjunction_builder(
1549            *expressions,
1550            instance=self,
1551            arg="where",
1552            append=append,
1553            into=Where,
1554            dialect=dialect,
1555            copy=copy,
1556            **opts,
1557        )
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:
1487    def delete(
1488        self,
1489        table: ExpOrStr,
1490        dialect: DialectType = None,
1491        copy: bool = True,
1492        **opts,
1493    ) -> Delete:
1494        """
1495        Create a DELETE expression or replace the table on an existing DELETE expression.
1496
1497        Example:
1498            >>> delete("tbl").sql()
1499            'DELETE FROM tbl'
1500
1501        Args:
1502            table: the table from which to delete.
1503            dialect: the dialect used to parse the input expression.
1504            copy: if `False`, modify this expression instance in-place.
1505            opts: other options to use to parse the input expressions.
1506
1507        Returns:
1508            Delete: the modified expression.
1509        """
1510        return _apply_builder(
1511            expression=table,
1512            instance=self,
1513            arg="this",
1514            dialect=dialect,
1515            into=Table,
1516            copy=copy,
1517            **opts,
1518        )

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

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):
1560class Drop(Expression):
1561    arg_types = {
1562        "this": False,
1563        "kind": False,
1564        "exists": False,
1565        "temporary": False,
1566        "materialized": False,
1567        "cascade": False,
1568        "constraints": False,
1569        "purge": False,
1570    }
arg_types = {'this': False, 'kind': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False}
key = 'drop'
class Filter(Expression):
1573class Filter(Expression):
1574    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
1577class Check(Expression):
1578    pass
key = 'check'
class Connect(Expression):
1582class Connect(Expression):
1583    arg_types = {"start": False, "connect": True}
arg_types = {'start': False, 'connect': True}
key = 'connect'
class Prior(Expression):
1586class Prior(Expression):
1587    pass
key = 'prior'
class Directory(Expression):
1590class Directory(Expression):
1591    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
1592    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
1595class ForeignKey(Expression):
1596    arg_types = {
1597        "expressions": True,
1598        "reference": False,
1599        "delete": False,
1600        "update": False,
1601    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
1604class ColumnPrefix(Expression):
1605    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
1608class PrimaryKey(Expression):
1609    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
1614class Into(Expression):
1615    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
1618class From(Expression):
1619    @property
1620    def name(self) -> str:
1621        return self.this.name
1622
1623    @property
1624    def alias_or_name(self) -> str:
1625        return self.this.alias_or_name
name: str
1619    @property
1620    def name(self) -> str:
1621        return self.this.name
alias_or_name: str
1623    @property
1624    def alias_or_name(self) -> str:
1625        return self.this.alias_or_name
key = 'from'
class Having(Expression):
1628class Having(Expression):
1629    pass
key = 'having'
class Hint(Expression):
1632class Hint(Expression):
1633    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
1636class JoinHint(Expression):
1637    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
1640class Identifier(Expression):
1641    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
1642
1643    @property
1644    def quoted(self) -> bool:
1645        return bool(self.args.get("quoted"))
1646
1647    @property
1648    def hashable_args(self) -> t.Any:
1649        return (self.this, self.quoted)
1650
1651    @property
1652    def output_name(self) -> str:
1653        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
1643    @property
1644    def quoted(self) -> bool:
1645        return bool(self.args.get("quoted"))
hashable_args: Any
1647    @property
1648    def hashable_args(self) -> t.Any:
1649        return (self.this, self.quoted)
output_name: str
1651    @property
1652    def output_name(self) -> str:
1653        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):
1657class Opclass(Expression):
1658    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
1661class Index(Expression):
1662    arg_types = {
1663        "this": False,
1664        "table": False,
1665        "using": False,
1666        "where": False,
1667        "columns": False,
1668        "unique": False,
1669        "primary": False,
1670        "amp": False,  # teradata
1671        "partition_by": False,  # teradata
1672        "where": False,  # postgres partial indexes
1673    }
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):
1676class Insert(DDL, DML):
1677    arg_types = {
1678        "with": False,
1679        "this": True,
1680        "expression": False,
1681        "conflict": False,
1682        "returning": False,
1683        "overwrite": False,
1684        "exists": False,
1685        "partition": False,
1686        "alternative": False,
1687        "where": False,
1688        "ignore": False,
1689        "by_name": False,
1690    }
1691
1692    def with_(
1693        self,
1694        alias: ExpOrStr,
1695        as_: ExpOrStr,
1696        recursive: t.Optional[bool] = None,
1697        append: bool = True,
1698        dialect: DialectType = None,
1699        copy: bool = True,
1700        **opts,
1701    ) -> Insert:
1702        """
1703        Append to or set the common table expressions.
1704
1705        Example:
1706            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1707            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1708
1709        Args:
1710            alias: the SQL code string to parse as the table name.
1711                If an `Expression` instance is passed, this is used as-is.
1712            as_: the SQL code string to parse as the table expression.
1713                If an `Expression` instance is passed, it will be used as-is.
1714            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1715            append: if `True`, add to any existing expressions.
1716                Otherwise, this resets the expressions.
1717            dialect: the dialect used to parse the input expression.
1718            copy: if `False`, modify this expression instance in-place.
1719            opts: other options to use to parse the input expressions.
1720
1721        Returns:
1722            The modified expression.
1723        """
1724        return _apply_cte_builder(
1725            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1726        )
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:
1692    def with_(
1693        self,
1694        alias: ExpOrStr,
1695        as_: ExpOrStr,
1696        recursive: t.Optional[bool] = None,
1697        append: bool = True,
1698        dialect: DialectType = None,
1699        copy: bool = True,
1700        **opts,
1701    ) -> Insert:
1702        """
1703        Append to or set the common table expressions.
1704
1705        Example:
1706            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1707            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1708
1709        Args:
1710            alias: the SQL code string to parse as the table name.
1711                If an `Expression` instance is passed, this is used as-is.
1712            as_: the SQL code string to parse as the table expression.
1713                If an `Expression` instance is passed, it will be used as-is.
1714            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1715            append: if `True`, add to any existing expressions.
1716                Otherwise, this resets the expressions.
1717            dialect: the dialect used to parse the input expression.
1718            copy: if `False`, modify this expression instance in-place.
1719            opts: other options to use to parse the input expressions.
1720
1721        Returns:
1722            The modified expression.
1723        """
1724        return _apply_cte_builder(
1725            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1726        )

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):
1729class OnConflict(Expression):
1730    arg_types = {
1731        "duplicate": False,
1732        "expressions": False,
1733        "nothing": False,
1734        "key": False,
1735        "constraint": False,
1736    }
arg_types = {'duplicate': False, 'expressions': False, 'nothing': False, 'key': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
1739class Returning(Expression):
1740    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
1744class Introducer(Expression):
1745    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
1749class National(Expression):
1750    pass
key = 'national'
class LoadData(Expression):
1753class LoadData(Expression):
1754    arg_types = {
1755        "this": True,
1756        "local": False,
1757        "overwrite": False,
1758        "inpath": True,
1759        "partition": False,
1760        "input_format": False,
1761        "serde": False,
1762    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
1765class Partition(Expression):
1766    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class Fetch(Expression):
1769class Fetch(Expression):
1770    arg_types = {
1771        "direction": False,
1772        "count": False,
1773        "percent": False,
1774        "with_ties": False,
1775    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
1778class Group(Expression):
1779    arg_types = {
1780        "expressions": False,
1781        "grouping_sets": False,
1782        "cube": False,
1783        "rollup": False,
1784        "totals": False,
1785        "all": False,
1786    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
1789class Lambda(Expression):
1790    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
1793class Limit(Expression):
1794    arg_types = {"this": False, "expression": True, "offset": False}
arg_types = {'this': False, 'expression': True, 'offset': False}
key = 'limit'
class Literal(Condition):
1797class Literal(Condition):
1798    arg_types = {"this": True, "is_string": True}
1799
1800    @property
1801    def hashable_args(self) -> t.Any:
1802        return (self.this, self.args.get("is_string"))
1803
1804    @classmethod
1805    def number(cls, number) -> Literal:
1806        return cls(this=str(number), is_string=False)
1807
1808    @classmethod
1809    def string(cls, string) -> Literal:
1810        return cls(this=str(string), is_string=True)
1811
1812    @property
1813    def output_name(self) -> str:
1814        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
1800    @property
1801    def hashable_args(self) -> t.Any:
1802        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
1804    @classmethod
1805    def number(cls, number) -> Literal:
1806        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
1808    @classmethod
1809    def string(cls, string) -> Literal:
1810        return cls(this=str(string), is_string=True)
output_name: str
1812    @property
1813    def output_name(self) -> str:
1814        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):
1817class Join(Expression):
1818    arg_types = {
1819        "this": True,
1820        "on": False,
1821        "side": False,
1822        "kind": False,
1823        "using": False,
1824        "method": False,
1825        "global": False,
1826        "hint": False,
1827    }
1828
1829    @property
1830    def method(self) -> str:
1831        return self.text("method").upper()
1832
1833    @property
1834    def kind(self) -> str:
1835        return self.text("kind").upper()
1836
1837    @property
1838    def side(self) -> str:
1839        return self.text("side").upper()
1840
1841    @property
1842    def hint(self) -> str:
1843        return self.text("hint").upper()
1844
1845    @property
1846    def alias_or_name(self) -> str:
1847        return self.this.alias_or_name
1848
1849    def on(
1850        self,
1851        *expressions: t.Optional[ExpOrStr],
1852        append: bool = True,
1853        dialect: DialectType = None,
1854        copy: bool = True,
1855        **opts,
1856    ) -> Join:
1857        """
1858        Append to or set the ON expressions.
1859
1860        Example:
1861            >>> import sqlglot
1862            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1863            'JOIN x ON y = 1'
1864
1865        Args:
1866            *expressions: the SQL code strings to parse.
1867                If an `Expression` instance is passed, it will be used as-is.
1868                Multiple expressions are combined with an AND operator.
1869            append: if `True`, AND the new expressions to any existing expression.
1870                Otherwise, this resets the expression.
1871            dialect: the dialect used to parse the input expressions.
1872            copy: if `False`, modify this expression instance in-place.
1873            opts: other options to use to parse the input expressions.
1874
1875        Returns:
1876            The modified Join expression.
1877        """
1878        join = _apply_conjunction_builder(
1879            *expressions,
1880            instance=self,
1881            arg="on",
1882            append=append,
1883            dialect=dialect,
1884            copy=copy,
1885            **opts,
1886        )
1887
1888        if join.kind == "CROSS":
1889            join.set("kind", None)
1890
1891        return join
1892
1893    def using(
1894        self,
1895        *expressions: t.Optional[ExpOrStr],
1896        append: bool = True,
1897        dialect: DialectType = None,
1898        copy: bool = True,
1899        **opts,
1900    ) -> Join:
1901        """
1902        Append to or set the USING expressions.
1903
1904        Example:
1905            >>> import sqlglot
1906            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1907            'JOIN x USING (foo, bla)'
1908
1909        Args:
1910            *expressions: the SQL code strings to parse.
1911                If an `Expression` instance is passed, it will be used as-is.
1912            append: if `True`, concatenate the new expressions to the existing "using" list.
1913                Otherwise, this resets the expression.
1914            dialect: the dialect used to parse the input expressions.
1915            copy: if `False`, modify this expression instance in-place.
1916            opts: other options to use to parse the input expressions.
1917
1918        Returns:
1919            The modified Join expression.
1920        """
1921        join = _apply_list_builder(
1922            *expressions,
1923            instance=self,
1924            arg="using",
1925            append=append,
1926            dialect=dialect,
1927            copy=copy,
1928            **opts,
1929        )
1930
1931        if join.kind == "CROSS":
1932            join.set("kind", None)
1933
1934        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False}
method: str
1829    @property
1830    def method(self) -> str:
1831        return self.text("method").upper()
kind: str
1833    @property
1834    def kind(self) -> str:
1835        return self.text("kind").upper()
side: str
1837    @property
1838    def side(self) -> str:
1839        return self.text("side").upper()
hint: str
1841    @property
1842    def hint(self) -> str:
1843        return self.text("hint").upper()
alias_or_name: str
1845    @property
1846    def alias_or_name(self) -> str:
1847        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:
1849    def on(
1850        self,
1851        *expressions: t.Optional[ExpOrStr],
1852        append: bool = True,
1853        dialect: DialectType = None,
1854        copy: bool = True,
1855        **opts,
1856    ) -> Join:
1857        """
1858        Append to or set the ON expressions.
1859
1860        Example:
1861            >>> import sqlglot
1862            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
1863            'JOIN x ON y = 1'
1864
1865        Args:
1866            *expressions: the SQL code strings to parse.
1867                If an `Expression` instance is passed, it will be used as-is.
1868                Multiple expressions are combined with an AND operator.
1869            append: if `True`, AND the new expressions to any existing expression.
1870                Otherwise, this resets the expression.
1871            dialect: the dialect used to parse the input expressions.
1872            copy: if `False`, modify this expression instance in-place.
1873            opts: other options to use to parse the input expressions.
1874
1875        Returns:
1876            The modified Join expression.
1877        """
1878        join = _apply_conjunction_builder(
1879            *expressions,
1880            instance=self,
1881            arg="on",
1882            append=append,
1883            dialect=dialect,
1884            copy=copy,
1885            **opts,
1886        )
1887
1888        if join.kind == "CROSS":
1889            join.set("kind", None)
1890
1891        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:
1893    def using(
1894        self,
1895        *expressions: t.Optional[ExpOrStr],
1896        append: bool = True,
1897        dialect: DialectType = None,
1898        copy: bool = True,
1899        **opts,
1900    ) -> Join:
1901        """
1902        Append to or set the USING expressions.
1903
1904        Example:
1905            >>> import sqlglot
1906            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
1907            'JOIN x USING (foo, bla)'
1908
1909        Args:
1910            *expressions: the SQL code strings to parse.
1911                If an `Expression` instance is passed, it will be used as-is.
1912            append: if `True`, concatenate the new expressions to the existing "using" list.
1913                Otherwise, this resets the expression.
1914            dialect: the dialect used to parse the input expressions.
1915            copy: if `False`, modify this expression instance in-place.
1916            opts: other options to use to parse the input expressions.
1917
1918        Returns:
1919            The modified Join expression.
1920        """
1921        join = _apply_list_builder(
1922            *expressions,
1923            instance=self,
1924            arg="using",
1925            append=append,
1926            dialect=dialect,
1927            copy=copy,
1928            **opts,
1929        )
1930
1931        if join.kind == "CROSS":
1932            join.set("kind", None)
1933
1934        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):
1937class Lateral(UDTF):
1938    arg_types = {
1939        "this": True,
1940        "view": False,
1941        "outer": False,
1942        "alias": False,
1943        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
1944    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognize(Expression):
1947class MatchRecognize(Expression):
1948    arg_types = {
1949        "partition_by": False,
1950        "order": False,
1951        "measures": False,
1952        "rows": False,
1953        "after": False,
1954        "pattern": False,
1955        "define": False,
1956        "alias": False,
1957    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
1962class Final(Expression):
1963    pass
key = 'final'
class Offset(Expression):
1966class Offset(Expression):
1967    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'offset'
class Order(Expression):
1970class Order(Expression):
1971    arg_types = {
1972        "this": False,
1973        "expressions": True,
1974        "interpolate": False,
1975        "siblings": False,
1976    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
1980class WithFill(Expression):
1981    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
1986class Cluster(Order):
1987    pass
key = 'cluster'
class Distribute(Order):
1990class Distribute(Order):
1991    pass
key = 'distribute'
class Sort(Order):
1994class Sort(Order):
1995    pass
key = 'sort'
class Ordered(Expression):
1998class Ordered(Expression):
1999    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):
2002class Property(Expression):
2003    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AlgorithmProperty(Property):
2006class AlgorithmProperty(Property):
2007    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2010class AutoIncrementProperty(Property):
2011    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2015class AutoRefreshProperty(Property):
2016    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BlockCompressionProperty(Property):
2019class BlockCompressionProperty(Property):
2020    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):
2023class CharacterSetProperty(Property):
2024    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2027class ChecksumProperty(Property):
2028    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2031class CollateProperty(Property):
2032    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2035class CopyGrantsProperty(Property):
2036    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2039class DataBlocksizeProperty(Property):
2040    arg_types = {
2041        "size": False,
2042        "units": False,
2043        "minimum": False,
2044        "maximum": False,
2045        "default": False,
2046    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DefinerProperty(Property):
2049class DefinerProperty(Property):
2050    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2053class DistKeyProperty(Property):
2054    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2057class DistStyleProperty(Property):
2058    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2061class EngineProperty(Property):
2062    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2065class HeapProperty(Property):
2066    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2069class ToTableProperty(Property):
2070    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2073class ExecuteAsProperty(Property):
2074    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2077class ExternalProperty(Property):
2078    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2081class FallbackProperty(Property):
2082    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2085class FileFormatProperty(Property):
2086    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2089class FreespaceProperty(Property):
2090    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class InputModelProperty(Property):
2093class InputModelProperty(Property):
2094    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2097class OutputModelProperty(Property):
2098    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2101class IsolatedLoadingProperty(Property):
2102    arg_types = {
2103        "no": True,
2104        "concurrent": True,
2105        "for_all": True,
2106        "for_insert": True,
2107        "for_none": True,
2108    }
arg_types = {'no': True, 'concurrent': True, 'for_all': True, 'for_insert': True, 'for_none': True}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2111class JournalProperty(Property):
2112    arg_types = {
2113        "no": False,
2114        "dual": False,
2115        "before": False,
2116        "local": False,
2117        "after": False,
2118    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2121class LanguageProperty(Property):
2122    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2126class ClusteredByProperty(Property):
2127    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2130class DictProperty(Property):
2131    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2134class DictSubProperty(Property):
2135    pass
key = 'dictsubproperty'
class DictRange(Property):
2138class DictRange(Property):
2139    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2144class OnCluster(Property):
2145    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2148class LikeProperty(Property):
2149    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2152class LocationProperty(Property):
2153    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockingProperty(Property):
2156class LockingProperty(Property):
2157    arg_types = {
2158        "this": False,
2159        "kind": True,
2160        "for_or_in": False,
2161        "lock_type": True,
2162        "override": False,
2163    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2166class LogProperty(Property):
2167    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2170class MaterializedProperty(Property):
2171    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2174class MergeBlockRatioProperty(Property):
2175    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):
2178class NoPrimaryIndexProperty(Property):
2179    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2182class OnProperty(Property):
2183    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2186class OnCommitProperty(Property):
2187    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2190class PartitionedByProperty(Property):
2191    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2195class PartitionBoundSpec(Expression):
2196    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2197    arg_types = {
2198        "this": False,
2199        "expression": False,
2200        "from_expressions": False,
2201        "to_expressions": False,
2202    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2205class PartitionedOfProperty(Property):
2206    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2207    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2210class RemoteWithConnectionModelProperty(Property):
2211    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2214class ReturnsProperty(Property):
2215    arg_types = {"this": True, "is_table": False, "table": False}
arg_types = {'this': True, 'is_table': False, 'table': False}
key = 'returnsproperty'
class RowFormatProperty(Property):
2218class RowFormatProperty(Property):
2219    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2222class RowFormatDelimitedProperty(Property):
2223    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2224    arg_types = {
2225        "fields": False,
2226        "escaped": False,
2227        "collection_items": False,
2228        "map_keys": False,
2229        "lines": False,
2230        "null": False,
2231        "serde": False,
2232    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2235class RowFormatSerdeProperty(Property):
2236    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2240class QueryTransform(Expression):
2241    arg_types = {
2242        "expressions": True,
2243        "command_script": True,
2244        "schema": False,
2245        "row_format_before": False,
2246        "record_writer": False,
2247        "row_format_after": False,
2248        "record_reader": False,
2249    }
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):
2252class SampleProperty(Property):
2253    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2256class SchemaCommentProperty(Property):
2257    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2260class SerdeProperties(Property):
2261    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'serdeproperties'
class SetProperty(Property):
2264class SetProperty(Property):
2265    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SettingsProperty(Property):
2268class SettingsProperty(Property):
2269    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2272class SortKeyProperty(Property):
2273    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2276class SqlReadWriteProperty(Property):
2277    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2280class SqlSecurityProperty(Property):
2281    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2284class StabilityProperty(Property):
2285    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2288class TemporaryProperty(Property):
2289    arg_types = {}
arg_types = {}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2292class TransformModelProperty(Property):
2293    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2296class TransientProperty(Property):
2297    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class VolatileProperty(Property):
2300class VolatileProperty(Property):
2301    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2304class WithDataProperty(Property):
2305    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2308class WithJournalTableProperty(Property):
2309    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2312class WithSystemVersioningProperty(Property):
2313    # this -> history table name, expression -> data consistency check
2314    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'withsystemversioningproperty'
class Properties(Expression):
2317class Properties(Expression):
2318    arg_types = {"expressions": True}
2319
2320    NAME_TO_PROPERTY = {
2321        "ALGORITHM": AlgorithmProperty,
2322        "AUTO_INCREMENT": AutoIncrementProperty,
2323        "CHARACTER SET": CharacterSetProperty,
2324        "CLUSTERED_BY": ClusteredByProperty,
2325        "COLLATE": CollateProperty,
2326        "COMMENT": SchemaCommentProperty,
2327        "DEFINER": DefinerProperty,
2328        "DISTKEY": DistKeyProperty,
2329        "DISTSTYLE": DistStyleProperty,
2330        "ENGINE": EngineProperty,
2331        "EXECUTE AS": ExecuteAsProperty,
2332        "FORMAT": FileFormatProperty,
2333        "LANGUAGE": LanguageProperty,
2334        "LOCATION": LocationProperty,
2335        "PARTITIONED_BY": PartitionedByProperty,
2336        "RETURNS": ReturnsProperty,
2337        "ROW_FORMAT": RowFormatProperty,
2338        "SORTKEY": SortKeyProperty,
2339    }
2340
2341    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2342
2343    # CREATE property locations
2344    # Form: schema specified
2345    #   create [POST_CREATE]
2346    #     table a [POST_NAME]
2347    #     (b int) [POST_SCHEMA]
2348    #     with ([POST_WITH])
2349    #     index (b) [POST_INDEX]
2350    #
2351    # Form: alias selection
2352    #   create [POST_CREATE]
2353    #     table a [POST_NAME]
2354    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2355    #     index (c) [POST_INDEX]
2356    class Location(AutoName):
2357        POST_CREATE = auto()
2358        POST_NAME = auto()
2359        POST_SCHEMA = auto()
2360        POST_WITH = auto()
2361        POST_ALIAS = auto()
2362        POST_EXPRESSION = auto()
2363        POST_INDEX = auto()
2364        UNSUPPORTED = auto()
2365
2366    @classmethod
2367    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2368        expressions = []
2369        for key, value in properties_dict.items():
2370            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2371            if property_cls:
2372                expressions.append(property_cls(this=convert(value)))
2373            else:
2374                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2375
2376        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:
2366    @classmethod
2367    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2368        expressions = []
2369        for key, value in properties_dict.items():
2370            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2371            if property_cls:
2372                expressions.append(property_cls(this=convert(value)))
2373            else:
2374                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2375
2376        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2356    class Location(AutoName):
2357        POST_CREATE = auto()
2358        POST_NAME = auto()
2359        POST_SCHEMA = auto()
2360        POST_WITH = auto()
2361        POST_ALIAS = auto()
2362        POST_EXPRESSION = auto()
2363        POST_INDEX = auto()
2364        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):
2379class Qualify(Expression):
2380    pass
key = 'qualify'
class InputOutputFormat(Expression):
2383class InputOutputFormat(Expression):
2384    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2388class Return(Expression):
2389    pass
key = 'return'
class Reference(Expression):
2392class Reference(Expression):
2393    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2396class Tuple(Expression):
2397    arg_types = {"expressions": False}
2398
2399    def isin(
2400        self,
2401        *expressions: t.Any,
2402        query: t.Optional[ExpOrStr] = None,
2403        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2404        copy: bool = True,
2405        **opts,
2406    ) -> In:
2407        return In(
2408            this=maybe_copy(self, copy),
2409            expressions=[convert(e, copy=copy) for e in expressions],
2410            query=maybe_parse(query, copy=copy, **opts) if query else None,
2411            unnest=Unnest(
2412                expressions=[
2413                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2414                ]
2415            )
2416            if unnest
2417            else None,
2418        )
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:
2399    def isin(
2400        self,
2401        *expressions: t.Any,
2402        query: t.Optional[ExpOrStr] = None,
2403        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2404        copy: bool = True,
2405        **opts,
2406    ) -> In:
2407        return In(
2408            this=maybe_copy(self, copy),
2409            expressions=[convert(e, copy=copy) for e in expressions],
2410            query=maybe_parse(query, copy=copy, **opts) if query else None,
2411            unnest=Unnest(
2412                expressions=[
2413                    maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts) for e in ensure_list(unnest)
2414                ]
2415            )
2416            if unnest
2417            else None,
2418        )
key = 'tuple'
class Subqueryable(Unionable):
2421class Subqueryable(Unionable):
2422    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2423        """
2424        Convert this expression to an aliased expression that can be used as a Subquery.
2425
2426        Example:
2427            >>> subquery = Select().select("x").from_("tbl").subquery()
2428            >>> Select().select("x").from_(subquery).sql()
2429            'SELECT x FROM (SELECT x FROM tbl)'
2430
2431        Args:
2432            alias (str | Identifier): an optional alias for the subquery
2433            copy (bool): if `False`, modify this expression instance in-place.
2434
2435        Returns:
2436            Alias: the subquery
2437        """
2438        instance = maybe_copy(self, copy)
2439        if not isinstance(alias, Expression):
2440            alias = TableAlias(this=to_identifier(alias)) if alias else None
2441
2442        return Subquery(this=instance, alias=alias)
2443
2444    def limit(
2445        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2446    ) -> Select:
2447        raise NotImplementedError
2448
2449    @property
2450    def ctes(self):
2451        with_ = self.args.get("with")
2452        if not with_:
2453            return []
2454        return with_.expressions
2455
2456    @property
2457    def selects(self) -> t.List[Expression]:
2458        raise NotImplementedError("Subqueryable objects must implement `selects`")
2459
2460    @property
2461    def named_selects(self) -> t.List[str]:
2462        raise NotImplementedError("Subqueryable objects must implement `named_selects`")
2463
2464    def select(
2465        self,
2466        *expressions: t.Optional[ExpOrStr],
2467        append: bool = True,
2468        dialect: DialectType = None,
2469        copy: bool = True,
2470        **opts,
2471    ) -> Subqueryable:
2472        raise NotImplementedError("Subqueryable objects must implement `select`")
2473
2474    def with_(
2475        self,
2476        alias: ExpOrStr,
2477        as_: ExpOrStr,
2478        recursive: t.Optional[bool] = None,
2479        append: bool = True,
2480        dialect: DialectType = None,
2481        copy: bool = True,
2482        **opts,
2483    ) -> Subqueryable:
2484        """
2485        Append to or set the common table expressions.
2486
2487        Example:
2488            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2489            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2490
2491        Args:
2492            alias: the SQL code string to parse as the table name.
2493                If an `Expression` instance is passed, this is used as-is.
2494            as_: the SQL code string to parse as the table expression.
2495                If an `Expression` instance is passed, it will be used as-is.
2496            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2497            append: if `True`, add to any existing expressions.
2498                Otherwise, this resets the expressions.
2499            dialect: the dialect used to parse the input expression.
2500            copy: if `False`, modify this expression instance in-place.
2501            opts: other options to use to parse the input expressions.
2502
2503        Returns:
2504            The modified expression.
2505        """
2506        return _apply_cte_builder(
2507            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2508        )
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
2422    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
2423        """
2424        Convert this expression to an aliased expression that can be used as a Subquery.
2425
2426        Example:
2427            >>> subquery = Select().select("x").from_("tbl").subquery()
2428            >>> Select().select("x").from_(subquery).sql()
2429            'SELECT x FROM (SELECT x FROM tbl)'
2430
2431        Args:
2432            alias (str | Identifier): an optional alias for the subquery
2433            copy (bool): if `False`, modify this expression instance in-place.
2434
2435        Returns:
2436            Alias: the subquery
2437        """
2438        instance = maybe_copy(self, copy)
2439        if not isinstance(alias, Expression):
2440            alias = TableAlias(this=to_identifier(alias)) if alias else None
2441
2442        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:
2444    def limit(
2445        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
2446    ) -> Select:
2447        raise NotImplementedError
ctes
2449    @property
2450    def ctes(self):
2451        with_ = self.args.get("with")
2452        if not with_:
2453            return []
2454        return with_.expressions
selects: List[Expression]
2456    @property
2457    def selects(self) -> t.List[Expression]:
2458        raise NotImplementedError("Subqueryable objects must implement `selects`")
named_selects: List[str]
2460    @property
2461    def named_selects(self) -> t.List[str]:
2462        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:
2464    def select(
2465        self,
2466        *expressions: t.Optional[ExpOrStr],
2467        append: bool = True,
2468        dialect: DialectType = None,
2469        copy: bool = True,
2470        **opts,
2471    ) -> Subqueryable:
2472        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:
2474    def with_(
2475        self,
2476        alias: ExpOrStr,
2477        as_: ExpOrStr,
2478        recursive: t.Optional[bool] = None,
2479        append: bool = True,
2480        dialect: DialectType = None,
2481        copy: bool = True,
2482        **opts,
2483    ) -> Subqueryable:
2484        """
2485        Append to or set the common table expressions.
2486
2487        Example:
2488            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
2489            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
2490
2491        Args:
2492            alias: the SQL code string to parse as the table name.
2493                If an `Expression` instance is passed, this is used as-is.
2494            as_: the SQL code string to parse as the table expression.
2495                If an `Expression` instance is passed, it will be used as-is.
2496            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2497            append: if `True`, add to any existing expressions.
2498                Otherwise, this resets the expressions.
2499            dialect: the dialect used to parse the input expression.
2500            copy: if `False`, modify this expression instance in-place.
2501            opts: other options to use to parse the input expressions.
2502
2503        Returns:
2504            The modified expression.
2505        """
2506        return _apply_cte_builder(
2507            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2508        )

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

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

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

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:
2652    def select(
2653        self,
2654        *expressions: t.Optional[ExpOrStr],
2655        append: bool = True,
2656        dialect: DialectType = None,
2657        copy: bool = True,
2658        **opts,
2659    ) -> Union:
2660        """Append to or set the SELECT of the union recursively.
2661
2662        Example:
2663            >>> from sqlglot import parse_one
2664            >>> parse_one("select a from x union select a from y union select a from z").select("b").sql()
2665            'SELECT a, b FROM x UNION SELECT a, b FROM y UNION SELECT a, b FROM z'
2666
2667        Args:
2668            *expressions: the SQL code strings to parse.
2669                If an `Expression` instance is passed, it will be used as-is.
2670            append: if `True`, add to any existing expressions.
2671                Otherwise, this resets the expressions.
2672            dialect: the dialect used to parse the input expressions.
2673            copy: if `False`, modify this expression instance in-place.
2674            opts: other options to use to parse the input expressions.
2675
2676        Returns:
2677            Union: the modified expression.
2678        """
2679        this = self.copy() if copy else self
2680        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
2681        this.expression.unnest().select(
2682            *expressions, append=append, dialect=dialect, copy=False, **opts
2683        )
2684        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]
2686    @property
2687    def named_selects(self) -> t.List[str]:
2688        return self.this.unnest().named_selects
is_star: bool
2690    @property
2691    def is_star(self) -> bool:
2692        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

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

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

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

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

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:
2944    def cluster_by(
2945        self,
2946        *expressions: t.Optional[ExpOrStr],
2947        append: bool = True,
2948        dialect: DialectType = None,
2949        copy: bool = True,
2950        **opts,
2951    ) -> Select:
2952        """
2953        Set the CLUSTER BY expression.
2954
2955        Example:
2956            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
2957            'SELECT x FROM tbl CLUSTER BY x DESC'
2958
2959        Args:
2960            *expressions: the SQL code strings to parse.
2961                If a `Group` instance is passed, this is used as-is.
2962                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
2963            append: if `True`, add to any existing expressions.
2964                Otherwise, this flattens all the `Order` expression into a single expression.
2965            dialect: the dialect used to parse the input expression.
2966            copy: if `False`, modify this expression instance in-place.
2967            opts: other options to use to parse the input expressions.
2968
2969        Returns:
2970            The modified Select expression.
2971        """
2972        return _apply_child_list_builder(
2973            *expressions,
2974            instance=self,
2975            arg="cluster",
2976            append=append,
2977            copy=copy,
2978            prefix="CLUSTER BY",
2979            into=Cluster,
2980            dialect=dialect,
2981            **opts,
2982        )

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

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:
3018    def offset(
3019        self, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
3020    ) -> Select:
3021        """
3022        Set the OFFSET expression.
3023
3024        Example:
3025            >>> Select().from_("tbl").select("x").offset(10).sql()
3026            'SELECT x FROM tbl OFFSET 10'
3027
3028        Args:
3029            expression: the SQL code string to parse.
3030                This can also be an integer.
3031                If a `Offset` instance is passed, this is used as-is.
3032                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
3033            dialect: the dialect used to parse the input expression.
3034            copy: if `False`, modify this expression instance in-place.
3035            opts: other options to use to parse the input expressions.
3036
3037        Returns:
3038            The modified Select expression.
3039        """
3040        return _apply_builder(
3041            expression=expression,
3042            instance=self,
3043            arg="offset",
3044            into=Offset,
3045            prefix="OFFSET",
3046            dialect=dialect,
3047            copy=copy,
3048            into_arg="expression",
3049            **opts,
3050        )

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

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:
3089    def lateral(
3090        self,
3091        *expressions: t.Optional[ExpOrStr],
3092        append: bool = True,
3093        dialect: DialectType = None,
3094        copy: bool = True,
3095        **opts,
3096    ) -> Select:
3097        """
3098        Append to or set the LATERAL expressions.
3099
3100        Example:
3101            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3102            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3103
3104        Args:
3105            *expressions: the SQL code strings to parse.
3106                If an `Expression` instance is passed, it will be used as-is.
3107            append: if `True`, add to any existing expressions.
3108                Otherwise, this resets the expressions.
3109            dialect: the dialect used to parse the input expressions.
3110            copy: if `False`, modify this expression instance in-place.
3111            opts: other options to use to parse the input expressions.
3112
3113        Returns:
3114            The modified Select expression.
3115        """
3116        return _apply_list_builder(
3117            *expressions,
3118            instance=self,
3119            arg="laterals",
3120            append=append,
3121            into=Lateral,
3122            prefix="LATERAL VIEW",
3123            dialect=dialect,
3124            copy=copy,
3125            **opts,
3126        )

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

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

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:
3265    def having(
3266        self,
3267        *expressions: t.Optional[ExpOrStr],
3268        append: bool = True,
3269        dialect: DialectType = None,
3270        copy: bool = True,
3271        **opts,
3272    ) -> Select:
3273        """
3274        Append to or set the HAVING expressions.
3275
3276        Example:
3277            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3278            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3279
3280        Args:
3281            *expressions: the SQL code strings to parse.
3282                If an `Expression` instance is passed, it will be used as-is.
3283                Multiple expressions are combined with an AND operator.
3284            append: if `True`, AND the new expressions to any existing expression.
3285                Otherwise, this resets the expression.
3286            dialect: the dialect used to parse the input expressions.
3287            copy: if `False`, modify this expression instance in-place.
3288            opts: other options to use to parse the input expressions.
3289
3290        Returns:
3291            The modified Select expression.
3292        """
3293        return _apply_conjunction_builder(
3294            *expressions,
3295            instance=self,
3296            arg="having",
3297            append=append,
3298            into=Having,
3299            dialect=dialect,
3300            copy=copy,
3301            **opts,
3302        )

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:
3304    def window(
3305        self,
3306        *expressions: t.Optional[ExpOrStr],
3307        append: bool = True,
3308        dialect: DialectType = None,
3309        copy: bool = True,
3310        **opts,
3311    ) -> Select:
3312        return _apply_list_builder(
3313            *expressions,
3314            instance=self,
3315            arg="windows",
3316            append=append,
3317            into=Window,
3318            dialect=dialect,
3319            copy=copy,
3320            **opts,
3321        )
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:
3323    def qualify(
3324        self,
3325        *expressions: t.Optional[ExpOrStr],
3326        append: bool = True,
3327        dialect: DialectType = None,
3328        copy: bool = True,
3329        **opts,
3330    ) -> Select:
3331        return _apply_conjunction_builder(
3332            *expressions,
3333            instance=self,
3334            arg="qualify",
3335            append=append,
3336            into=Qualify,
3337            dialect=dialect,
3338            copy=copy,
3339            **opts,
3340        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3342    def distinct(
3343        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3344    ) -> Select:
3345        """
3346        Set the OFFSET expression.
3347
3348        Example:
3349            >>> Select().from_("tbl").select("x").distinct().sql()
3350            'SELECT DISTINCT x FROM tbl'
3351
3352        Args:
3353            ons: the expressions to distinct on
3354            distinct: whether the Select should be distinct
3355            copy: if `False`, modify this expression instance in-place.
3356
3357        Returns:
3358            Select: the modified expression.
3359        """
3360        instance = maybe_copy(self, copy)
3361        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3362        instance.set("distinct", Distinct(on=on) if distinct else None)
3363        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:
3365    def ctas(
3366        self,
3367        table: ExpOrStr,
3368        properties: t.Optional[t.Dict] = None,
3369        dialect: DialectType = None,
3370        copy: bool = True,
3371        **opts,
3372    ) -> Create:
3373        """
3374        Convert this expression to a CREATE TABLE AS statement.
3375
3376        Example:
3377            >>> Select().select("*").from_("tbl").ctas("x").sql()
3378            'CREATE TABLE x AS SELECT * FROM tbl'
3379
3380        Args:
3381            table: the SQL code string to parse as the table name.
3382                If another `Expression` instance is passed, it will be used as-is.
3383            properties: an optional mapping of table properties
3384            dialect: the dialect used to parse the input table.
3385            copy: if `False`, modify this expression instance in-place.
3386            opts: other options to use to parse the input table.
3387
3388        Returns:
3389            The new Create expression.
3390        """
3391        instance = maybe_copy(self, copy)
3392        table_expression = maybe_parse(
3393            table,
3394            into=Table,
3395            dialect=dialect,
3396            **opts,
3397        )
3398        properties_expression = None
3399        if properties:
3400            properties_expression = Properties.from_dict(properties)
3401
3402        return Create(
3403            this=table_expression,
3404            kind="TABLE",
3405            expression=instance,
3406            properties=properties_expression,
3407        )

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:
3409    def lock(self, update: bool = True, copy: bool = True) -> Select:
3410        """
3411        Set the locking read mode for this expression.
3412
3413        Examples:
3414            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3415            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3416
3417            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3418            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3419
3420        Args:
3421            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3422            copy: if `False`, modify this expression instance in-place.
3423
3424        Returns:
3425            The modified expression.
3426        """
3427        inst = maybe_copy(self, copy)
3428        inst.set("locks", [Lock(update=update)])
3429
3430        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:
3432    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3433        """
3434        Set hints for this expression.
3435
3436        Examples:
3437            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3438            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3439
3440        Args:
3441            hints: The SQL code strings to parse as the hints.
3442                If an `Expression` instance is passed, it will be used as-is.
3443            dialect: The dialect used to parse the hints.
3444            copy: If `False`, modify this expression instance in-place.
3445
3446        Returns:
3447            The modified expression.
3448        """
3449        inst = maybe_copy(self, copy)
3450        inst.set(
3451            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3452        )
3453
3454        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]
3456    @property
3457    def named_selects(self) -> t.List[str]:
3458        return [e.output_name for e in self.expressions if e.alias_or_name]
is_star: bool
3460    @property
3461    def is_star(self) -> bool:
3462        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3464    @property
3465    def selects(self) -> t.List[Expression]:
3466        return self.expressions
key = 'select'
class Subquery(DerivedTable, Unionable):
3469class Subquery(DerivedTable, Unionable):
3470    arg_types = {
3471        "this": True,
3472        "alias": False,
3473        "with": False,
3474        **QUERY_MODIFIERS,
3475    }
3476
3477    def unnest(self):
3478        """
3479        Returns the first non subquery.
3480        """
3481        expression = self
3482        while isinstance(expression, Subquery):
3483            expression = expression.this
3484        return expression
3485
3486    def unwrap(self) -> Subquery:
3487        expression = self
3488        while expression.same_parent and expression.is_wrapper:
3489            expression = t.cast(Subquery, expression.parent)
3490        return expression
3491
3492    @property
3493    def is_wrapper(self) -> bool:
3494        """
3495        Whether this Subquery acts as a simple wrapper around another expression.
3496
3497        SELECT * FROM (((SELECT * FROM t)))
3498                      ^
3499                      This corresponds to a "wrapper" Subquery node
3500        """
3501        return all(v is None for k, v in self.args.items() if k != "this")
3502
3503    @property
3504    def is_star(self) -> bool:
3505        return self.this.is_star
3506
3507    @property
3508    def output_name(self) -> str:
3509        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):
3477    def unnest(self):
3478        """
3479        Returns the first non subquery.
3480        """
3481        expression = self
3482        while isinstance(expression, Subquery):
3483            expression = expression.this
3484        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3486    def unwrap(self) -> Subquery:
3487        expression = self
3488        while expression.same_parent and expression.is_wrapper:
3489            expression = t.cast(Subquery, expression.parent)
3490        return expression
is_wrapper: bool
3492    @property
3493    def is_wrapper(self) -> bool:
3494        """
3495        Whether this Subquery acts as a simple wrapper around another expression.
3496
3497        SELECT * FROM (((SELECT * FROM t)))
3498                      ^
3499                      This corresponds to a "wrapper" Subquery node
3500        """
3501        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
3503    @property
3504    def is_star(self) -> bool:
3505        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3507    @property
3508    def output_name(self) -> str:
3509        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):
3512class TableSample(Expression):
3513    arg_types = {
3514        "this": False,
3515        "expressions": False,
3516        "method": False,
3517        "bucket_numerator": False,
3518        "bucket_denominator": False,
3519        "bucket_field": False,
3520        "percent": False,
3521        "rows": False,
3522        "size": False,
3523        "seed": False,
3524    }
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):
3527class Tag(Expression):
3528    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3529
3530    arg_types = {
3531        "this": False,
3532        "prefix": False,
3533        "postfix": False,
3534    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3539class Pivot(Expression):
3540    arg_types = {
3541        "this": False,
3542        "alias": False,
3543        "expressions": False,
3544        "field": False,
3545        "unpivot": False,
3546        "using": False,
3547        "group": False,
3548        "columns": False,
3549        "include_nulls": False,
3550    }
3551
3552    @property
3553    def unpivot(self) -> bool:
3554        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False}
unpivot: bool
3552    @property
3553    def unpivot(self) -> bool:
3554        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3557class Window(Condition):
3558    arg_types = {
3559        "this": True,
3560        "partition_by": False,
3561        "order": False,
3562        "spec": False,
3563        "alias": False,
3564        "over": False,
3565        "first": False,
3566    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3569class WindowSpec(Expression):
3570    arg_types = {
3571        "kind": False,
3572        "start": False,
3573        "start_side": False,
3574        "end": False,
3575        "end_side": False,
3576    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class Where(Expression):
3579class Where(Expression):
3580    pass
key = 'where'
class Star(Expression):
3583class Star(Expression):
3584    arg_types = {"except": False, "replace": False}
3585
3586    @property
3587    def name(self) -> str:
3588        return "*"
3589
3590    @property
3591    def output_name(self) -> str:
3592        return self.name
arg_types = {'except': False, 'replace': False}
name: str
3586    @property
3587    def name(self) -> str:
3588        return "*"
output_name: str
3590    @property
3591    def output_name(self) -> str:
3592        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):
3595class Parameter(Condition):
3596    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3599class SessionParameter(Condition):
3600    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3603class Placeholder(Condition):
3604    arg_types = {"this": False, "kind": False}
arg_types = {'this': False, 'kind': False}
key = 'placeholder'
class Null(Condition):
3607class Null(Condition):
3608    arg_types: t.Dict[str, t.Any] = {}
3609
3610    @property
3611    def name(self) -> str:
3612        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3610    @property
3611    def name(self) -> str:
3612        return "NULL"
key = 'null'
class Boolean(Condition):
3615class Boolean(Condition):
3616    pass
key = 'boolean'
class DataTypeParam(Expression):
3619class DataTypeParam(Expression):
3620    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datatypeparam'
class DataType(Expression):
3623class DataType(Expression):
3624    arg_types = {
3625        "this": True,
3626        "expressions": False,
3627        "nested": False,
3628        "values": False,
3629        "prefix": False,
3630        "kind": False,
3631    }
3632
3633    class Type(AutoName):
3634        ARRAY = auto()
3635        BIGDECIMAL = auto()
3636        BIGINT = auto()
3637        BIGSERIAL = auto()
3638        BINARY = auto()
3639        BIT = auto()
3640        BOOLEAN = auto()
3641        CHAR = auto()
3642        DATE = auto()
3643        DATE32 = auto()
3644        DATEMULTIRANGE = auto()
3645        DATERANGE = auto()
3646        DATETIME = auto()
3647        DATETIME64 = auto()
3648        DECIMAL = auto()
3649        DOUBLE = auto()
3650        ENUM = auto()
3651        ENUM8 = auto()
3652        ENUM16 = auto()
3653        FIXEDSTRING = auto()
3654        FLOAT = auto()
3655        GEOGRAPHY = auto()
3656        GEOMETRY = auto()
3657        HLLSKETCH = auto()
3658        HSTORE = auto()
3659        IMAGE = auto()
3660        INET = auto()
3661        INT = auto()
3662        INT128 = auto()
3663        INT256 = auto()
3664        INT4MULTIRANGE = auto()
3665        INT4RANGE = auto()
3666        INT8MULTIRANGE = auto()
3667        INT8RANGE = auto()
3668        INTERVAL = auto()
3669        IPADDRESS = auto()
3670        IPPREFIX = auto()
3671        IPV4 = auto()
3672        IPV6 = auto()
3673        JSON = auto()
3674        JSONB = auto()
3675        LONGBLOB = auto()
3676        LONGTEXT = auto()
3677        LOWCARDINALITY = auto()
3678        MAP = auto()
3679        MEDIUMBLOB = auto()
3680        MEDIUMINT = auto()
3681        MEDIUMTEXT = auto()
3682        MONEY = auto()
3683        NCHAR = auto()
3684        NESTED = auto()
3685        NULL = auto()
3686        NULLABLE = auto()
3687        NUMMULTIRANGE = auto()
3688        NUMRANGE = auto()
3689        NVARCHAR = auto()
3690        OBJECT = auto()
3691        ROWVERSION = auto()
3692        SERIAL = auto()
3693        SET = auto()
3694        SMALLINT = auto()
3695        SMALLMONEY = auto()
3696        SMALLSERIAL = auto()
3697        STRUCT = auto()
3698        SUPER = auto()
3699        TEXT = auto()
3700        TINYBLOB = auto()
3701        TINYTEXT = auto()
3702        TIME = auto()
3703        TIMETZ = auto()
3704        TIMESTAMP = auto()
3705        TIMESTAMPLTZ = auto()
3706        TIMESTAMPTZ = auto()
3707        TIMESTAMP_S = auto()
3708        TIMESTAMP_MS = auto()
3709        TIMESTAMP_NS = auto()
3710        TINYINT = auto()
3711        TSMULTIRANGE = auto()
3712        TSRANGE = auto()
3713        TSTZMULTIRANGE = auto()
3714        TSTZRANGE = auto()
3715        UBIGINT = auto()
3716        UINT = auto()
3717        UINT128 = auto()
3718        UINT256 = auto()
3719        UMEDIUMINT = auto()
3720        UDECIMAL = auto()
3721        UNIQUEIDENTIFIER = auto()
3722        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3723        USERDEFINED = "USER-DEFINED"
3724        USMALLINT = auto()
3725        UTINYINT = auto()
3726        UUID = auto()
3727        VARBINARY = auto()
3728        VARCHAR = auto()
3729        VARIANT = auto()
3730        XML = auto()
3731        YEAR = auto()
3732
3733    TEXT_TYPES = {
3734        Type.CHAR,
3735        Type.NCHAR,
3736        Type.VARCHAR,
3737        Type.NVARCHAR,
3738        Type.TEXT,
3739    }
3740
3741    INTEGER_TYPES = {
3742        Type.INT,
3743        Type.TINYINT,
3744        Type.SMALLINT,
3745        Type.BIGINT,
3746        Type.INT128,
3747        Type.INT256,
3748        Type.BIT,
3749    }
3750
3751    FLOAT_TYPES = {
3752        Type.FLOAT,
3753        Type.DOUBLE,
3754    }
3755
3756    NUMERIC_TYPES = {
3757        *INTEGER_TYPES,
3758        *FLOAT_TYPES,
3759    }
3760
3761    TEMPORAL_TYPES = {
3762        Type.TIME,
3763        Type.TIMETZ,
3764        Type.TIMESTAMP,
3765        Type.TIMESTAMPTZ,
3766        Type.TIMESTAMPLTZ,
3767        Type.TIMESTAMP_S,
3768        Type.TIMESTAMP_MS,
3769        Type.TIMESTAMP_NS,
3770        Type.DATE,
3771        Type.DATE32,
3772        Type.DATETIME,
3773        Type.DATETIME64,
3774    }
3775
3776    @classmethod
3777    def build(
3778        cls,
3779        dtype: DATA_TYPE,
3780        dialect: DialectType = None,
3781        udt: bool = False,
3782        **kwargs,
3783    ) -> DataType:
3784        """
3785        Constructs a DataType object.
3786
3787        Args:
3788            dtype: the data type of interest.
3789            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3790            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3791                DataType, thus creating a user-defined type.
3792            kawrgs: additional arguments to pass in the constructor of DataType.
3793
3794        Returns:
3795            The constructed DataType object.
3796        """
3797        from sqlglot import parse_one
3798
3799        if isinstance(dtype, str):
3800            if dtype.upper() == "UNKNOWN":
3801                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3802
3803            try:
3804                data_type_exp = parse_one(
3805                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3806                )
3807            except ParseError:
3808                if udt:
3809                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3810                raise
3811        elif isinstance(dtype, DataType.Type):
3812            data_type_exp = DataType(this=dtype)
3813        elif isinstance(dtype, DataType):
3814            return dtype
3815        else:
3816            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3817
3818        return DataType(**{**data_type_exp.args, **kwargs})
3819
3820    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3821        """
3822        Checks whether this DataType matches one of the provided data types. Nested types or precision
3823        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3824
3825        Args:
3826            dtypes: the data types to compare this DataType to.
3827
3828        Returns:
3829            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3830        """
3831        for dtype in dtypes:
3832            other = DataType.build(dtype, udt=True)
3833
3834            if (
3835                other.expressions
3836                or self.this == DataType.Type.USERDEFINED
3837                or other.this == DataType.Type.USERDEFINED
3838            ):
3839                matches = self == other
3840            else:
3841                matches = self.this == other.this
3842
3843            if matches:
3844                return True
3845        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NCHAR: 'NCHAR'>}
INTEGER_TYPES = {<Type.INT128: 'INT128'>, <Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.BIT: 'BIT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.INT128: 'INT128'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT256: 'INT256'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGINT: 'BIGINT'>, <Type.BIT: 'BIT'>, <Type.FLOAT: 'FLOAT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>}
TEMPORAL_TYPES = {<Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATE: 'DATE'>, <Type.DATE32: 'DATE32'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}
@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:
3776    @classmethod
3777    def build(
3778        cls,
3779        dtype: DATA_TYPE,
3780        dialect: DialectType = None,
3781        udt: bool = False,
3782        **kwargs,
3783    ) -> DataType:
3784        """
3785        Constructs a DataType object.
3786
3787        Args:
3788            dtype: the data type of interest.
3789            dialect: the dialect to use for parsing `dtype`, in case it's a string.
3790            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
3791                DataType, thus creating a user-defined type.
3792            kawrgs: additional arguments to pass in the constructor of DataType.
3793
3794        Returns:
3795            The constructed DataType object.
3796        """
3797        from sqlglot import parse_one
3798
3799        if isinstance(dtype, str):
3800            if dtype.upper() == "UNKNOWN":
3801                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
3802
3803            try:
3804                data_type_exp = parse_one(
3805                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
3806                )
3807            except ParseError:
3808                if udt:
3809                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
3810                raise
3811        elif isinstance(dtype, DataType.Type):
3812            data_type_exp = DataType(this=dtype)
3813        elif isinstance(dtype, DataType):
3814            return dtype
3815        else:
3816            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
3817
3818        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:
3820    def is_type(self, *dtypes: DATA_TYPE) -> bool:
3821        """
3822        Checks whether this DataType matches one of the provided data types. Nested types or precision
3823        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
3824
3825        Args:
3826            dtypes: the data types to compare this DataType to.
3827
3828        Returns:
3829            True, if and only if there is a type in `dtypes` which is equal to this DataType.
3830        """
3831        for dtype in dtypes:
3832            other = DataType.build(dtype, udt=True)
3833
3834            if (
3835                other.expressions
3836                or self.this == DataType.Type.USERDEFINED
3837                or other.this == DataType.Type.USERDEFINED
3838            ):
3839                matches = self == other
3840            else:
3841                matches = self.this == other.this
3842
3843            if matches:
3844                return True
3845        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):
3633    class Type(AutoName):
3634        ARRAY = auto()
3635        BIGDECIMAL = auto()
3636        BIGINT = auto()
3637        BIGSERIAL = auto()
3638        BINARY = auto()
3639        BIT = auto()
3640        BOOLEAN = auto()
3641        CHAR = auto()
3642        DATE = auto()
3643        DATE32 = auto()
3644        DATEMULTIRANGE = auto()
3645        DATERANGE = auto()
3646        DATETIME = auto()
3647        DATETIME64 = auto()
3648        DECIMAL = auto()
3649        DOUBLE = auto()
3650        ENUM = auto()
3651        ENUM8 = auto()
3652        ENUM16 = auto()
3653        FIXEDSTRING = auto()
3654        FLOAT = auto()
3655        GEOGRAPHY = auto()
3656        GEOMETRY = auto()
3657        HLLSKETCH = auto()
3658        HSTORE = auto()
3659        IMAGE = auto()
3660        INET = auto()
3661        INT = auto()
3662        INT128 = auto()
3663        INT256 = auto()
3664        INT4MULTIRANGE = auto()
3665        INT4RANGE = auto()
3666        INT8MULTIRANGE = auto()
3667        INT8RANGE = auto()
3668        INTERVAL = auto()
3669        IPADDRESS = auto()
3670        IPPREFIX = auto()
3671        IPV4 = auto()
3672        IPV6 = auto()
3673        JSON = auto()
3674        JSONB = auto()
3675        LONGBLOB = auto()
3676        LONGTEXT = auto()
3677        LOWCARDINALITY = auto()
3678        MAP = auto()
3679        MEDIUMBLOB = auto()
3680        MEDIUMINT = auto()
3681        MEDIUMTEXT = auto()
3682        MONEY = auto()
3683        NCHAR = auto()
3684        NESTED = auto()
3685        NULL = auto()
3686        NULLABLE = auto()
3687        NUMMULTIRANGE = auto()
3688        NUMRANGE = auto()
3689        NVARCHAR = auto()
3690        OBJECT = auto()
3691        ROWVERSION = auto()
3692        SERIAL = auto()
3693        SET = auto()
3694        SMALLINT = auto()
3695        SMALLMONEY = auto()
3696        SMALLSERIAL = auto()
3697        STRUCT = auto()
3698        SUPER = auto()
3699        TEXT = auto()
3700        TINYBLOB = auto()
3701        TINYTEXT = auto()
3702        TIME = auto()
3703        TIMETZ = auto()
3704        TIMESTAMP = auto()
3705        TIMESTAMPLTZ = auto()
3706        TIMESTAMPTZ = auto()
3707        TIMESTAMP_S = auto()
3708        TIMESTAMP_MS = auto()
3709        TIMESTAMP_NS = auto()
3710        TINYINT = auto()
3711        TSMULTIRANGE = auto()
3712        TSRANGE = auto()
3713        TSTZMULTIRANGE = auto()
3714        TSTZRANGE = auto()
3715        UBIGINT = auto()
3716        UINT = auto()
3717        UINT128 = auto()
3718        UINT256 = auto()
3719        UMEDIUMINT = auto()
3720        UDECIMAL = auto()
3721        UNIQUEIDENTIFIER = auto()
3722        UNKNOWN = auto()  # Sentinel value, useful for type annotation
3723        USERDEFINED = "USER-DEFINED"
3724        USMALLINT = auto()
3725        UTINYINT = auto()
3726        UUID = auto()
3727        VARBINARY = auto()
3728        VARCHAR = auto()
3729        VARIANT = auto()
3730        XML = auto()
3731        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'>
DATE32 = <Type.DATE32: 'DATE32'>
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'>
IPV4 = <Type.IPV4: 'IPV4'>
IPV6 = <Type.IPV6: 'IPV6'>
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):
3852class PseudoType(DataType):
3853    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
3857class ObjectIdentifier(DataType):
3858    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
3862class SubqueryPredicate(Predicate):
3863    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
3866class All(SubqueryPredicate):
3867    pass
key = 'all'
class Any(SubqueryPredicate):
3870class Any(SubqueryPredicate):
3871    pass
key = 'any'
class Exists(SubqueryPredicate):
3874class Exists(SubqueryPredicate):
3875    pass
key = 'exists'
class Command(Expression):
3880class Command(Expression):
3881    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
3884class Transaction(Expression):
3885    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
3888class Commit(Expression):
3889    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
3892class Rollback(Expression):
3893    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
3896class AlterTable(Expression):
3897    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):
3900class AddConstraint(Expression):
3901    arg_types = {"this": False, "expression": False, "enforced": False}
arg_types = {'this': False, 'expression': False, 'enforced': False}
key = 'addconstraint'
class DropPartition(Expression):
3904class DropPartition(Expression):
3905    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class Binary(Condition):
3909class Binary(Condition):
3910    arg_types = {"this": True, "expression": True}
3911
3912    @property
3913    def left(self) -> Expression:
3914        return self.this
3915
3916    @property
3917    def right(self) -> Expression:
3918        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
3912    @property
3913    def left(self) -> Expression:
3914        return self.this
right: Expression
3916    @property
3917    def right(self) -> Expression:
3918        return self.expression
key = 'binary'
class Add(Binary):
3921class Add(Binary):
3922    pass
key = 'add'
class Connector(Binary):
3925class Connector(Binary):
3926    pass
key = 'connector'
class And(Connector):
3929class And(Connector):
3930    pass
key = 'and'
class Or(Connector):
3933class Or(Connector):
3934    pass
key = 'or'
class BitwiseAnd(Binary):
3937class BitwiseAnd(Binary):
3938    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
3941class BitwiseLeftShift(Binary):
3942    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
3945class BitwiseOr(Binary):
3946    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
3949class BitwiseRightShift(Binary):
3950    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
3953class BitwiseXor(Binary):
3954    pass
key = 'bitwisexor'
class Div(Binary):
3957class Div(Binary):
3958    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):
3961class Overlaps(Binary):
3962    pass
key = 'overlaps'
class Dot(Binary):
3965class Dot(Binary):
3966    @property
3967    def name(self) -> str:
3968        return self.expression.name
3969
3970    @property
3971    def output_name(self) -> str:
3972        return self.name
3973
3974    @classmethod
3975    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3976        """Build a Dot object with a sequence of expressions."""
3977        if len(expressions) < 2:
3978            raise ValueError(f"Dot requires >= 2 expressions.")
3979
3980        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
3981
3982    @property
3983    def parts(self) -> t.List[Expression]:
3984        """Return the parts of a table / column in order catalog, db, table."""
3985        this, *parts = self.flatten()
3986
3987        parts.reverse()
3988
3989        for arg in ("this", "table", "db", "catalog"):
3990            part = this.args.get(arg)
3991
3992            if isinstance(part, Expression):
3993                parts.append(part)
3994
3995        parts.reverse()
3996        return parts
name: str
3966    @property
3967    def name(self) -> str:
3968        return self.expression.name
output_name: str
3970    @property
3971    def output_name(self) -> str:
3972        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:
3974    @classmethod
3975    def build(self, expressions: t.Sequence[Expression]) -> Dot:
3976        """Build a Dot object with a sequence of expressions."""
3977        if len(expressions) < 2:
3978            raise ValueError(f"Dot requires >= 2 expressions.")
3979
3980        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]
3982    @property
3983    def parts(self) -> t.List[Expression]:
3984        """Return the parts of a table / column in order catalog, db, table."""
3985        this, *parts = self.flatten()
3986
3987        parts.reverse()
3988
3989        for arg in ("this", "table", "db", "catalog"):
3990            part = this.args.get(arg)
3991
3992            if isinstance(part, Expression):
3993                parts.append(part)
3994
3995        parts.reverse()
3996        return parts

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

key = 'dot'
class DPipe(Binary):
3999class DPipe(Binary):
4000    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4003class EQ(Binary, Predicate):
4004    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4007class NullSafeEQ(Binary, Predicate):
4008    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4011class NullSafeNEQ(Binary, Predicate):
4012    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4016class PropertyEQ(Binary):
4017    pass
key = 'propertyeq'
class Distance(Binary):
4020class Distance(Binary):
4021    pass
key = 'distance'
class Escape(Binary):
4024class Escape(Binary):
4025    pass
key = 'escape'
class Glob(Binary, Predicate):
4028class Glob(Binary, Predicate):
4029    pass
key = 'glob'
class GT(Binary, Predicate):
4032class GT(Binary, Predicate):
4033    pass
key = 'gt'
class GTE(Binary, Predicate):
4036class GTE(Binary, Predicate):
4037    pass
key = 'gte'
class ILike(Binary, Predicate):
4040class ILike(Binary, Predicate):
4041    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4044class ILikeAny(Binary, Predicate):
4045    pass
key = 'ilikeany'
class IntDiv(Binary):
4048class IntDiv(Binary):
4049    pass
key = 'intdiv'
class Is(Binary, Predicate):
4052class Is(Binary, Predicate):
4053    pass
key = 'is'
class Kwarg(Binary):
4056class Kwarg(Binary):
4057    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4060class Like(Binary, Predicate):
4061    pass
key = 'like'
class LikeAny(Binary, Predicate):
4064class LikeAny(Binary, Predicate):
4065    pass
key = 'likeany'
class LT(Binary, Predicate):
4068class LT(Binary, Predicate):
4069    pass
key = 'lt'
class LTE(Binary, Predicate):
4072class LTE(Binary, Predicate):
4073    pass
key = 'lte'
class Mod(Binary):
4076class Mod(Binary):
4077    pass
key = 'mod'
class Mul(Binary):
4080class Mul(Binary):
4081    pass
key = 'mul'
class NEQ(Binary, Predicate):
4084class NEQ(Binary, Predicate):
4085    pass
key = 'neq'
class Operator(Binary):
4089class Operator(Binary):
4090    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4093class SimilarTo(Binary, Predicate):
4094    pass
key = 'similarto'
class Slice(Binary):
4097class Slice(Binary):
4098    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4101class Sub(Binary):
4102    pass
key = 'sub'
class ArrayOverlaps(Binary):
4105class ArrayOverlaps(Binary):
4106    pass
key = 'arrayoverlaps'
class Unary(Condition):
4111class Unary(Condition):
4112    pass
key = 'unary'
class BitwiseNot(Unary):
4115class BitwiseNot(Unary):
4116    pass
key = 'bitwisenot'
class Not(Unary):
4119class Not(Unary):
4120    pass
key = 'not'
class Paren(Unary):
4123class Paren(Unary):
4124    arg_types = {"this": True, "with": False}
4125
4126    @property
4127    def output_name(self) -> str:
4128        return self.this.name
arg_types = {'this': True, 'with': False}
output_name: str
4126    @property
4127    def output_name(self) -> str:
4128        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):
4131class Neg(Unary):
4132    pass
key = 'neg'
class Alias(Expression):
4135class Alias(Expression):
4136    arg_types = {"this": True, "alias": False}
4137
4138    @property
4139    def output_name(self) -> str:
4140        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4138    @property
4139    def output_name(self) -> str:
4140        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 PivotAlias(Alias):
4145class PivotAlias(Alias):
4146    pass
key = 'pivotalias'
class Aliases(Expression):
4149class Aliases(Expression):
4150    arg_types = {"this": True, "expressions": True}
4151
4152    @property
4153    def aliases(self):
4154        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4152    @property
4153    def aliases(self):
4154        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4158class AtIndex(Expression):
4159    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4162class AtTimeZone(Expression):
4163    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class Between(Predicate):
4166class Between(Predicate):
4167    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4170class Bracket(Condition):
4171    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4172    arg_types = {"this": True, "expressions": True, "offset": False, "safe": False}
4173
4174    @property
4175    def output_name(self) -> str:
4176        if len(self.expressions) == 1:
4177            return self.expressions[0].output_name
4178
4179        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False}
output_name: str
4174    @property
4175    def output_name(self) -> str:
4176        if len(self.expressions) == 1:
4177            return self.expressions[0].output_name
4178
4179        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):
4182class Distinct(Expression):
4183    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4186class In(Predicate):
4187    arg_types = {
4188        "this": True,
4189        "expressions": False,
4190        "query": False,
4191        "unnest": False,
4192        "field": False,
4193        "is_global": False,
4194    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4198class ForIn(Expression):
4199    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4202class TimeUnit(Expression):
4203    """Automatically converts unit arg into a var."""
4204
4205    arg_types = {"unit": False}
4206
4207    UNABBREVIATED_UNIT_NAME = {
4208        "D": "DAY",
4209        "H": "HOUR",
4210        "M": "MINUTE",
4211        "MS": "MILLISECOND",
4212        "NS": "NANOSECOND",
4213        "Q": "QUARTER",
4214        "S": "SECOND",
4215        "US": "MICROSECOND",
4216        "W": "WEEK",
4217        "Y": "YEAR",
4218    }
4219
4220    VAR_LIKE = (Column, Literal, Var)
4221
4222    def __init__(self, **args):
4223        unit = args.get("unit")
4224        if isinstance(unit, self.VAR_LIKE):
4225            args["unit"] = Var(
4226                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4227            )
4228        elif isinstance(unit, Week):
4229            unit.set("this", Var(this=unit.this.name.upper()))
4230
4231        super().__init__(**args)
4232
4233    @property
4234    def unit(self) -> t.Optional[Var]:
4235        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4222    def __init__(self, **args):
4223        unit = args.get("unit")
4224        if isinstance(unit, self.VAR_LIKE):
4225            args["unit"] = Var(
4226                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4227            )
4228        elif isinstance(unit, Week):
4229            unit.set("this", Var(this=unit.this.name.upper()))
4230
4231        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]
4233    @property
4234    def unit(self) -> t.Optional[Var]:
4235        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4238class IntervalOp(TimeUnit):
4239    arg_types = {"unit": True, "expression": True}
4240
4241    def interval(self):
4242        return Interval(
4243            this=self.expression.copy(),
4244            unit=self.unit.copy(),
4245        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4241    def interval(self):
4242        return Interval(
4243            this=self.expression.copy(),
4244            unit=self.unit.copy(),
4245        )
key = 'intervalop'
class IntervalSpan(DataType):
4251class IntervalSpan(DataType):
4252    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4255class Interval(TimeUnit):
4256    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4259class IgnoreNulls(Expression):
4260    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4263class RespectNulls(Expression):
4264    pass
key = 'respectnulls'
class Func(Condition):
4268class Func(Condition):
4269    """
4270    The base class for all function expressions.
4271
4272    Attributes:
4273        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4274            treated as a variable length argument and the argument's value will be stored as a list.
4275        _sql_names (list): determines the SQL name (1st item in the list) and aliases (subsequent items)
4276            for this function expression. These values are used to map this node to a name during parsing
4277            as well as to provide the function's name during SQL string generation. By default the SQL
4278            name is set to the expression's class name transformed to snake case.
4279    """
4280
4281    is_var_len_args = False
4282
4283    @classmethod
4284    def from_arg_list(cls, args):
4285        if cls.is_var_len_args:
4286            all_arg_keys = list(cls.arg_types)
4287            # If this function supports variable length argument treat the last argument as such.
4288            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4289            num_non_var = len(non_var_len_arg_keys)
4290
4291            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4292            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4293        else:
4294            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4295
4296        return cls(**args_dict)
4297
4298    @classmethod
4299    def sql_names(cls):
4300        if cls is Func:
4301            raise NotImplementedError(
4302                "SQL name is only supported by concrete function implementations"
4303            )
4304        if "_sql_names" not in cls.__dict__:
4305            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4306        return cls._sql_names
4307
4308    @classmethod
4309    def sql_name(cls):
4310        return cls.sql_names()[0]
4311
4312    @classmethod
4313    def default_parser_mappings(cls):
4314        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):
4283    @classmethod
4284    def from_arg_list(cls, args):
4285        if cls.is_var_len_args:
4286            all_arg_keys = list(cls.arg_types)
4287            # If this function supports variable length argument treat the last argument as such.
4288            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4289            num_non_var = len(non_var_len_arg_keys)
4290
4291            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4292            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4293        else:
4294            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4295
4296        return cls(**args_dict)
@classmethod
def sql_names(cls):
4298    @classmethod
4299    def sql_names(cls):
4300        if cls is Func:
4301            raise NotImplementedError(
4302                "SQL name is only supported by concrete function implementations"
4303            )
4304        if "_sql_names" not in cls.__dict__:
4305            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4306        return cls._sql_names
@classmethod
def sql_name(cls):
4308    @classmethod
4309    def sql_name(cls):
4310        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4312    @classmethod
4313    def default_parser_mappings(cls):
4314        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4317class AggFunc(Func):
4318    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4321class ParameterizedAgg(AggFunc):
4322    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4325class Abs(Func):
4326    pass
key = 'abs'
class ArgMax(AggFunc):
4329class ArgMax(AggFunc):
4330    arg_types = {"this": True, "expression": True, "count": False}
4331    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4334class ArgMin(AggFunc):
4335    arg_types = {"this": True, "expression": True, "count": False}
4336    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4339class ApproxTopK(AggFunc):
4340    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4343class Flatten(Func):
4344    pass
key = 'flatten'
class Transform(Func):
4348class Transform(Func):
4349    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4352class Anonymous(Func):
4353    arg_types = {"this": True, "expressions": False}
4354    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4357class AnonymousAggFunc(AggFunc):
4358    arg_types = {"this": True, "expressions": False}
4359    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4363class CombinedAggFunc(AnonymousAggFunc):
4364    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4367class CombinedParameterizedAgg(ParameterizedAgg):
4368    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):
4373class Hll(AggFunc):
4374    arg_types = {"this": True, "expressions": False}
4375    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4378class ApproxDistinct(AggFunc):
4379    arg_types = {"this": True, "accuracy": False}
4380    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4383class Array(Func):
4384    arg_types = {"expressions": False}
4385    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4389class ToArray(Func):
4390    pass
key = 'toarray'
class ToChar(Func):
4395class ToChar(Func):
4396    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class GenerateSeries(Func):
4399class GenerateSeries(Func):
4400    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4403class ArrayAgg(AggFunc):
4404    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4407class ArrayUniqueAgg(AggFunc):
4408    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4411class ArrayAll(Func):
4412    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4415class ArrayAny(Func):
4416    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4419class ArrayConcat(Func):
4420    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4421    arg_types = {"this": True, "expressions": False}
4422    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayContains(Binary, Func):
4425class ArrayContains(Binary, Func):
4426    pass
key = 'arraycontains'
class ArrayContained(Binary):
4429class ArrayContained(Binary):
4430    pass
key = 'arraycontained'
class ArrayFilter(Func):
4433class ArrayFilter(Func):
4434    arg_types = {"this": True, "expression": True}
4435    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayJoin(Func):
4438class ArrayJoin(Func):
4439    arg_types = {"this": True, "expression": True, "null": False}
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arrayjoin'
class ArraySize(Func):
4442class ArraySize(Func):
4443    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4446class ArraySort(Func):
4447    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4450class ArraySum(Func):
4451    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4454class ArrayUnionAgg(AggFunc):
4455    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4458class Avg(AggFunc):
4459    pass
key = 'avg'
class AnyValue(AggFunc):
4462class AnyValue(AggFunc):
4463    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):
4466class First(Func):
4467    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'first'
class Last(Func):
4470class Last(Func):
4471    arg_types = {"this": True, "ignore_nulls": False}
arg_types = {'this': True, 'ignore_nulls': False}
key = 'last'
class Case(Func):
4474class Case(Func):
4475    arg_types = {"this": False, "ifs": True, "default": False}
4476
4477    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4478        instance = maybe_copy(self, copy)
4479        instance.append(
4480            "ifs",
4481            If(
4482                this=maybe_parse(condition, copy=copy, **opts),
4483                true=maybe_parse(then, copy=copy, **opts),
4484            ),
4485        )
4486        return instance
4487
4488    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4489        instance = maybe_copy(self, copy)
4490        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4491        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:
4477    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4478        instance = maybe_copy(self, copy)
4479        instance.append(
4480            "ifs",
4481            If(
4482                this=maybe_parse(condition, copy=copy, **opts),
4483                true=maybe_parse(then, copy=copy, **opts),
4484            ),
4485        )
4486        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4488    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4489        instance = maybe_copy(self, copy)
4490        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4491        return instance
key = 'case'
class Cast(Func):
4494class Cast(Func):
4495    arg_types = {"this": True, "to": True, "format": False, "safe": False}
4496
4497    @property
4498    def name(self) -> str:
4499        return self.this.name
4500
4501    @property
4502    def to(self) -> DataType:
4503        return self.args["to"]
4504
4505    @property
4506    def output_name(self) -> str:
4507        return self.name
4508
4509    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4510        """
4511        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4512        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4513        array<int> != array<float>.
4514
4515        Args:
4516            dtypes: the data types to compare this Cast's DataType to.
4517
4518        Returns:
4519            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4520        """
4521        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False}
name: str
4497    @property
4498    def name(self) -> str:
4499        return self.this.name
to: DataType
4501    @property
4502    def to(self) -> DataType:
4503        return self.args["to"]
output_name: str
4505    @property
4506    def output_name(self) -> str:
4507        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:
4509    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4510        """
4511        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4512        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4513        array<int> != array<float>.
4514
4515        Args:
4516            dtypes: the data types to compare this Cast's DataType to.
4517
4518        Returns:
4519            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4520        """
4521        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):
4524class TryCast(Cast):
4525    pass
key = 'trycast'
class CastToStrType(Func):
4528class CastToStrType(Func):
4529    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4532class Collate(Binary, Func):
4533    pass
key = 'collate'
class Ceil(Func):
4536class Ceil(Func):
4537    arg_types = {"this": True, "decimals": False}
4538    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4541class Coalesce(Func):
4542    arg_types = {"this": True, "expressions": False}
4543    is_var_len_args = True
4544    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4547class Chr(Func):
4548    arg_types = {"this": True, "charset": False, "expressions": False}
4549    is_var_len_args = True
4550    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4553class Concat(Func):
4554    arg_types = {"expressions": True, "safe": False, "coalesce": False}
4555    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
4558class ConcatWs(Concat):
4559    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Count(AggFunc):
4562class Count(AggFunc):
4563    arg_types = {"this": False, "expressions": False}
4564    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
4567class CountIf(AggFunc):
4568    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class CurrentDate(Func):
4571class CurrentDate(Func):
4572    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
4575class CurrentDatetime(Func):
4576    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
4579class CurrentTime(Func):
4580    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
4583class CurrentTimestamp(Func):
4584    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttimestamp'
class CurrentUser(Func):
4587class CurrentUser(Func):
4588    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
4591class DateAdd(Func, IntervalOp):
4592    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
4595class DateSub(Func, IntervalOp):
4596    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
4599class DateDiff(Func, TimeUnit):
4600    _sql_names = ["DATEDIFF", "DATE_DIFF"]
4601    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
4604class DateTrunc(Func):
4605    arg_types = {"unit": True, "this": True, "zone": False}
4606
4607    def __init__(self, **args):
4608        unit = args.get("unit")
4609        if isinstance(unit, TimeUnit.VAR_LIKE):
4610            args["unit"] = Literal.string(
4611                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4612            )
4613        elif isinstance(unit, Week):
4614            unit.set("this", Literal.string(unit.this.name.upper()))
4615
4616        super().__init__(**args)
4617
4618    @property
4619    def unit(self) -> Expression:
4620        return self.args["unit"]
DateTrunc(**args)
4607    def __init__(self, **args):
4608        unit = args.get("unit")
4609        if isinstance(unit, TimeUnit.VAR_LIKE):
4610            args["unit"] = Literal.string(
4611                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4612            )
4613        elif isinstance(unit, Week):
4614            unit.set("this", Literal.string(unit.this.name.upper()))
4615
4616        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
4618    @property
4619    def unit(self) -> Expression:
4620        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
4623class DatetimeAdd(Func, IntervalOp):
4624    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
4627class DatetimeSub(Func, IntervalOp):
4628    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
4631class DatetimeDiff(Func, TimeUnit):
4632    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
4635class DatetimeTrunc(Func, TimeUnit):
4636    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
4639class DayOfWeek(Func):
4640    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
4643class DayOfMonth(Func):
4644    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
4647class DayOfYear(Func):
4648    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
4651class ToDays(Func):
4652    pass
key = 'todays'
class WeekOfYear(Func):
4655class WeekOfYear(Func):
4656    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
4659class MonthsBetween(Func):
4660    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
4663class LastDay(Func, TimeUnit):
4664    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
4665    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
4668class Extract(Func):
4669    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
4672class Timestamp(Func):
4673    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
4676class TimestampAdd(Func, TimeUnit):
4677    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
4680class TimestampSub(Func, TimeUnit):
4681    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
4684class TimestampDiff(Func, TimeUnit):
4685    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
4688class TimestampTrunc(Func, TimeUnit):
4689    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
4692class TimeAdd(Func, TimeUnit):
4693    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
4696class TimeSub(Func, TimeUnit):
4697    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
4700class TimeDiff(Func, TimeUnit):
4701    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
4704class TimeTrunc(Func, TimeUnit):
4705    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
4708class DateFromParts(Func):
4709    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
4710    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
4713class TimeFromParts(Func):
4714    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
4715    arg_types = {
4716        "hour": True,
4717        "min": True,
4718        "sec": True,
4719        "nano": False,
4720        "fractions": False,
4721        "precision": False,
4722    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
4725class DateStrToDate(Func):
4726    pass
key = 'datestrtodate'
class DateToDateStr(Func):
4729class DateToDateStr(Func):
4730    pass
key = 'datetodatestr'
class DateToDi(Func):
4733class DateToDi(Func):
4734    pass
key = 'datetodi'
class Date(Func):
4738class Date(Func):
4739    arg_types = {"this": False, "zone": False, "expressions": False}
4740    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
4743class Day(Func):
4744    pass
key = 'day'
class Decode(Func):
4747class Decode(Func):
4748    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
4751class DiToDate(Func):
4752    pass
key = 'ditodate'
class Encode(Func):
4755class Encode(Func):
4756    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
4759class Exp(Func):
4760    pass
key = 'exp'
class Explode(Func):
4764class Explode(Func):
4765    arg_types = {"this": True, "expressions": False}
4766    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
4769class ExplodeOuter(Explode):
4770    pass
key = 'explodeouter'
class Posexplode(Explode):
4773class Posexplode(Explode):
4774    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode):
4777class PosexplodeOuter(Posexplode):
4778    pass
key = 'posexplodeouter'
class Floor(Func):
4781class Floor(Func):
4782    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
4785class FromBase64(Func):
4786    pass
key = 'frombase64'
class ToBase64(Func):
4789class ToBase64(Func):
4790    pass
key = 'tobase64'
class Greatest(Func):
4793class Greatest(Func):
4794    arg_types = {"this": True, "expressions": False}
4795    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
4798class GroupConcat(AggFunc):
4799    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
4802class Hex(Func):
4803    pass
key = 'hex'
class Xor(Connector, Func):
4806class Xor(Connector, Func):
4807    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
4810class If(Func):
4811    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
4814class Nullif(Func):
4815    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
4818class Initcap(Func):
4819    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
4822class IsNan(Func):
4823    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
4826class IsInf(Func):
4827    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class FormatJson(Expression):
4830class FormatJson(Expression):
4831    pass
key = 'formatjson'
class JSONKeyValue(Expression):
4834class JSONKeyValue(Expression):
4835    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
4838class JSONObject(Func):
4839    arg_types = {
4840        "expressions": False,
4841        "null_handling": False,
4842        "unique_keys": False,
4843        "return_type": False,
4844        "encoding": False,
4845    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
4848class JSONObjectAgg(AggFunc):
4849    arg_types = {
4850        "expressions": False,
4851        "null_handling": False,
4852        "unique_keys": False,
4853        "return_type": False,
4854        "encoding": False,
4855    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
4859class JSONArray(Func):
4860    arg_types = {
4861        "expressions": True,
4862        "null_handling": False,
4863        "return_type": False,
4864        "strict": False,
4865    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
4869class JSONArrayAgg(Func):
4870    arg_types = {
4871        "this": True,
4872        "order": False,
4873        "null_handling": False,
4874        "return_type": False,
4875        "strict": False,
4876    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
4881class JSONColumnDef(Expression):
4882    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):
4885class JSONSchema(Expression):
4886    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
4890class JSONTable(Func):
4891    arg_types = {
4892        "this": True,
4893        "schema": True,
4894        "path": False,
4895        "error_handling": False,
4896        "empty_handling": False,
4897    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
4900class OpenJSONColumnDef(Expression):
4901    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):
4904class OpenJSON(Func):
4905    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
4908class JSONBContains(Binary):
4909    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
4912class JSONExtract(Binary, Func):
4913    _sql_names = ["JSON_EXTRACT"]
key = 'jsonextract'
class JSONExtractScalar(JSONExtract):
4916class JSONExtractScalar(JSONExtract):
4917    _sql_names = ["JSON_EXTRACT_SCALAR"]
key = 'jsonextractscalar'
class JSONBExtract(JSONExtract):
4920class JSONBExtract(JSONExtract):
4921    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(JSONExtract):
4924class JSONBExtractScalar(JSONExtract):
4925    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
4928class JSONFormat(Func):
4929    arg_types = {"this": False, "options": False}
4930    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
4934class JSONArrayContains(Binary, Predicate, Func):
4935    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
4938class ParseJSON(Func):
4939    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
4940    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
4941    arg_types = {"this": True, "expressions": False}
4942    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class GetPath(Func):
4946class GetPath(Func):
4947    arg_types = {"this": True, "expression": True}
4948
4949    @property
4950    def output_name(self) -> str:
4951        return self.expression.output_name
arg_types = {'this': True, 'expression': True}
output_name: str
4949    @property
4950    def output_name(self) -> str:
4951        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):
4954class Least(Func):
4955    arg_types = {"this": True, "expressions": False}
4956    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
4959class Left(Func):
4960    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
4967class Length(Func):
4968    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
4971class Levenshtein(Func):
4972    arg_types = {
4973        "this": True,
4974        "expression": False,
4975        "ins_cost": False,
4976        "del_cost": False,
4977        "sub_cost": False,
4978    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
4981class Ln(Func):
4982    pass
key = 'ln'
class Log(Func):
4985class Log(Func):
4986    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class Log2(Func):
4989class Log2(Func):
4990    pass
key = 'log2'
class Log10(Func):
4993class Log10(Func):
4994    pass
key = 'log10'
class LogicalOr(AggFunc):
4997class LogicalOr(AggFunc):
4998    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5001class LogicalAnd(AggFunc):
5002    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5005class Lower(Func):
5006    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5009class Map(Func):
5010    arg_types = {"keys": False, "values": False}
5011
5012    @property
5013    def keys(self) -> t.List[Expression]:
5014        keys = self.args.get("keys")
5015        return keys.expressions if keys else []
5016
5017    @property
5018    def values(self) -> t.List[Expression]:
5019        values = self.args.get("values")
5020        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5012    @property
5013    def keys(self) -> t.List[Expression]:
5014        keys = self.args.get("keys")
5015        return keys.expressions if keys else []
values: List[Expression]
5017    @property
5018    def values(self) -> t.List[Expression]:
5019        values = self.args.get("values")
5020        return values.expressions if values else []
key = 'map'
class MapFromEntries(Func):
5023class MapFromEntries(Func):
5024    pass
key = 'mapfromentries'
class StarMap(Func):
5027class StarMap(Func):
5028    pass
key = 'starmap'
class VarMap(Func):
5031class VarMap(Func):
5032    arg_types = {"keys": True, "values": True}
5033    is_var_len_args = True
5034
5035    @property
5036    def keys(self) -> t.List[Expression]:
5037        return self.args["keys"].expressions
5038
5039    @property
5040    def values(self) -> t.List[Expression]:
5041        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5035    @property
5036    def keys(self) -> t.List[Expression]:
5037        return self.args["keys"].expressions
values: List[Expression]
5039    @property
5040    def values(self) -> t.List[Expression]:
5041        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5045class MatchAgainst(Func):
5046    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5049class Max(AggFunc):
5050    arg_types = {"this": True, "expressions": False}
5051    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5054class MD5(Func):
5055    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5059class MD5Digest(Func):
5060    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5063class Min(AggFunc):
5064    arg_types = {"this": True, "expressions": False}
5065    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5068class Month(Func):
5069    pass
key = 'month'
class Nvl2(Func):
5072class Nvl2(Func):
5073    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5077class Predict(Func):
5078    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5081class Pow(Binary, Func):
5082    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5085class PercentileCont(AggFunc):
5086    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5089class PercentileDisc(AggFunc):
5090    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5093class Quantile(AggFunc):
5094    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5097class ApproxQuantile(Quantile):
5098    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):
5101class Rand(Func):
5102    _sql_names = ["RAND", "RANDOM"]
5103    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5106class Randn(Func):
5107    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5110class RangeN(Func):
5111    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5114class ReadCSV(Func):
5115    _sql_names = ["READ_CSV"]
5116    is_var_len_args = True
5117    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5120class Reduce(Func):
5121    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):
5124class RegexpExtract(Func):
5125    arg_types = {
5126        "this": True,
5127        "expression": True,
5128        "position": False,
5129        "occurrence": False,
5130        "parameters": False,
5131        "group": False,
5132    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5135class RegexpReplace(Func):
5136    arg_types = {
5137        "this": True,
5138        "expression": True,
5139        "replacement": False,
5140        "position": False,
5141        "occurrence": False,
5142        "parameters": False,
5143        "modifiers": False,
5144    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'parameters': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5147class RegexpLike(Binary, Func):
5148    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5151class RegexpILike(Binary, Func):
5152    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5157class RegexpSplit(Func):
5158    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5161class Repeat(Func):
5162    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5167class Round(Func):
5168    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5171class RowNumber(Func):
5172    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5175class SafeDivide(Func):
5176    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5179class SHA(Func):
5180    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5183class SHA2(Func):
5184    _sql_names = ["SHA2"]
5185    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SortArray(Func):
5188class SortArray(Func):
5189    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5192class Split(Func):
5193    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5198class Substring(Func):
5199    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5202class StandardHash(Func):
5203    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5206class StartsWith(Func):
5207    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5208    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5211class StrPosition(Func):
5212    arg_types = {
5213        "this": True,
5214        "substr": True,
5215        "position": False,
5216        "instance": False,
5217    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5220class StrToDate(Func):
5221    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5224class StrToTime(Func):
5225    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5230class StrToUnix(Func):
5231    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5236class StrToMap(Func):
5237    arg_types = {
5238        "this": True,
5239        "pair_delim": False,
5240        "key_value_delim": False,
5241        "duplicate_resolution_callback": False,
5242    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5245class NumberToStr(Func):
5246    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5249class FromBase(Func):
5250    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5253class Struct(Func):
5254    arg_types = {"expressions": False}
5255    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5258class StructExtract(Func):
5259    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5264class Stuff(Func):
5265    _sql_names = ["STUFF", "INSERT"]
5266    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):
5269class Sum(AggFunc):
5270    pass
key = 'sum'
class Sqrt(Func):
5273class Sqrt(Func):
5274    pass
key = 'sqrt'
class Stddev(AggFunc):
5277class Stddev(AggFunc):
5278    pass
key = 'stddev'
class StddevPop(AggFunc):
5281class StddevPop(AggFunc):
5282    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5285class StddevSamp(AggFunc):
5286    pass
key = 'stddevsamp'
class TimeToStr(Func):
5289class TimeToStr(Func):
5290    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5293class TimeToTimeStr(Func):
5294    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5297class TimeToUnix(Func):
5298    pass
key = 'timetounix'
class TimeStrToDate(Func):
5301class TimeStrToDate(Func):
5302    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5305class TimeStrToTime(Func):
5306    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5309class TimeStrToUnix(Func):
5310    pass
key = 'timestrtounix'
class Trim(Func):
5313class Trim(Func):
5314    arg_types = {
5315        "this": True,
5316        "expression": False,
5317        "position": False,
5318        "collation": False,
5319    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5322class TsOrDsAdd(Func, TimeUnit):
5323    # return_type is used to correctly cast the arguments of this expression when transpiling it
5324    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5325
5326    @property
5327    def return_type(self) -> DataType:
5328        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
5326    @property
5327    def return_type(self) -> DataType:
5328        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5331class TsOrDsDiff(Func, TimeUnit):
5332    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5335class TsOrDsToDateStr(Func):
5336    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5339class TsOrDsToDate(Func):
5340    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5343class TsOrDsToTime(Func):
5344    pass
key = 'tsordstotime'
class TsOrDiToDi(Func):
5347class TsOrDiToDi(Func):
5348    pass
key = 'tsorditodi'
class Unhex(Func):
5351class Unhex(Func):
5352    pass
key = 'unhex'
class UnixDate(Func):
5356class UnixDate(Func):
5357    pass
key = 'unixdate'
class UnixToStr(Func):
5360class UnixToStr(Func):
5361    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5366class UnixToTime(Func):
5367    arg_types = {"this": True, "scale": False, "zone": False, "hours": False, "minutes": False}
5368
5369    SECONDS = Literal.number(0)
5370    DECIS = Literal.number(1)
5371    CENTIS = Literal.number(2)
5372    MILLIS = Literal.number(3)
5373    DECIMILLIS = Literal.number(4)
5374    CENTIMILLIS = Literal.number(5)
5375    MICROS = Literal.number(6)
5376    DECIMICROS = Literal.number(7)
5377    CENTIMICROS = Literal.number(8)
5378    NANOS = Literal.number(9)
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False}
SECONDS = Literal(this=0, is_string=False)
DECIS = Literal(this=1, is_string=False)
CENTIS = Literal(this=2, is_string=False)
MILLIS = Literal(this=3, is_string=False)
DECIMILLIS = Literal(this=4, is_string=False)
CENTIMILLIS = Literal(this=5, is_string=False)
MICROS = Literal(this=6, is_string=False)
DECIMICROS = Literal(this=7, is_string=False)
CENTIMICROS = Literal(this=8, is_string=False)
NANOS = Literal(this=9, is_string=False)
key = 'unixtotime'
class UnixToTimeStr(Func):
5381class UnixToTimeStr(Func):
5382    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5385class TimestampFromParts(Func):
5386    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5387    arg_types = {
5388        "year": True,
5389        "month": True,
5390        "day": True,
5391        "hour": True,
5392        "min": True,
5393        "sec": True,
5394        "nano": False,
5395        "zone": False,
5396        "milli": False,
5397    }
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):
5400class Upper(Func):
5401    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Variance(AggFunc):
5404class Variance(AggFunc):
5405    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5408class VariancePop(AggFunc):
5409    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class Week(Func):
5412class Week(Func):
5413    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5416class XMLTable(Func):
5417    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):
5420class Year(Func):
5421    pass
key = 'year'
class Use(Expression):
5424class Use(Expression):
5425    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5428class Merge(Expression):
5429    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):
5432class When(Func):
5433    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):
5438class NextValueFor(Func):
5439    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 'JSONObjectAgg'>, <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_OBJECT_AGG': <class 'JSONObjectAgg'>, '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:
5477def maybe_parse(
5478    sql_or_expression: ExpOrStr,
5479    *,
5480    into: t.Optional[IntoType] = None,
5481    dialect: DialectType = None,
5482    prefix: t.Optional[str] = None,
5483    copy: bool = False,
5484    **opts,
5485) -> Expression:
5486    """Gracefully handle a possible string or expression.
5487
5488    Example:
5489        >>> maybe_parse("1")
5490        Literal(this=1, is_string=False)
5491        >>> maybe_parse(to_identifier("x"))
5492        Identifier(this=x, quoted=False)
5493
5494    Args:
5495        sql_or_expression: the SQL code string or an expression
5496        into: the SQLGlot Expression to parse into
5497        dialect: the dialect used to parse the input expressions (in the case that an
5498            input expression is a SQL string).
5499        prefix: a string to prefix the sql with before it gets parsed
5500            (automatically includes a space)
5501        copy: whether or not to copy the expression.
5502        **opts: other options to use to parse the input expressions (again, in the case
5503            that an input expression is a SQL string).
5504
5505    Returns:
5506        Expression: the parsed or given expression.
5507    """
5508    if isinstance(sql_or_expression, Expression):
5509        if copy:
5510            return sql_or_expression.copy()
5511        return sql_or_expression
5512
5513    if sql_or_expression is None:
5514        raise ParseError(f"SQL cannot be None")
5515
5516    import sqlglot
5517
5518    sql = str(sql_or_expression)
5519    if prefix:
5520        sql = f"{prefix} {sql}"
5521
5522    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):
5535def maybe_copy(instance, copy=True):
5536    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:
5750def union(
5751    left: ExpOrStr,
5752    right: ExpOrStr,
5753    distinct: bool = True,
5754    dialect: DialectType = None,
5755    copy: bool = True,
5756    **opts,
5757) -> Union:
5758    """
5759    Initializes a syntax tree from one UNION expression.
5760
5761    Example:
5762        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
5763        'SELECT * FROM foo UNION SELECT * FROM bla'
5764
5765    Args:
5766        left: the SQL code string corresponding to the left-hand side.
5767            If an `Expression` instance is passed, it will be used as-is.
5768        right: the SQL code string corresponding to the right-hand side.
5769            If an `Expression` instance is passed, it will be used as-is.
5770        distinct: set the DISTINCT flag if and only if this is true.
5771        dialect: the dialect used to parse the input expression.
5772        copy: whether or not to copy the expression.
5773        opts: other options to use to parse the input expressions.
5774
5775    Returns:
5776        The new Union instance.
5777    """
5778    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5779    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5780
5781    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:
5784def intersect(
5785    left: ExpOrStr,
5786    right: ExpOrStr,
5787    distinct: bool = True,
5788    dialect: DialectType = None,
5789    copy: bool = True,
5790    **opts,
5791) -> Intersect:
5792    """
5793    Initializes a syntax tree from one INTERSECT expression.
5794
5795    Example:
5796        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
5797        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
5798
5799    Args:
5800        left: the SQL code string corresponding to the left-hand side.
5801            If an `Expression` instance is passed, it will be used as-is.
5802        right: the SQL code string corresponding to the right-hand side.
5803            If an `Expression` instance is passed, it will be used as-is.
5804        distinct: set the DISTINCT flag if and only if this is true.
5805        dialect: the dialect used to parse the input expression.
5806        copy: whether or not to copy the expression.
5807        opts: other options to use to parse the input expressions.
5808
5809    Returns:
5810        The new Intersect instance.
5811    """
5812    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5813    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5814
5815    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:
5818def except_(
5819    left: ExpOrStr,
5820    right: ExpOrStr,
5821    distinct: bool = True,
5822    dialect: DialectType = None,
5823    copy: bool = True,
5824    **opts,
5825) -> Except:
5826    """
5827    Initializes a syntax tree from one EXCEPT expression.
5828
5829    Example:
5830        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
5831        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
5832
5833    Args:
5834        left: the SQL code string corresponding to the left-hand side.
5835            If an `Expression` instance is passed, it will be used as-is.
5836        right: the SQL code string corresponding to the right-hand side.
5837            If an `Expression` instance is passed, it will be used as-is.
5838        distinct: set the DISTINCT flag if and only if this is true.
5839        dialect: the dialect used to parse the input expression.
5840        copy: whether or not to copy the expression.
5841        opts: other options to use to parse the input expressions.
5842
5843    Returns:
5844        The new Except instance.
5845    """
5846    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
5847    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
5848
5849    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:
5852def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5853    """
5854    Initializes a syntax tree from one or multiple SELECT expressions.
5855
5856    Example:
5857        >>> select("col1", "col2").from_("tbl").sql()
5858        'SELECT col1, col2 FROM tbl'
5859
5860    Args:
5861        *expressions: the SQL code string to parse as the expressions of a
5862            SELECT statement. If an Expression instance is passed, this is used as-is.
5863        dialect: the dialect used to parse the input expressions (in the case that an
5864            input expression is a SQL string).
5865        **opts: other options to use to parse the input expressions (again, in the case
5866            that an input expression is a SQL string).
5867
5868    Returns:
5869        Select: the syntax tree for the SELECT statement.
5870    """
5871    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:
5874def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
5875    """
5876    Initializes a syntax tree from a FROM expression.
5877
5878    Example:
5879        >>> from_("tbl").select("col1", "col2").sql()
5880        'SELECT col1, col2 FROM tbl'
5881
5882    Args:
5883        *expression: the SQL code string to parse as the FROM expressions of a
5884            SELECT statement. If an Expression instance is passed, this is used as-is.
5885        dialect: the dialect used to parse the input expression (in the case that the
5886            input expression is a SQL string).
5887        **opts: other options to use to parse the input expressions (again, in the case
5888            that the input expression is a SQL string).
5889
5890    Returns:
5891        Select: the syntax tree for the SELECT statement.
5892    """
5893    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:
5896def update(
5897    table: str | Table,
5898    properties: dict,
5899    where: t.Optional[ExpOrStr] = None,
5900    from_: t.Optional[ExpOrStr] = None,
5901    dialect: DialectType = None,
5902    **opts,
5903) -> Update:
5904    """
5905    Creates an update statement.
5906
5907    Example:
5908        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
5909        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
5910
5911    Args:
5912        *properties: dictionary of properties to set which are
5913            auto converted to sql objects eg None -> NULL
5914        where: sql conditional parsed into a WHERE statement
5915        from_: sql statement parsed into a FROM statement
5916        dialect: the dialect used to parse the input expressions.
5917        **opts: other options to use to parse the input expressions.
5918
5919    Returns:
5920        Update: the syntax tree for the UPDATE statement.
5921    """
5922    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
5923    update_expr.set(
5924        "expressions",
5925        [
5926            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
5927            for k, v in properties.items()
5928        ],
5929    )
5930    if from_:
5931        update_expr.set(
5932            "from",
5933            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
5934        )
5935    if isinstance(where, Condition):
5936        where = Where(this=where)
5937    if where:
5938        update_expr.set(
5939            "where",
5940            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
5941        )
5942    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:
5945def delete(
5946    table: ExpOrStr,
5947    where: t.Optional[ExpOrStr] = None,
5948    returning: t.Optional[ExpOrStr] = None,
5949    dialect: DialectType = None,
5950    **opts,
5951) -> Delete:
5952    """
5953    Builds a delete statement.
5954
5955    Example:
5956        >>> delete("my_table", where="id > 1").sql()
5957        'DELETE FROM my_table WHERE id > 1'
5958
5959    Args:
5960        where: sql conditional parsed into a WHERE statement
5961        returning: sql conditional parsed into a RETURNING statement
5962        dialect: the dialect used to parse the input expressions.
5963        **opts: other options to use to parse the input expressions.
5964
5965    Returns:
5966        Delete: the syntax tree for the DELETE statement.
5967    """
5968    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
5969    if where:
5970        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
5971    if returning:
5972        delete_expr = t.cast(
5973            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
5974        )
5975    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[str | Identifier]] = 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:
5978def insert(
5979    expression: ExpOrStr,
5980    into: ExpOrStr,
5981    columns: t.Optional[t.Sequence[str | Identifier]] = None,
5982    overwrite: t.Optional[bool] = None,
5983    returning: t.Optional[ExpOrStr] = None,
5984    dialect: DialectType = None,
5985    copy: bool = True,
5986    **opts,
5987) -> Insert:
5988    """
5989    Builds an INSERT statement.
5990
5991    Example:
5992        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
5993        'INSERT INTO tbl VALUES (1, 2, 3)'
5994
5995    Args:
5996        expression: the sql string or expression of the INSERT statement
5997        into: the tbl to insert data to.
5998        columns: optionally the table's column names.
5999        overwrite: whether to INSERT OVERWRITE or not.
6000        returning: sql conditional parsed into a RETURNING statement
6001        dialect: the dialect used to parse the input expressions.
6002        copy: whether or not to copy the expression.
6003        **opts: other options to use to parse the input expressions.
6004
6005    Returns:
6006        Insert: the syntax tree for the INSERT statement.
6007    """
6008    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6009    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6010
6011    if columns:
6012        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6013
6014    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6015
6016    if returning:
6017        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6018
6019    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:
6022def condition(
6023    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6024) -> Condition:
6025    """
6026    Initialize a logical condition expression.
6027
6028    Example:
6029        >>> condition("x=1").sql()
6030        'x = 1'
6031
6032        This is helpful for composing larger logical syntax trees:
6033        >>> where = condition("x=1")
6034        >>> where = where.and_("y=1")
6035        >>> Select().from_("tbl").select("*").where(where).sql()
6036        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6037
6038    Args:
6039        *expression: the SQL code string to parse.
6040            If an Expression instance is passed, this is used as-is.
6041        dialect: the dialect used to parse the input expression (in the case that the
6042            input expression is a SQL string).
6043        copy: Whether or not to copy `expression` (only applies to expressions).
6044        **opts: other options to use to parse the input expressions (again, in the case
6045            that the input expression is a SQL string).
6046
6047    Returns:
6048        The new Condition instance
6049    """
6050    return maybe_parse(
6051        expression,
6052        into=Condition,
6053        dialect=dialect,
6054        copy=copy,
6055        **opts,
6056    )

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:
6059def and_(
6060    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6061) -> Condition:
6062    """
6063    Combine multiple conditions with an AND logical operator.
6064
6065    Example:
6066        >>> and_("x=1", and_("y=1", "z=1")).sql()
6067        'x = 1 AND (y = 1 AND z = 1)'
6068
6069    Args:
6070        *expressions: the SQL code strings to parse.
6071            If an Expression instance is passed, this is used as-is.
6072        dialect: the dialect used to parse the input expression.
6073        copy: whether or not to copy `expressions` (only applies to Expressions).
6074        **opts: other options to use to parse the input expressions.
6075
6076    Returns:
6077        And: the new condition
6078    """
6079    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:
6082def or_(
6083    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6084) -> Condition:
6085    """
6086    Combine multiple conditions with an OR logical operator.
6087
6088    Example:
6089        >>> or_("x=1", or_("y=1", "z=1")).sql()
6090        'x = 1 OR (y = 1 OR z = 1)'
6091
6092    Args:
6093        *expressions: the SQL code strings to parse.
6094            If an Expression instance is passed, this is used as-is.
6095        dialect: the dialect used to parse the input expression.
6096        copy: whether or not to copy `expressions` (only applies to Expressions).
6097        **opts: other options to use to parse the input expressions.
6098
6099    Returns:
6100        Or: the new condition
6101    """
6102    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:
6105def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6106    """
6107    Wrap a condition with a NOT operator.
6108
6109    Example:
6110        >>> not_("this_suit='black'").sql()
6111        "NOT this_suit = 'black'"
6112
6113    Args:
6114        expression: the SQL code string to parse.
6115            If an Expression instance is passed, this is used as-is.
6116        dialect: the dialect used to parse the input expression.
6117        copy: whether to copy the expression or not.
6118        **opts: other options to use to parse the input expressions.
6119
6120    Returns:
6121        The new condition.
6122    """
6123    this = condition(
6124        expression,
6125        dialect=dialect,
6126        copy=copy,
6127        **opts,
6128    )
6129    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:
6132def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6133    """
6134    Wrap an expression in parentheses.
6135
6136    Example:
6137        >>> paren("5 + 3").sql()
6138        '(5 + 3)'
6139
6140    Args:
6141        expression: the SQL code string to parse.
6142            If an Expression instance is passed, this is used as-is.
6143        copy: whether to copy the expression or not.
6144
6145    Returns:
6146        The wrapped expression.
6147    """
6148    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):
6166def to_identifier(name, quoted=None, copy=True):
6167    """Builds an identifier.
6168
6169    Args:
6170        name: The name to turn into an identifier.
6171        quoted: Whether or not force quote the identifier.
6172        copy: Whether or not to copy name if it's an Identifier.
6173
6174    Returns:
6175        The identifier ast node.
6176    """
6177
6178    if name is None:
6179        return None
6180
6181    if isinstance(name, Identifier):
6182        identifier = maybe_copy(name, copy)
6183    elif isinstance(name, str):
6184        identifier = Identifier(
6185            this=name,
6186            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6187        )
6188    else:
6189        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6190    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:
6193def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6194    """
6195    Parses a given string into an identifier.
6196
6197    Args:
6198        name: The name to parse into an identifier.
6199        dialect: The dialect to parse against.
6200
6201    Returns:
6202        The identifier ast node.
6203    """
6204    try:
6205        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6206    except ParseError:
6207        expression = to_identifier(name)
6208
6209    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:
6215def to_interval(interval: str | Literal) -> Interval:
6216    """Builds an interval expression from a string like '1 day' or '5 months'."""
6217    if isinstance(interval, Literal):
6218        if not interval.is_string:
6219            raise ValueError("Invalid interval string.")
6220
6221        interval = interval.this
6222
6223    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6224
6225    if not interval_parts:
6226        raise ValueError("Invalid interval string.")
6227
6228    return Interval(
6229        this=Literal.string(interval_parts.group(1)),
6230        unit=Var(this=interval_parts.group(2).upper()),
6231    )

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]:
6244def to_table(
6245    sql_path: t.Optional[str | Table], dialect: DialectType = None, copy: bool = True, **kwargs
6246) -> t.Optional[Table]:
6247    """
6248    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6249    If a table is passed in then that table is returned.
6250
6251    Args:
6252        sql_path: a `[catalog].[schema].[table]` string.
6253        dialect: the source dialect according to which the table name will be parsed.
6254        copy: Whether or not to copy a table if it is passed in.
6255        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6256
6257    Returns:
6258        A table expression.
6259    """
6260    if sql_path is None or isinstance(sql_path, Table):
6261        return maybe_copy(sql_path, copy=copy)
6262    if not isinstance(sql_path, str):
6263        raise ValueError(f"Invalid type provided for a table: {type(sql_path)}")
6264
6265    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6266    if table:
6267        for k, v in kwargs.items():
6268            table.set(k, v)
6269
6270    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:
6273def to_column(sql_path: str | Column, **kwargs) -> Column:
6274    """
6275    Create a column from a `[table].[column]` sql path. Schema is optional.
6276
6277    If a column is passed in then that column is returned.
6278
6279    Args:
6280        sql_path: `[table].[column]` string
6281    Returns:
6282        Table: A column expression
6283    """
6284    if sql_path is None or isinstance(sql_path, Column):
6285        return sql_path
6286    if not isinstance(sql_path, str):
6287        raise ValueError(f"Invalid type provided for column: {type(sql_path)}")
6288    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):
6291def alias_(
6292    expression: ExpOrStr,
6293    alias: str | Identifier,
6294    table: bool | t.Sequence[str | Identifier] = False,
6295    quoted: t.Optional[bool] = None,
6296    dialect: DialectType = None,
6297    copy: bool = True,
6298    **opts,
6299):
6300    """Create an Alias expression.
6301
6302    Example:
6303        >>> alias_('foo', 'bar').sql()
6304        'foo AS bar'
6305
6306        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6307        '(SELECT 1, 2) AS bar(a, b)'
6308
6309    Args:
6310        expression: the SQL code strings to parse.
6311            If an Expression instance is passed, this is used as-is.
6312        alias: the alias name to use. If the name has
6313            special characters it is quoted.
6314        table: Whether or not to create a table alias, can also be a list of columns.
6315        quoted: whether or not to quote the alias
6316        dialect: the dialect used to parse the input expression.
6317        copy: Whether or not to copy the expression.
6318        **opts: other options to use to parse the input expressions.
6319
6320    Returns:
6321        Alias: the aliased expression
6322    """
6323    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6324    alias = to_identifier(alias, quoted=quoted)
6325
6326    if table:
6327        table_alias = TableAlias(this=alias)
6328        exp.set("alias", table_alias)
6329
6330        if not isinstance(table, bool):
6331            for column in table:
6332                table_alias.append("columns", to_identifier(column, quoted=quoted))
6333
6334        return exp
6335
6336    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6337    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6338    # for the complete Window expression.
6339    #
6340    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6341
6342    if "alias" in exp.arg_types and not isinstance(exp, Window):
6343        exp.set("alias", alias)
6344        return exp
6345    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:
6348def subquery(
6349    expression: ExpOrStr,
6350    alias: t.Optional[Identifier | str] = None,
6351    dialect: DialectType = None,
6352    **opts,
6353) -> Select:
6354    """
6355    Build a subquery expression.
6356
6357    Example:
6358        >>> subquery('select x from tbl', 'bar').select('x').sql()
6359        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6360
6361    Args:
6362        expression: the SQL code strings to parse.
6363            If an Expression instance is passed, this is used as-is.
6364        alias: the alias name to use.
6365        dialect: the dialect used to parse the input expression.
6366        **opts: other options to use to parse the input expressions.
6367
6368    Returns:
6369        A new Select instance with the subquery expression included.
6370    """
6371
6372    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias)
6373    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, table=None, db=None, catalog=None, *, fields=None, quoted=None, copy=True):
6404def column(
6405    col,
6406    table=None,
6407    db=None,
6408    catalog=None,
6409    *,
6410    fields=None,
6411    quoted=None,
6412    copy=True,
6413):
6414    """
6415    Build a Column.
6416
6417    Args:
6418        col: Column name.
6419        table: Table name.
6420        db: Database name.
6421        catalog: Catalog name.
6422        fields: Additional fields using dots.
6423        quoted: Whether to force quotes on the column's identifiers.
6424        copy: Whether or not to copy identifiers if passed in.
6425
6426    Returns:
6427        The new Column instance.
6428    """
6429    this = Column(
6430        this=to_identifier(col, quoted=quoted, copy=copy),
6431        table=to_identifier(table, quoted=quoted, copy=copy),
6432        db=to_identifier(db, quoted=quoted, copy=copy),
6433        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
6434    )
6435
6436    if fields:
6437        this = Dot.build((this, *(to_identifier(field, copy=copy) for field in fields)))
6438    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:
6441def cast(expression: ExpOrStr, to: DATA_TYPE, **opts) -> Cast:
6442    """Cast an expression to a data type.
6443
6444    Example:
6445        >>> cast('x + 1', 'int').sql()
6446        'CAST(x + 1 AS INT)'
6447
6448    Args:
6449        expression: The expression to cast.
6450        to: The datatype to cast to.
6451
6452    Returns:
6453        The new Cast instance.
6454    """
6455    expression = maybe_parse(expression, **opts)
6456    data_type = DataType.build(to, **opts)
6457    expression = Cast(this=expression, to=data_type)
6458    expression.type = data_type
6459    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:
6462def table_(
6463    table: Identifier | str,
6464    db: t.Optional[Identifier | str] = None,
6465    catalog: t.Optional[Identifier | str] = None,
6466    quoted: t.Optional[bool] = None,
6467    alias: t.Optional[Identifier | str] = None,
6468) -> Table:
6469    """Build a Table.
6470
6471    Args:
6472        table: Table name.
6473        db: Database name.
6474        catalog: Catalog name.
6475        quote: Whether to force quotes on the table's identifiers.
6476        alias: Table's alias.
6477
6478    Returns:
6479        The new Table instance.
6480    """
6481    return Table(
6482        this=to_identifier(table, quoted=quoted) if table else None,
6483        db=to_identifier(db, quoted=quoted) if db else None,
6484        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
6485        alias=TableAlias(this=to_identifier(alias)) if alias else None,
6486    )

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:
6489def values(
6490    values: t.Iterable[t.Tuple[t.Any, ...]],
6491    alias: t.Optional[str] = None,
6492    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
6493) -> Values:
6494    """Build VALUES statement.
6495
6496    Example:
6497        >>> values([(1, '2')]).sql()
6498        "VALUES (1, '2')"
6499
6500    Args:
6501        values: values statements that will be converted to SQL
6502        alias: optional alias
6503        columns: Optional list of ordered column names or ordered dictionary of column names to types.
6504         If either are provided then an alias is also required.
6505
6506    Returns:
6507        Values: the Values expression object
6508    """
6509    if columns and not alias:
6510        raise ValueError("Alias is required when providing columns")
6511
6512    return Values(
6513        expressions=[convert(tup) for tup in values],
6514        alias=(
6515            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
6516            if columns
6517            else (TableAlias(this=to_identifier(alias)) if alias else None)
6518        ),
6519    )

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:
6522def var(name: t.Optional[ExpOrStr]) -> Var:
6523    """Build a SQL variable.
6524
6525    Example:
6526        >>> repr(var('x'))
6527        'Var(this=x)'
6528
6529        >>> repr(var(column('x', table='y')))
6530        'Var(this=x)'
6531
6532    Args:
6533        name: The name of the var or an expression who's name will become the var.
6534
6535    Returns:
6536        The new variable node.
6537    """
6538    if not name:
6539        raise ValueError("Cannot convert empty name into var.")
6540
6541    if isinstance(name, Expression):
6542        name = name.name
6543    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:
6546def rename_table(old_name: str | Table, new_name: str | Table) -> AlterTable:
6547    """Build ALTER TABLE... RENAME... expression
6548
6549    Args:
6550        old_name: The old name of the table
6551        new_name: The new name of the table
6552
6553    Returns:
6554        Alter table expression
6555    """
6556    old_table = to_table(old_name)
6557    new_table = to_table(new_name)
6558    return AlterTable(
6559        this=old_table,
6560        actions=[
6561            RenameTable(this=new_table),
6562        ],
6563    )

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:
6566def convert(value: t.Any, copy: bool = False) -> Expression:
6567    """Convert a python value into an expression object.
6568
6569    Raises an error if a conversion is not possible.
6570
6571    Args:
6572        value: A python object.
6573        copy: Whether or not to copy `value` (only applies to Expressions and collections).
6574
6575    Returns:
6576        Expression: the equivalent expression object.
6577    """
6578    if isinstance(value, Expression):
6579        return maybe_copy(value, copy)
6580    if isinstance(value, str):
6581        return Literal.string(value)
6582    if isinstance(value, bool):
6583        return Boolean(this=value)
6584    if value is None or (isinstance(value, float) and math.isnan(value)):
6585        return NULL
6586    if isinstance(value, numbers.Number):
6587        return Literal.number(value)
6588    if isinstance(value, datetime.datetime):
6589        datetime_literal = Literal.string(
6590            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat()
6591        )
6592        return TimeStrToTime(this=datetime_literal)
6593    if isinstance(value, datetime.date):
6594        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
6595        return DateStrToDate(this=date_literal)
6596    if isinstance(value, tuple):
6597        return Tuple(expressions=[convert(v, copy=copy) for v in value])
6598    if isinstance(value, list):
6599        return Array(expressions=[convert(v, copy=copy) for v in value])
6600    if isinstance(value, dict):
6601        return Map(
6602            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
6603            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
6604        )
6605    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:
6608def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
6609    """
6610    Replace children of an expression with the result of a lambda fun(child) -> exp.
6611    """
6612    for k, v in expression.args.items():
6613        is_list_arg = type(v) is list
6614
6615        child_nodes = v if is_list_arg else [v]
6616        new_child_nodes = []
6617
6618        for cn in child_nodes:
6619            if isinstance(cn, Expression):
6620                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
6621                    new_child_nodes.append(child_node)
6622                    child_node.parent = expression
6623                    child_node.arg_key = k
6624            else:
6625                new_child_nodes.append(cn)
6626
6627        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]:
6630def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
6631    """
6632    Return all table names referenced through columns in an expression.
6633
6634    Example:
6635        >>> import sqlglot
6636        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
6637        ['a', 'c']
6638
6639    Args:
6640        expression: expression to find table names.
6641        exclude: a table name to exclude
6642
6643    Returns:
6644        A list of unique names.
6645    """
6646    return {
6647        table
6648        for table in (column.table for column in expression.find_all(Column))
6649        if table and table != exclude
6650    }

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:
6653def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
6654    """Get the full name of a table as a string.
6655
6656    Args:
6657        table: Table expression node or string.
6658        dialect: The dialect to generate the table name for.
6659        identify: Determines when an identifier should be quoted. Possible values are:
6660            False (default): Never quote, except in cases where it's mandatory by the dialect.
6661            True: Always quote.
6662
6663    Examples:
6664        >>> from sqlglot import exp, parse_one
6665        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
6666        'a.b.c'
6667
6668    Returns:
6669        The table name.
6670    """
6671
6672    table = maybe_parse(table, into=Table, dialect=dialect)
6673
6674    if not table:
6675        raise ValueError(f"Cannot parse {table}")
6676
6677    return ".".join(
6678        part.sql(dialect=dialect, identify=True, copy=False)
6679        if identify or not SAFE_IDENTIFIER_RE.match(part.name)
6680        else part.name
6681        for part in table.parts
6682    )

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:
6685def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
6686    """Returns a case normalized table name without quotes.
6687
6688    Args:
6689        table: the table to normalize
6690        dialect: the dialect to use for normalization rules
6691        copy: whether or not to copy the expression.
6692
6693    Examples:
6694        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
6695        'A-B.c'
6696    """
6697    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
6698
6699    return ".".join(
6700        p.name
6701        for p in normalize_identifiers(
6702            to_table(table, dialect=dialect, copy=copy), dialect=dialect
6703        ).parts
6704    )

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:
6707def replace_tables(
6708    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
6709) -> E:
6710    """Replace all tables in expression according to the mapping.
6711
6712    Args:
6713        expression: expression node to be transformed and replaced.
6714        mapping: mapping of table names.
6715        dialect: the dialect of the mapping table
6716        copy: whether or not to copy the expression.
6717
6718    Examples:
6719        >>> from sqlglot import exp, parse_one
6720        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
6721        'SELECT * FROM c /* a.b */'
6722
6723    Returns:
6724        The mapped expression.
6725    """
6726
6727    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
6728
6729    def _replace_tables(node: Expression) -> Expression:
6730        if isinstance(node, Table):
6731            original = normalize_table_name(node, dialect=dialect)
6732            new_name = mapping.get(original)
6733
6734            if new_name:
6735                table = to_table(
6736                    new_name,
6737                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
6738                )
6739                table.add_comments([original])
6740                return table
6741        return node
6742
6743    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:
6746def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
6747    """Replace placeholders in an expression.
6748
6749    Args:
6750        expression: expression node to be transformed and replaced.
6751        args: positional names that will substitute unnamed placeholders in the given order.
6752        kwargs: keyword arguments that will substitute named placeholders.
6753
6754    Examples:
6755        >>> from sqlglot import exp, parse_one
6756        >>> replace_placeholders(
6757        ...     parse_one("select * from :tbl where ? = ?"),
6758        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
6759        ... ).sql()
6760        "SELECT * FROM foo WHERE str_col = 'b'"
6761
6762    Returns:
6763        The mapped expression.
6764    """
6765
6766    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
6767        if isinstance(node, Placeholder):
6768            if node.name:
6769                new_name = kwargs.get(node.name)
6770                if new_name:
6771                    return convert(new_name)
6772            else:
6773                try:
6774                    return convert(next(args))
6775                except StopIteration:
6776                    pass
6777        return node
6778
6779    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:
6782def expand(
6783    expression: Expression,
6784    sources: t.Dict[str, Subqueryable],
6785    dialect: DialectType = None,
6786    copy: bool = True,
6787) -> Expression:
6788    """Transforms an expression by expanding all referenced sources into subqueries.
6789
6790    Examples:
6791        >>> from sqlglot import parse_one
6792        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
6793        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
6794
6795        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
6796        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
6797
6798    Args:
6799        expression: The expression to expand.
6800        sources: A dictionary of name to Subqueryables.
6801        dialect: The dialect of the sources dict.
6802        copy: Whether or not to copy the expression during transformation. Defaults to True.
6803
6804    Returns:
6805        The transformed expression.
6806    """
6807    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
6808
6809    def _expand(node: Expression):
6810        if isinstance(node, Table):
6811            name = normalize_table_name(node, dialect=dialect)
6812            source = sources.get(name)
6813            if source:
6814                subquery = source.subquery(node.alias or name)
6815                subquery.comments = [f"source: {name}"]
6816                return subquery.transform(_expand, copy=False)
6817        return node
6818
6819    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:
6822def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
6823    """
6824    Returns a Func expression.
6825
6826    Examples:
6827        >>> func("abs", 5).sql()
6828        'ABS(5)'
6829
6830        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
6831        'CAST(5 AS DOUBLE)'
6832
6833    Args:
6834        name: the name of the function to build.
6835        args: the args used to instantiate the function of interest.
6836        copy: whether or not to copy the argument expressions.
6837        dialect: the source dialect.
6838        kwargs: the kwargs used to instantiate the function of interest.
6839
6840    Note:
6841        The arguments `args` and `kwargs` are mutually exclusive.
6842
6843    Returns:
6844        An instance of the function of interest, or an anonymous function, if `name` doesn't
6845        correspond to an existing `sqlglot.expressions.Func` class.
6846    """
6847    if args and kwargs:
6848        raise ValueError("Can't use both args and kwargs to instantiate a function.")
6849
6850    from sqlglot.dialects.dialect import Dialect
6851
6852    dialect = Dialect.get_or_raise(dialect)
6853
6854    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
6855    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
6856
6857    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
6858    if constructor:
6859        if converted:
6860            if "dialect" in constructor.__code__.co_varnames:
6861                function = constructor(converted, dialect=dialect)
6862            else:
6863                function = constructor(converted)
6864        elif constructor.__name__ == "from_arg_list":
6865            function = constructor.__self__(**kwargs)  # type: ignore
6866        else:
6867            constructor = FUNCTION_BY_NAME.get(name.upper())
6868            if constructor:
6869                function = constructor(**kwargs)
6870            else:
6871                raise ValueError(
6872                    f"Unable to convert '{name}' into a Func. Either manually construct "
6873                    "the Func expression of interest or parse the function call."
6874                )
6875    else:
6876        kwargs = kwargs or {"expressions": converted}
6877        function = Anonymous(this=name, **kwargs)
6878
6879    for error_message in function.error_messages(converted):
6880        raise ValueError(error_message)
6881
6882    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:
6885def case(
6886    expression: t.Optional[ExpOrStr] = None,
6887    **opts,
6888) -> Case:
6889    """
6890    Initialize a CASE statement.
6891
6892    Example:
6893        case().when("a = 1", "foo").else_("bar")
6894
6895    Args:
6896        expression: Optionally, the input expression (not all dialects support this)
6897        **opts: Extra keyword arguments for parsing `expression`
6898    """
6899    if expression is not None:
6900        this = maybe_parse(expression, **opts)
6901    else:
6902        this = None
6903    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:
6906def cast_unless(
6907    expression: ExpOrStr,
6908    to: DATA_TYPE,
6909    *types: DATA_TYPE,
6910    **opts: t.Any,
6911) -> Expression | Cast:
6912    """
6913    Cast an expression to a data type unless it is a specified type.
6914
6915    Args:
6916        expression: The expression to cast.
6917        to: The data type to cast to.
6918        **types: The types to exclude from casting.
6919        **opts: Extra keyword arguments for parsing `expression`
6920    """
6921    expr = maybe_parse(expression, **opts)
6922    if expr.is_type(*types):
6923        return expr
6924    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:
6927def true() -> Boolean:
6928    """
6929    Returns a true Boolean expression.
6930    """
6931    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
6934def false() -> Boolean:
6935    """
6936    Returns a false Boolean expression.
6937    """
6938    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
6941def null() -> Null:
6942    """
6943    Returns a Null expression.
6944    """
6945    return Null()

Returns a Null expression.

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