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

Retrieves the argument with key "this".

expression: Any
138    @property
139    def expression(self) -> t.Any:
140        """
141        Retrieves the argument with key "expression".
142        """
143        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
145    @property
146    def expressions(self) -> t.List[t.Any]:
147        """
148        Retrieves the argument with key "expressions".
149        """
150        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

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

Checks whether a Literal expression is a string.

is_number: bool
173    @property
174    def is_number(self) -> bool:
175        """
176        Checks whether a Literal expression is a number.
177        """
178        return isinstance(self, Literal) and not self.args["is_string"]

Checks whether a Literal expression is a number.

is_negative: bool
180    @property
181    def is_negative(self) -> bool:
182        """
183        Checks whether an expression is negative.
184
185        Handles both exp.Neg and Literal numbers with "-" which come from optimizer.simplify.
186        """
187        return isinstance(self, Neg) or (self.is_number and self.this.startswith("-"))

Checks whether an expression is negative.

Handles both exp.Neg and Literal numbers with "-" which come from optimizer.simplify.

is_int: bool
189    @property
190    def is_int(self) -> bool:
191        """
192        Checks whether a Literal expression is an integer.
193        """
194        return self.is_number and is_int(self.name)

Checks whether a Literal expression is an integer.

is_star: bool
196    @property
197    def is_star(self) -> bool:
198        """Checks whether an expression is a star."""
199        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
201    @property
202    def alias(self) -> str:
203        """
204        Returns the alias of the expression, or an empty string if it's not aliased.
205        """
206        if isinstance(self.args.get("alias"), TableAlias):
207            return self.args["alias"].name
208        return self.text("alias")

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

alias_column_names: List[str]
210    @property
211    def alias_column_names(self) -> t.List[str]:
212        table_alias = self.args.get("alias")
213        if not table_alias:
214            return []
215        return [c.name for c in table_alias.args.get("columns") or []]
name: str
217    @property
218    def name(self) -> str:
219        return self.text("this")
alias_or_name: str
221    @property
222    def alias_or_name(self) -> str:
223        return self.alias or self.name
output_name: str
225    @property
226    def output_name(self) -> str:
227        """
228        Name of the output column if this expression is a selection.
229
230        If the Expression has no output name, an empty string is returned.
231
232        Example:
233            >>> from sqlglot import parse_one
234            >>> parse_one("SELECT a").expressions[0].output_name
235            'a'
236            >>> parse_one("SELECT b AS c").expressions[0].output_name
237            'c'
238            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
239            ''
240        """
241        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]
243    @property
244    def type(self) -> t.Optional[DataType]:
245        return self._type
def is_type(self, *dtypes) -> bool:
253    def is_type(self, *dtypes) -> bool:
254        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
256    def is_leaf(self) -> bool:
257        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
259    @property
260    def meta(self) -> t.Dict[str, t.Any]:
261        if self._meta is None:
262            self._meta = {}
263        return self._meta
def copy(self):
299    def copy(self):
300        """
301        Returns a deep copy of the expression.
302        """
303        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]] = None) -> None:
305    def add_comments(self, comments: t.Optional[t.List[str]] = None) -> None:
306        if self.comments is None:
307            self.comments = []
308
309        if comments:
310            for comment in comments:
311                _, *meta = comment.split(SQLGLOT_META)
312                if meta:
313                    for kv in "".join(meta).split(","):
314                        k, *v = kv.split("=")
315                        value = v[0].strip() if v else True
316                        self.meta[k.strip()] = value
317                self.comments.append(comment)
def pop_comments(self) -> List[str]:
319    def pop_comments(self) -> t.List[str]:
320        comments = self.comments or []
321        self.comments = None
322        return comments
def append(self, arg_key: str, value: Any) -> None:
324    def append(self, arg_key: str, value: t.Any) -> None:
325        """
326        Appends value to arg_key if it's a list or sets it as a new list.
327
328        Args:
329            arg_key (str): name of the list expression arg
330            value (Any): value to append to the list
331        """
332        if type(self.args.get(arg_key)) is not list:
333            self.args[arg_key] = []
334        self._set_parent(arg_key, value)
335        values = self.args[arg_key]
336        if hasattr(value, "parent"):
337            value.index = len(values)
338        values.append(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, index: Optional[int] = None) -> None:
340    def set(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
341        """
342        Sets arg_key to value.
343
344        Args:
345            arg_key: name of the expression arg.
346            value: value to set the arg to.
347            index: if the arg is a list, this specifies what position to add the value in it.
348        """
349        if index is not None:
350            expressions = self.args.get(arg_key) or []
351
352            if seq_get(expressions, index) is None:
353                return
354            if value is None:
355                expressions.pop(index)
356                for v in expressions[index:]:
357                    v.index = v.index - 1
358                return
359
360            if isinstance(value, list):
361                expressions.pop(index)
362                expressions[index:index] = value
363            else:
364                expressions[index] = value
365
366            value = expressions
367        elif value is None:
368            self.args.pop(arg_key, None)
369            return
370
371        self.args[arg_key] = value
372        self._set_parent(arg_key, value, index)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
  • index: if the arg is a list, this specifies what position to add the value in it.
depth: int
386    @property
387    def depth(self) -> int:
388        """
389        Returns the depth of this tree.
390        """
391        if self.parent:
392            return self.parent.depth + 1
393        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
395    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
396        """Yields the key and expression for all arguments, exploding list args."""
397        # remove tuple when python 3.7 is deprecated
398        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
399            if type(vs) is list:
400                for v in reversed(vs) if reverse else vs:
401                    if hasattr(v, "parent"):
402                        yield v
403            else:
404                if hasattr(vs, "parent"):
405                    yield vs

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

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
407    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
408        """
409        Returns the first node in this tree which matches at least one of
410        the specified types.
411
412        Args:
413            expression_types: the expression type(s) to match.
414            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
415
416        Returns:
417            The node which matches the criteria or None if no such node was found.
418        """
419        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]:
421    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
422        """
423        Returns a generator object which visits all nodes in this tree and only
424        yields those that match at least one of the specified expression types.
425
426        Args:
427            expression_types: the expression type(s) to match.
428            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
429
430        Returns:
431            The generator object.
432        """
433        for expression in self.walk(bfs=bfs):
434            if isinstance(expression, expression_types):
435                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]:
437    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
438        """
439        Returns a nearest parent matching expression_types.
440
441        Args:
442            expression_types: the expression type(s) to match.
443
444        Returns:
445            The parent node.
446        """
447        ancestor = self.parent
448        while ancestor and not isinstance(ancestor, expression_types):
449            ancestor = ancestor.parent
450        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

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

The parent node.

parent_select: Optional[Select]
452    @property
453    def parent_select(self) -> t.Optional[Select]:
454        """
455        Returns the parent select statement.
456        """
457        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
459    @property
460    def same_parent(self) -> bool:
461        """Returns if the parent is the same class as itself."""
462        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
464    def root(self) -> Expression:
465        """
466        Returns the root expression of this tree.
467        """
468        expression = self
469        while expression.parent:
470            expression = expression.parent
471        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
473    def walk(
474        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
475    ) -> t.Iterator[Expression]:
476        """
477        Returns a generator object which visits all nodes in this tree.
478
479        Args:
480            bfs: if set to True the BFS traversal order will be applied,
481                otherwise the DFS traversal will be used instead.
482            prune: callable that returns True if the generator should stop traversing
483                this branch of the tree.
484
485        Returns:
486            the generator object.
487        """
488        if bfs:
489            yield from self.bfs(prune=prune)
490        else:
491            yield from self.dfs(prune=prune)

Returns a generator object which visits all nodes in this tree.

Arguments:
  • bfs: if set to True the BFS traversal order will be applied, otherwise the DFS traversal will be used instead.
  • prune: callable that returns True if the generator should stop traversing this branch of the tree.
Returns:

the generator object.

def dfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
493    def dfs(
494        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
495    ) -> t.Iterator[Expression]:
496        """
497        Returns a generator object which visits all nodes in this tree in
498        the DFS (Depth-first) order.
499
500        Returns:
501            The generator object.
502        """
503        stack = [self]
504
505        while stack:
506            node = stack.pop()
507
508            yield node
509
510            if prune and prune(node):
511                continue
512
513            for v in node.iter_expressions(reverse=True):
514                stack.append(v)

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: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
516    def bfs(
517        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
518    ) -> t.Iterator[Expression]:
519        """
520        Returns a generator object which visits all nodes in this tree in
521        the BFS (Breadth-first) order.
522
523        Returns:
524            The generator object.
525        """
526        queue = deque([self])
527
528        while queue:
529            node = queue.popleft()
530
531            yield node
532
533            if prune and prune(node):
534                continue
535
536            for v in node.iter_expressions():
537                queue.append(v)

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

Returns:

The generator object.

def unnest(self):
539    def unnest(self):
540        """
541        Returns the first non parenthesis child or self.
542        """
543        expression = self
544        while type(expression) is Paren:
545            expression = expression.this
546        return expression

Returns the first non parenthesis child or self.

def unalias(self):
548    def unalias(self):
549        """
550        Returns the inner expression if this is an Alias.
551        """
552        if isinstance(self, Alias):
553            return self.this
554        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
556    def unnest_operands(self):
557        """
558        Returns unnested operands as a tuple.
559        """
560        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
562    def flatten(self, unnest=True):
563        """
564        Returns a generator which yields child nodes whose parents are the same class.
565
566        A AND B AND C -> [A, B, C]
567        """
568        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
569            if type(node) is not self.__class__:
570                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:
578    def to_s(self) -> str:
579        """
580        Same as __repr__, but includes additional information which can be useful
581        for debugging, like empty or missing args and the AST nodes' object IDs.
582        """
583        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:
585    def sql(self, dialect: DialectType = None, **opts) -> str:
586        """
587        Returns SQL string representation of this tree.
588
589        Args:
590            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
591            opts: other `sqlglot.generator.Generator` options.
592
593        Returns:
594            The SQL string.
595        """
596        from sqlglot.dialects import Dialect
597
598        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: Callable, *args: Any, copy: bool = True, **kwargs) -> Expression:
600    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
601        """
602        Visits all tree nodes (excluding already transformed ones)
603        and applies the given transformation function to each node.
604
605        Args:
606            fun: a function which takes a node as an argument and returns a
607                new transformed node or the same node without modifications. If the function
608                returns None, then the corresponding node will be removed from the syntax tree.
609            copy: if set to True a new tree instance is constructed, otherwise the tree is
610                modified in place.
611
612        Returns:
613            The transformed tree.
614        """
615        root = None
616        new_node = None
617
618        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
619            parent, arg_key, index = node.parent, node.arg_key, node.index
620            new_node = fun(node, *args, **kwargs)
621
622            if not root:
623                root = new_node
624            elif new_node is not node:
625                parent.set(arg_key, new_node, index)
626
627        assert root
628        return root.assert_is(Expression)

Visits all tree nodes (excluding already transformed ones) and applies the given transformation function to each node.

Arguments:
  • fun: 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: 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):
636    def replace(self, expression):
637        """
638        Swap out this expression with a new expression.
639
640        For example::
641
642            >>> tree = Select().select("x").from_("tbl")
643            >>> tree.find(Column).replace(column("y"))
644            Column(
645              this=Identifier(this=y, quoted=False))
646            >>> tree.sql()
647            'SELECT y FROM tbl'
648
649        Args:
650            expression: new node
651
652        Returns:
653            The new expression or expressions.
654        """
655        parent = self.parent
656
657        if not parent or parent is expression:
658            return expression
659
660        key = self.arg_key
661        value = parent.args.get(key)
662
663        if type(expression) is list and isinstance(value, Expression):
664            # We are trying to replace an Expression with a list, so it's assumed that
665            # the intention was to really replace the parent of this expression.
666            value.parent.replace(expression)
667        else:
668            parent.set(key, expression, self.index)
669
670        if expression is not self:
671            self.parent = None
672            self.arg_key = None
673            self.index = None
674
675        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:
677    def pop(self: E) -> E:
678        """
679        Remove this expression from its AST.
680
681        Returns:
682            The popped expression.
683        """
684        self.replace(None)
685        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
687    def assert_is(self, type_: t.Type[E]) -> E:
688        """
689        Assert that this `Expression` is an instance of `type_`.
690
691        If it is NOT an instance of `type_`, this raises an assertion error.
692        Otherwise, this returns this expression.
693
694        Examples:
695            This is useful for type security in chained expressions:
696
697            >>> import sqlglot
698            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
699            'SELECT x, z FROM y'
700        """
701        if not isinstance(self, type_):
702            raise AssertionError(f"{self} is not {type_}.")
703        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]:
705    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
706        """
707        Checks if this expression is valid (e.g. all mandatory args are set).
708
709        Args:
710            args: a sequence of values that were used to instantiate a Func expression. This is used
711                to check that the provided arguments don't exceed the function argument limit.
712
713        Returns:
714            A list of error messages for all possible errors that were found.
715        """
716        errors: t.List[str] = []
717
718        for k in self.args:
719            if k not in self.arg_types:
720                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
721        for k, mandatory in self.arg_types.items():
722            v = self.args.get(k)
723            if mandatory and (v is None or (isinstance(v, list) and not v)):
724                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
725
726        if (
727            args
728            and isinstance(self, Func)
729            and len(args) > len(self.arg_types)
730            and not self.is_var_len_args
731        ):
732            errors.append(
733                f"The number of provided arguments ({len(args)}) is greater than "
734                f"the maximum number of supported arguments ({len(self.arg_types)})"
735            )
736
737        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):
739    def dump(self):
740        """
741        Dump this Expression to a JSON-serializable dict.
742        """
743        from sqlglot.serde import dump
744
745        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
747    @classmethod
748    def load(cls, obj):
749        """
750        Load a dict (as returned by `Expression.dump`) into an Expression instance.
751        """
752        from sqlglot.serde import load
753
754        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:
756    def and_(
757        self,
758        *expressions: t.Optional[ExpOrStr],
759        dialect: DialectType = None,
760        copy: bool = True,
761        **opts,
762    ) -> Condition:
763        """
764        AND this condition with one or multiple expressions.
765
766        Example:
767            >>> condition("x=1").and_("y=1").sql()
768            'x = 1 AND y = 1'
769
770        Args:
771            *expressions: the SQL code strings to parse.
772                If an `Expression` instance is passed, it will be used as-is.
773            dialect: the dialect used to parse the input expression.
774            copy: whether to copy the involved expressions (only applies to Expressions).
775            opts: other options to use to parse the input expressions.
776
777        Returns:
778            The new And condition.
779        """
780        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 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:
782    def or_(
783        self,
784        *expressions: t.Optional[ExpOrStr],
785        dialect: DialectType = None,
786        copy: bool = True,
787        **opts,
788    ) -> Condition:
789        """
790        OR this condition with one or multiple expressions.
791
792        Example:
793            >>> condition("x=1").or_("y=1").sql()
794            'x = 1 OR y = 1'
795
796        Args:
797            *expressions: the SQL code strings to parse.
798                If an `Expression` instance is passed, it will be used as-is.
799            dialect: the dialect used to parse the input expression.
800            copy: whether to copy the involved expressions (only applies to Expressions).
801            opts: other options to use to parse the input expressions.
802
803        Returns:
804            The new Or condition.
805        """
806        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 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):
808    def not_(self, copy: bool = True):
809        """
810        Wrap this condition with NOT.
811
812        Example:
813            >>> condition("x=1").not_().sql()
814            'NOT x = 1'
815
816        Args:
817            copy: whether to copy this object.
818
819        Returns:
820            The new Not instance.
821        """
822        return not_(self, copy=copy)

Wrap this condition with NOT.

Example:
>>> condition("x=1").not_().sql()
'NOT x = 1'
Arguments:
  • copy: whether 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:
824    def as_(
825        self,
826        alias: str | Identifier,
827        quoted: t.Optional[bool] = None,
828        dialect: DialectType = None,
829        copy: bool = True,
830        **opts,
831    ) -> Alias:
832        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:
857    def isin(
858        self,
859        *expressions: t.Any,
860        query: t.Optional[ExpOrStr] = None,
861        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
862        copy: bool = True,
863        **opts,
864    ) -> In:
865        subquery = maybe_parse(query, copy=copy, **opts) if query else None
866        if subquery and not isinstance(subquery, Subquery):
867            subquery = subquery.subquery(copy=False)
868
869        return In(
870            this=maybe_copy(self, copy),
871            expressions=[convert(e, copy=copy) for e in expressions],
872            query=subquery,
873            unnest=(
874                Unnest(
875                    expressions=[
876                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
877                        for e in ensure_list(unnest)
878                    ]
879                )
880                if unnest
881                else None
882            ),
883        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
885    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
886        return Between(
887            this=maybe_copy(self, copy),
888            low=convert(low, copy=copy, **opts),
889            high=convert(high, copy=copy, **opts),
890        )
def is_( self, other: Union[str, Expression]) -> Is:
892    def is_(self, other: ExpOrStr) -> Is:
893        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
895    def like(self, other: ExpOrStr) -> Like:
896        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
898    def ilike(self, other: ExpOrStr) -> ILike:
899        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
901    def eq(self, other: t.Any) -> EQ:
902        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
904    def neq(self, other: t.Any) -> NEQ:
905        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
907    def rlike(self, other: ExpOrStr) -> RegexpLike:
908        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
910    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
911        div = self._binop(Div, other)
912        div.args["typed"] = typed
913        div.args["safe"] = safe
914        return div
def asc(self, nulls_first: bool = True) -> Ordered:
916    def asc(self, nulls_first: bool = True) -> Ordered:
917        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
919    def desc(self, nulls_first: bool = False) -> Ordered:
920        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):
1003class Condition(Expression):
1004    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
1011class DerivedTable(Expression):
1012    @property
1013    def selects(self) -> t.List[Expression]:
1014        return self.this.selects if isinstance(self.this, Query) else []
1015
1016    @property
1017    def named_selects(self) -> t.List[str]:
1018        return [select.output_name for select in self.selects]
selects: List[Expression]
1012    @property
1013    def selects(self) -> t.List[Expression]:
1014        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
1016    @property
1017    def named_selects(self) -> t.List[str]:
1018        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
1021class Query(Expression):
1022    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1023        """
1024        Returns a `Subquery` that wraps around this query.
1025
1026        Example:
1027            >>> subquery = Select().select("x").from_("tbl").subquery()
1028            >>> Select().select("x").from_(subquery).sql()
1029            'SELECT x FROM (SELECT x FROM tbl)'
1030
1031        Args:
1032            alias: an optional alias for the subquery.
1033            copy: if `False`, modify this expression instance in-place.
1034        """
1035        instance = maybe_copy(self, copy)
1036        if not isinstance(alias, Expression):
1037            alias = TableAlias(this=to_identifier(alias)) if alias else None
1038
1039        return Subquery(this=instance, alias=alias)
1040
1041    def limit(
1042        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1043    ) -> Q:
1044        """
1045        Adds a LIMIT clause to this query.
1046
1047        Example:
1048            >>> select("1").union(select("1")).limit(1).sql()
1049            'SELECT 1 UNION SELECT 1 LIMIT 1'
1050
1051        Args:
1052            expression: the SQL code string to parse.
1053                This can also be an integer.
1054                If a `Limit` instance is passed, it will be used as-is.
1055                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1056            dialect: the dialect used to parse the input expression.
1057            copy: if `False`, modify this expression instance in-place.
1058            opts: other options to use to parse the input expressions.
1059
1060        Returns:
1061            A limited Select expression.
1062        """
1063        return _apply_builder(
1064            expression=expression,
1065            instance=self,
1066            arg="limit",
1067            into=Limit,
1068            prefix="LIMIT",
1069            dialect=dialect,
1070            copy=copy,
1071            into_arg="expression",
1072            **opts,
1073        )
1074
1075    def offset(
1076        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1077    ) -> Q:
1078        """
1079        Set the OFFSET expression.
1080
1081        Example:
1082            >>> Select().from_("tbl").select("x").offset(10).sql()
1083            'SELECT x FROM tbl OFFSET 10'
1084
1085        Args:
1086            expression: the SQL code string to parse.
1087                This can also be an integer.
1088                If a `Offset` instance is passed, this is used as-is.
1089                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1090            dialect: the dialect used to parse the input expression.
1091            copy: if `False`, modify this expression instance in-place.
1092            opts: other options to use to parse the input expressions.
1093
1094        Returns:
1095            The modified Select expression.
1096        """
1097        return _apply_builder(
1098            expression=expression,
1099            instance=self,
1100            arg="offset",
1101            into=Offset,
1102            prefix="OFFSET",
1103            dialect=dialect,
1104            copy=copy,
1105            into_arg="expression",
1106            **opts,
1107        )
1108
1109    def order_by(
1110        self: Q,
1111        *expressions: t.Optional[ExpOrStr],
1112        append: bool = True,
1113        dialect: DialectType = None,
1114        copy: bool = True,
1115        **opts,
1116    ) -> Q:
1117        """
1118        Set the ORDER BY expression.
1119
1120        Example:
1121            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1122            'SELECT x FROM tbl ORDER BY x DESC'
1123
1124        Args:
1125            *expressions: the SQL code strings to parse.
1126                If a `Group` instance is passed, this is used as-is.
1127                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1128            append: if `True`, add to any existing expressions.
1129                Otherwise, this flattens all the `Order` expression into a single expression.
1130            dialect: the dialect used to parse the input expression.
1131            copy: if `False`, modify this expression instance in-place.
1132            opts: other options to use to parse the input expressions.
1133
1134        Returns:
1135            The modified Select expression.
1136        """
1137        return _apply_child_list_builder(
1138            *expressions,
1139            instance=self,
1140            arg="order",
1141            append=append,
1142            copy=copy,
1143            prefix="ORDER BY",
1144            into=Order,
1145            dialect=dialect,
1146            **opts,
1147        )
1148
1149    @property
1150    def ctes(self) -> t.List[CTE]:
1151        """Returns a list of all the CTEs attached to this query."""
1152        with_ = self.args.get("with")
1153        return with_.expressions if with_ else []
1154
1155    @property
1156    def selects(self) -> t.List[Expression]:
1157        """Returns the query's projections."""
1158        raise NotImplementedError("Query objects must implement `selects`")
1159
1160    @property
1161    def named_selects(self) -> t.List[str]:
1162        """Returns the output names of the query's projections."""
1163        raise NotImplementedError("Query objects must implement `named_selects`")
1164
1165    def select(
1166        self: Q,
1167        *expressions: t.Optional[ExpOrStr],
1168        append: bool = True,
1169        dialect: DialectType = None,
1170        copy: bool = True,
1171        **opts,
1172    ) -> Q:
1173        """
1174        Append to or set the SELECT expressions.
1175
1176        Example:
1177            >>> Select().select("x", "y").sql()
1178            'SELECT x, y'
1179
1180        Args:
1181            *expressions: the SQL code strings to parse.
1182                If an `Expression` instance is passed, it will be used as-is.
1183            append: if `True`, add to any existing expressions.
1184                Otherwise, this resets the expressions.
1185            dialect: the dialect used to parse the input expressions.
1186            copy: if `False`, modify this expression instance in-place.
1187            opts: other options to use to parse the input expressions.
1188
1189        Returns:
1190            The modified Query expression.
1191        """
1192        raise NotImplementedError("Query objects must implement `select`")
1193
1194    def with_(
1195        self: Q,
1196        alias: ExpOrStr,
1197        as_: ExpOrStr,
1198        recursive: t.Optional[bool] = None,
1199        append: bool = True,
1200        dialect: DialectType = None,
1201        copy: bool = True,
1202        **opts,
1203    ) -> Q:
1204        """
1205        Append to or set the common table expressions.
1206
1207        Example:
1208            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1209            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1210
1211        Args:
1212            alias: the SQL code string to parse as the table name.
1213                If an `Expression` instance is passed, this is used as-is.
1214            as_: the SQL code string to parse as the table expression.
1215                If an `Expression` instance is passed, it will be used as-is.
1216            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1217            append: if `True`, add to any existing expressions.
1218                Otherwise, this resets the expressions.
1219            dialect: the dialect used to parse the input expression.
1220            copy: if `False`, modify this expression instance in-place.
1221            opts: other options to use to parse the input expressions.
1222
1223        Returns:
1224            The modified expression.
1225        """
1226        return _apply_cte_builder(
1227            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1228        )
1229
1230    def union(
1231        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1232    ) -> Union:
1233        """
1234        Builds a UNION expression.
1235
1236        Example:
1237            >>> import sqlglot
1238            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1239            'SELECT * FROM foo UNION SELECT * FROM bla'
1240
1241        Args:
1242            expression: the SQL code string.
1243                If an `Expression` instance is passed, it will be used as-is.
1244            distinct: set the DISTINCT flag if and only if this is true.
1245            dialect: the dialect used to parse the input expression.
1246            opts: other options to use to parse the input expressions.
1247
1248        Returns:
1249            The new Union expression.
1250        """
1251        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1252
1253    def intersect(
1254        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1255    ) -> Intersect:
1256        """
1257        Builds an INTERSECT expression.
1258
1259        Example:
1260            >>> import sqlglot
1261            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1262            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1263
1264        Args:
1265            expression: the SQL code string.
1266                If an `Expression` instance is passed, it will be used as-is.
1267            distinct: set the DISTINCT flag if and only if this is true.
1268            dialect: the dialect used to parse the input expression.
1269            opts: other options to use to parse the input expressions.
1270
1271        Returns:
1272            The new Intersect expression.
1273        """
1274        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
1275
1276    def except_(
1277        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1278    ) -> Except:
1279        """
1280        Builds an EXCEPT expression.
1281
1282        Example:
1283            >>> import sqlglot
1284            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1285            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1286
1287        Args:
1288            expression: the SQL code string.
1289                If an `Expression` instance is passed, it will be used as-is.
1290            distinct: set the DISTINCT flag if and only if this is true.
1291            dialect: the dialect used to parse the input expression.
1292            opts: other options to use to parse the input expressions.
1293
1294        Returns:
1295            The new Except expression.
1296        """
1297        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
1022    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1023        """
1024        Returns a `Subquery` that wraps around this query.
1025
1026        Example:
1027            >>> subquery = Select().select("x").from_("tbl").subquery()
1028            >>> Select().select("x").from_(subquery).sql()
1029            'SELECT x FROM (SELECT x FROM tbl)'
1030
1031        Args:
1032            alias: an optional alias for the subquery.
1033            copy: if `False`, modify this expression instance in-place.
1034        """
1035        instance = maybe_copy(self, copy)
1036        if not isinstance(alias, Expression):
1037            alias = TableAlias(this=to_identifier(alias)) if alias else None
1038
1039        return Subquery(this=instance, alias=alias)

Returns a Subquery that wraps around this query.

Example:
>>> subquery = Select().select("x").from_("tbl").subquery()
>>> Select().select("x").from_(subquery).sql()
'SELECT x FROM (SELECT x FROM tbl)'
Arguments:
  • alias: an optional alias for the subquery.
  • copy: if False, modify this expression instance in-place.
def limit( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1041    def limit(
1042        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1043    ) -> Q:
1044        """
1045        Adds a LIMIT clause to this query.
1046
1047        Example:
1048            >>> select("1").union(select("1")).limit(1).sql()
1049            'SELECT 1 UNION SELECT 1 LIMIT 1'
1050
1051        Args:
1052            expression: the SQL code string to parse.
1053                This can also be an integer.
1054                If a `Limit` instance is passed, it will be used as-is.
1055                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1056            dialect: the dialect used to parse the input expression.
1057            copy: if `False`, modify this expression instance in-place.
1058            opts: other options to use to parse the input expressions.
1059
1060        Returns:
1061            A limited Select expression.
1062        """
1063        return _apply_builder(
1064            expression=expression,
1065            instance=self,
1066            arg="limit",
1067            into=Limit,
1068            prefix="LIMIT",
1069            dialect=dialect,
1070            copy=copy,
1071            into_arg="expression",
1072            **opts,
1073        )

Adds a LIMIT clause to this query.

Example:
>>> select("1").union(select("1")).limit(1).sql()
'SELECT 1 UNION SELECT 1 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, it will be 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:

A limited Select expression.

def offset( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1075    def offset(
1076        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1077    ) -> Q:
1078        """
1079        Set the OFFSET expression.
1080
1081        Example:
1082            >>> Select().from_("tbl").select("x").offset(10).sql()
1083            'SELECT x FROM tbl OFFSET 10'
1084
1085        Args:
1086            expression: the SQL code string to parse.
1087                This can also be an integer.
1088                If a `Offset` instance is passed, this is used as-is.
1089                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1090            dialect: the dialect used to parse the input expression.
1091            copy: if `False`, modify this expression instance in-place.
1092            opts: other options to use to parse the input expressions.
1093
1094        Returns:
1095            The modified Select expression.
1096        """
1097        return _apply_builder(
1098            expression=expression,
1099            instance=self,
1100            arg="offset",
1101            into=Offset,
1102            prefix="OFFSET",
1103            dialect=dialect,
1104            copy=copy,
1105            into_arg="expression",
1106            **opts,
1107        )

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 order_by( self: ~Q, *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) -> ~Q:
1109    def order_by(
1110        self: Q,
1111        *expressions: t.Optional[ExpOrStr],
1112        append: bool = True,
1113        dialect: DialectType = None,
1114        copy: bool = True,
1115        **opts,
1116    ) -> Q:
1117        """
1118        Set the ORDER BY expression.
1119
1120        Example:
1121            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1122            'SELECT x FROM tbl ORDER BY x DESC'
1123
1124        Args:
1125            *expressions: the SQL code strings to parse.
1126                If a `Group` instance is passed, this is used as-is.
1127                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1128            append: if `True`, add to any existing expressions.
1129                Otherwise, this flattens all the `Order` expression into a single expression.
1130            dialect: the dialect used to parse the input expression.
1131            copy: if `False`, modify this expression instance in-place.
1132            opts: other options to use to parse the input expressions.
1133
1134        Returns:
1135            The modified Select expression.
1136        """
1137        return _apply_child_list_builder(
1138            *expressions,
1139            instance=self,
1140            arg="order",
1141            append=append,
1142            copy=copy,
1143            prefix="ORDER BY",
1144            into=Order,
1145            dialect=dialect,
1146            **opts,
1147        )

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.

ctes: List[CTE]
1149    @property
1150    def ctes(self) -> t.List[CTE]:
1151        """Returns a list of all the CTEs attached to this query."""
1152        with_ = self.args.get("with")
1153        return with_.expressions if with_ else []

Returns a list of all the CTEs attached to this query.

selects: List[Expression]
1155    @property
1156    def selects(self) -> t.List[Expression]:
1157        """Returns the query's projections."""
1158        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1160    @property
1161    def named_selects(self) -> t.List[str]:
1162        """Returns the output names of the query's projections."""
1163        raise NotImplementedError("Query objects must implement `named_selects`")

Returns the output names of the query's projections.

def select( self: ~Q, *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) -> ~Q:
1165    def select(
1166        self: Q,
1167        *expressions: t.Optional[ExpOrStr],
1168        append: bool = True,
1169        dialect: DialectType = None,
1170        copy: bool = True,
1171        **opts,
1172    ) -> Q:
1173        """
1174        Append to or set the SELECT expressions.
1175
1176        Example:
1177            >>> Select().select("x", "y").sql()
1178            'SELECT x, y'
1179
1180        Args:
1181            *expressions: the SQL code strings to parse.
1182                If an `Expression` instance is passed, it will be used as-is.
1183            append: if `True`, add to any existing expressions.
1184                Otherwise, this resets the expressions.
1185            dialect: the dialect used to parse the input expressions.
1186            copy: if `False`, modify this expression instance in-place.
1187            opts: other options to use to parse the input expressions.
1188
1189        Returns:
1190            The modified Query expression.
1191        """
1192        raise NotImplementedError("Query objects must implement `select`")

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 Query expression.

def with_( self: ~Q, 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) -> ~Q:
1194    def with_(
1195        self: Q,
1196        alias: ExpOrStr,
1197        as_: ExpOrStr,
1198        recursive: t.Optional[bool] = None,
1199        append: bool = True,
1200        dialect: DialectType = None,
1201        copy: bool = True,
1202        **opts,
1203    ) -> Q:
1204        """
1205        Append to or set the common table expressions.
1206
1207        Example:
1208            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1209            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1210
1211        Args:
1212            alias: the SQL code string to parse as the table name.
1213                If an `Expression` instance is passed, this is used as-is.
1214            as_: the SQL code string to parse as the table expression.
1215                If an `Expression` instance is passed, it will be used as-is.
1216            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1217            append: if `True`, add to any existing expressions.
1218                Otherwise, this resets the expressions.
1219            dialect: the dialect used to parse the input expression.
1220            copy: if `False`, modify this expression instance in-place.
1221            opts: other options to use to parse the input expressions.
1222
1223        Returns:
1224            The modified expression.
1225        """
1226        return _apply_cte_builder(
1227            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
1228        )

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.

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) -> Union:
1230    def union(
1231        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1232    ) -> Union:
1233        """
1234        Builds a UNION expression.
1235
1236        Example:
1237            >>> import sqlglot
1238            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1239            'SELECT * FROM foo UNION SELECT * FROM bla'
1240
1241        Args:
1242            expression: the SQL code string.
1243                If an `Expression` instance is passed, it will be used as-is.
1244            distinct: set the DISTINCT flag if and only if this is true.
1245            dialect: the dialect used to parse the input expression.
1246            opts: other options to use to parse the input expressions.
1247
1248        Returns:
1249            The new Union expression.
1250        """
1251        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) -> Intersect:
1253    def intersect(
1254        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1255    ) -> Intersect:
1256        """
1257        Builds an INTERSECT expression.
1258
1259        Example:
1260            >>> import sqlglot
1261            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1262            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1263
1264        Args:
1265            expression: the SQL code string.
1266                If an `Expression` instance is passed, it will be used as-is.
1267            distinct: set the DISTINCT flag if and only if this is true.
1268            dialect: the dialect used to parse the input expression.
1269            opts: other options to use to parse the input expressions.
1270
1271        Returns:
1272            The new Intersect expression.
1273        """
1274        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) -> Except:
1276    def except_(
1277        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1278    ) -> Except:
1279        """
1280        Builds an EXCEPT expression.
1281
1282        Example:
1283            >>> import sqlglot
1284            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1285            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1286
1287        Args:
1288            expression: the SQL code string.
1289                If an `Expression` instance is passed, it will be used as-is.
1290            distinct: set the DISTINCT flag if and only if this is true.
1291            dialect: the dialect used to parse the input expression.
1292            opts: other options to use to parse the input expressions.
1293
1294        Returns:
1295            The new Except expression.
1296        """
1297        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 = 'query'
class UDTF(DerivedTable):
1300class UDTF(DerivedTable):
1301    @property
1302    def selects(self) -> t.List[Expression]:
1303        alias = self.args.get("alias")
1304        return alias.columns if alias else []
selects: List[Expression]
1301    @property
1302    def selects(self) -> t.List[Expression]:
1303        alias = self.args.get("alias")
1304        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1307class Cache(Expression):
1308    arg_types = {
1309        "this": True,
1310        "lazy": False,
1311        "options": False,
1312        "expression": False,
1313    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1316class Uncache(Expression):
1317    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1320class Refresh(Expression):
1321    pass
key = 'refresh'
class DDL(Expression):
1324class DDL(Expression):
1325    @property
1326    def ctes(self) -> t.List[CTE]:
1327        """Returns a list of all the CTEs attached to this statement."""
1328        with_ = self.args.get("with")
1329        return with_.expressions if with_ else []
1330
1331    @property
1332    def selects(self) -> t.List[Expression]:
1333        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1334        return self.expression.selects if isinstance(self.expression, Query) else []
1335
1336    @property
1337    def named_selects(self) -> t.List[str]:
1338        """
1339        If this statement contains a query (e.g. a CTAS), this returns the output
1340        names of the query's projections.
1341        """
1342        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1325    @property
1326    def ctes(self) -> t.List[CTE]:
1327        """Returns a list of all the CTEs attached to this statement."""
1328        with_ = self.args.get("with")
1329        return with_.expressions if with_ else []

Returns a list of all the CTEs attached to this statement.

selects: List[Expression]
1331    @property
1332    def selects(self) -> t.List[Expression]:
1333        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1334        return self.expression.selects if isinstance(self.expression, Query) else []

If this statement contains a query (e.g. a CTAS), this returns the query's projections.

named_selects: List[str]
1336    @property
1337    def named_selects(self) -> t.List[str]:
1338        """
1339        If this statement contains a query (e.g. a CTAS), this returns the output
1340        names of the query's projections.
1341        """
1342        return self.expression.named_selects if isinstance(self.expression, Query) else []

If this statement contains a query (e.g. a CTAS), this returns the output names of the query's projections.

key = 'ddl'
class DML(Expression):
1345class DML(Expression):
1346    def returning(
1347        self,
1348        expression: ExpOrStr,
1349        dialect: DialectType = None,
1350        copy: bool = True,
1351        **opts,
1352    ) -> DML:
1353        """
1354        Set the RETURNING expression. Not supported by all dialects.
1355
1356        Example:
1357            >>> delete("tbl").returning("*", dialect="postgres").sql()
1358            'DELETE FROM tbl RETURNING *'
1359
1360        Args:
1361            expression: the SQL code strings to parse.
1362                If an `Expression` instance is passed, it will be used as-is.
1363            dialect: the dialect used to parse the input expressions.
1364            copy: if `False`, modify this expression instance in-place.
1365            opts: other options to use to parse the input expressions.
1366
1367        Returns:
1368            Delete: the modified expression.
1369        """
1370        return _apply_builder(
1371            expression=expression,
1372            instance=self,
1373            arg="returning",
1374            prefix="RETURNING",
1375            dialect=dialect,
1376            copy=copy,
1377            into=Returning,
1378            **opts,
1379        )
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:
1346    def returning(
1347        self,
1348        expression: ExpOrStr,
1349        dialect: DialectType = None,
1350        copy: bool = True,
1351        **opts,
1352    ) -> DML:
1353        """
1354        Set the RETURNING expression. Not supported by all dialects.
1355
1356        Example:
1357            >>> delete("tbl").returning("*", dialect="postgres").sql()
1358            'DELETE FROM tbl RETURNING *'
1359
1360        Args:
1361            expression: the SQL code strings to parse.
1362                If an `Expression` instance is passed, it will be used as-is.
1363            dialect: the dialect used to parse the input expressions.
1364            copy: if `False`, modify this expression instance in-place.
1365            opts: other options to use to parse the input expressions.
1366
1367        Returns:
1368            Delete: the modified expression.
1369        """
1370        return _apply_builder(
1371            expression=expression,
1372            instance=self,
1373            arg="returning",
1374            prefix="RETURNING",
1375            dialect=dialect,
1376            copy=copy,
1377            into=Returning,
1378            **opts,
1379        )

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):
1382class Create(DDL):
1383    arg_types = {
1384        "with": False,
1385        "this": True,
1386        "kind": True,
1387        "expression": False,
1388        "exists": False,
1389        "properties": False,
1390        "replace": False,
1391        "unique": False,
1392        "indexes": False,
1393        "no_schema_binding": False,
1394        "begin": False,
1395        "end": False,
1396        "clone": False,
1397    }
1398
1399    @property
1400    def kind(self) -> t.Optional[str]:
1401        kind = self.args.get("kind")
1402        return kind and kind.upper()
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}
kind: Optional[str]
1399    @property
1400    def kind(self) -> t.Optional[str]:
1401        kind = self.args.get("kind")
1402        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1405class SequenceProperties(Expression):
1406    arg_types = {
1407        "increment": False,
1408        "minvalue": False,
1409        "maxvalue": False,
1410        "cache": False,
1411        "start": False,
1412        "owned": False,
1413        "options": False,
1414    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1417class TruncateTable(Expression):
1418    arg_types = {
1419        "expressions": True,
1420        "is_database": False,
1421        "exists": False,
1422        "only": False,
1423        "cluster": False,
1424        "identity": False,
1425        "option": False,
1426        "partition": False,
1427    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1433class Clone(Expression):
1434    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1437class Describe(Expression):
1438    arg_types = {"this": True, "style": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1441class Kill(Expression):
1442    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1445class Pragma(Expression):
1446    pass
key = 'pragma'
class Declare(Expression):
1449class Declare(Expression):
1450    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1453class DeclareItem(Expression):
1454    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1457class Set(Expression):
1458    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1461class Heredoc(Expression):
1462    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1465class SetItem(Expression):
1466    arg_types = {
1467        "this": False,
1468        "expressions": False,
1469        "kind": False,
1470        "collate": False,  # MySQL SET NAMES statement
1471        "global": False,
1472    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1475class Show(Expression):
1476    arg_types = {
1477        "this": True,
1478        "history": False,
1479        "terse": False,
1480        "target": False,
1481        "offset": False,
1482        "starts_with": False,
1483        "limit": False,
1484        "from": False,
1485        "like": False,
1486        "where": False,
1487        "db": False,
1488        "scope": False,
1489        "scope_kind": False,
1490        "full": False,
1491        "mutex": False,
1492        "query": False,
1493        "channel": False,
1494        "global": False,
1495        "log": False,
1496        "position": False,
1497        "types": False,
1498    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': 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):
1501class UserDefinedFunction(Expression):
1502    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1505class CharacterSet(Expression):
1506    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1509class With(Expression):
1510    arg_types = {"expressions": True, "recursive": False}
1511
1512    @property
1513    def recursive(self) -> bool:
1514        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1512    @property
1513    def recursive(self) -> bool:
1514        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1517class WithinGroup(Expression):
1518    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1523class CTE(DerivedTable):
1524    arg_types = {
1525        "this": True,
1526        "alias": True,
1527        "scalar": False,
1528        "materialized": False,
1529    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1532class ProjectionDef(Expression):
1533    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1536class TableAlias(Expression):
1537    arg_types = {"this": False, "columns": False}
1538
1539    @property
1540    def columns(self):
1541        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1539    @property
1540    def columns(self):
1541        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1544class BitString(Condition):
1545    pass
key = 'bitstring'
class HexString(Condition):
1548class HexString(Condition):
1549    pass
key = 'hexstring'
class ByteString(Condition):
1552class ByteString(Condition):
1553    pass
key = 'bytestring'
class RawString(Condition):
1556class RawString(Condition):
1557    pass
key = 'rawstring'
class UnicodeString(Condition):
1560class UnicodeString(Condition):
1561    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1564class Column(Condition):
1565    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1566
1567    @property
1568    def table(self) -> str:
1569        return self.text("table")
1570
1571    @property
1572    def db(self) -> str:
1573        return self.text("db")
1574
1575    @property
1576    def catalog(self) -> str:
1577        return self.text("catalog")
1578
1579    @property
1580    def output_name(self) -> str:
1581        return self.name
1582
1583    @property
1584    def parts(self) -> t.List[Identifier]:
1585        """Return the parts of a column in order catalog, db, table, name."""
1586        return [
1587            t.cast(Identifier, self.args[part])
1588            for part in ("catalog", "db", "table", "this")
1589            if self.args.get(part)
1590        ]
1591
1592    def to_dot(self) -> Dot | Identifier:
1593        """Converts the column into a dot expression."""
1594        parts = self.parts
1595        parent = self.parent
1596
1597        while parent:
1598            if isinstance(parent, Dot):
1599                parts.append(parent.expression)
1600            parent = parent.parent
1601
1602        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
1567    @property
1568    def table(self) -> str:
1569        return self.text("table")
db: str
1571    @property
1572    def db(self) -> str:
1573        return self.text("db")
catalog: str
1575    @property
1576    def catalog(self) -> str:
1577        return self.text("catalog")
output_name: str
1579    @property
1580    def output_name(self) -> str:
1581        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]
1583    @property
1584    def parts(self) -> t.List[Identifier]:
1585        """Return the parts of a column in order catalog, db, table, name."""
1586        return [
1587            t.cast(Identifier, self.args[part])
1588            for part in ("catalog", "db", "table", "this")
1589            if self.args.get(part)
1590        ]

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

def to_dot(self) -> Dot | Identifier:
1592    def to_dot(self) -> Dot | Identifier:
1593        """Converts the column into a dot expression."""
1594        parts = self.parts
1595        parent = self.parent
1596
1597        while parent:
1598            if isinstance(parent, Dot):
1599                parts.append(parent.expression)
1600            parent = parent.parent
1601
1602        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1605class ColumnPosition(Expression):
1606    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1609class ColumnDef(Expression):
1610    arg_types = {
1611        "this": True,
1612        "kind": False,
1613        "constraints": False,
1614        "exists": False,
1615        "position": False,
1616    }
1617
1618    @property
1619    def constraints(self) -> t.List[ColumnConstraint]:
1620        return self.args.get("constraints") or []
1621
1622    @property
1623    def kind(self) -> t.Optional[DataType]:
1624        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1618    @property
1619    def constraints(self) -> t.List[ColumnConstraint]:
1620        return self.args.get("constraints") or []
kind: Optional[DataType]
1622    @property
1623    def kind(self) -> t.Optional[DataType]:
1624        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1627class AlterColumn(Expression):
1628    arg_types = {
1629        "this": True,
1630        "dtype": False,
1631        "collate": False,
1632        "using": False,
1633        "default": False,
1634        "drop": False,
1635        "comment": False,
1636        "allow_null": False,
1637    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1641class AlterDistStyle(Expression):
1642    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1645class AlterSortKey(Expression):
1646    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1649class AlterSet(Expression):
1650    arg_types = {
1651        "expressions": False,
1652        "option": False,
1653        "tablespace": False,
1654        "access_method": False,
1655        "file_format": False,
1656        "copy_options": False,
1657        "tag": False,
1658        "location": False,
1659        "serde": False,
1660    }
arg_types = {'expressions': False, 'option': False, 'tablespace': False, 'access_method': False, 'file_format': False, 'copy_options': False, 'tag': False, 'location': False, 'serde': False}
key = 'alterset'
class RenameColumn(Expression):
1663class RenameColumn(Expression):
1664    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1667class RenameTable(Expression):
1668    pass
key = 'renametable'
class SwapTable(Expression):
1671class SwapTable(Expression):
1672    pass
key = 'swaptable'
class Comment(Expression):
1675class Comment(Expression):
1676    arg_types = {
1677        "this": True,
1678        "kind": True,
1679        "expression": True,
1680        "exists": False,
1681        "materialized": False,
1682    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1685class Comprehension(Expression):
1686    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):
1690class MergeTreeTTLAction(Expression):
1691    arg_types = {
1692        "this": True,
1693        "delete": False,
1694        "recompress": False,
1695        "to_disk": False,
1696        "to_volume": False,
1697    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1701class MergeTreeTTL(Expression):
1702    arg_types = {
1703        "expressions": True,
1704        "where": False,
1705        "group": False,
1706        "aggregates": False,
1707    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1711class IndexConstraintOption(Expression):
1712    arg_types = {
1713        "key_block_size": False,
1714        "using": False,
1715        "parser": False,
1716        "comment": False,
1717        "visible": False,
1718        "engine_attr": False,
1719        "secondary_engine_attr": False,
1720    }
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):
1723class ColumnConstraint(Expression):
1724    arg_types = {"this": False, "kind": True}
1725
1726    @property
1727    def kind(self) -> ColumnConstraintKind:
1728        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1726    @property
1727    def kind(self) -> ColumnConstraintKind:
1728        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1731class ColumnConstraintKind(Expression):
1732    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1735class AutoIncrementColumnConstraint(ColumnConstraintKind):
1736    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1739class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1740    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1743class CaseSpecificColumnConstraint(ColumnConstraintKind):
1744    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1747class CharacterSetColumnConstraint(ColumnConstraintKind):
1748    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1751class CheckColumnConstraint(ColumnConstraintKind):
1752    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1755class ClusteredColumnConstraint(ColumnConstraintKind):
1756    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1759class CollateColumnConstraint(ColumnConstraintKind):
1760    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1763class CommentColumnConstraint(ColumnConstraintKind):
1764    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1767class CompressColumnConstraint(ColumnConstraintKind):
1768    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1771class DateFormatColumnConstraint(ColumnConstraintKind):
1772    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1775class DefaultColumnConstraint(ColumnConstraintKind):
1776    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1779class EncodeColumnConstraint(ColumnConstraintKind):
1780    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1784class ExcludeColumnConstraint(ColumnConstraintKind):
1785    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1788class EphemeralColumnConstraint(ColumnConstraintKind):
1789    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1792class WithOperator(Expression):
1793    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1796class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1797    # this: True -> ALWAYS, this: False -> BY DEFAULT
1798    arg_types = {
1799        "this": False,
1800        "expression": False,
1801        "on_null": False,
1802        "start": False,
1803        "increment": False,
1804        "minvalue": False,
1805        "maxvalue": False,
1806        "cycle": False,
1807    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1810class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1811    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1816class IndexColumnConstraint(ColumnConstraintKind):
1817    arg_types = {
1818        "this": False,
1819        "expressions": False,
1820        "kind": False,
1821        "index_type": False,
1822        "options": False,
1823        "expression": False,  # Clickhouse
1824        "granularity": False,
1825    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1828class InlineLengthColumnConstraint(ColumnConstraintKind):
1829    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1832class NonClusteredColumnConstraint(ColumnConstraintKind):
1833    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1836class NotForReplicationColumnConstraint(ColumnConstraintKind):
1837    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1841class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1842    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1845class NotNullColumnConstraint(ColumnConstraintKind):
1846    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1850class OnUpdateColumnConstraint(ColumnConstraintKind):
1851    pass
key = 'onupdatecolumnconstraint'
class TagColumnConstraint(ColumnConstraintKind):
1855class TagColumnConstraint(ColumnConstraintKind):
1856    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tagcolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1860class TransformColumnConstraint(ColumnConstraintKind):
1861    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1864class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1865    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1868class TitleColumnConstraint(ColumnConstraintKind):
1869    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1872class UniqueColumnConstraint(ColumnConstraintKind):
1873    arg_types = {"this": False, "index_type": False, "on_conflict": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1876class UppercaseColumnConstraint(ColumnConstraintKind):
1877    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1880class PathColumnConstraint(ColumnConstraintKind):
1881    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1885class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1886    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1891class ComputedColumnConstraint(ColumnConstraintKind):
1892    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1895class Constraint(Expression):
1896    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1899class Delete(DML):
1900    arg_types = {
1901        "with": False,
1902        "this": False,
1903        "using": False,
1904        "where": False,
1905        "returning": False,
1906        "limit": False,
1907        "tables": False,  # Multiple-Table Syntax (MySQL)
1908    }
1909
1910    def delete(
1911        self,
1912        table: ExpOrStr,
1913        dialect: DialectType = None,
1914        copy: bool = True,
1915        **opts,
1916    ) -> Delete:
1917        """
1918        Create a DELETE expression or replace the table on an existing DELETE expression.
1919
1920        Example:
1921            >>> delete("tbl").sql()
1922            'DELETE FROM tbl'
1923
1924        Args:
1925            table: the table from which to delete.
1926            dialect: the dialect used to parse the input expression.
1927            copy: if `False`, modify this expression instance in-place.
1928            opts: other options to use to parse the input expressions.
1929
1930        Returns:
1931            Delete: the modified expression.
1932        """
1933        return _apply_builder(
1934            expression=table,
1935            instance=self,
1936            arg="this",
1937            dialect=dialect,
1938            into=Table,
1939            copy=copy,
1940            **opts,
1941        )
1942
1943    def where(
1944        self,
1945        *expressions: t.Optional[ExpOrStr],
1946        append: bool = True,
1947        dialect: DialectType = None,
1948        copy: bool = True,
1949        **opts,
1950    ) -> Delete:
1951        """
1952        Append to or set the WHERE expressions.
1953
1954        Example:
1955            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1956            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1957
1958        Args:
1959            *expressions: the SQL code strings to parse.
1960                If an `Expression` instance is passed, it will be used as-is.
1961                Multiple expressions are combined with an AND operator.
1962            append: if `True`, AND the new expressions to any existing expression.
1963                Otherwise, this resets the expression.
1964            dialect: the dialect used to parse the input expressions.
1965            copy: if `False`, modify this expression instance in-place.
1966            opts: other options to use to parse the input expressions.
1967
1968        Returns:
1969            Delete: the modified expression.
1970        """
1971        return _apply_conjunction_builder(
1972            *expressions,
1973            instance=self,
1974            arg="where",
1975            append=append,
1976            into=Where,
1977            dialect=dialect,
1978            copy=copy,
1979            **opts,
1980        )
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:
1910    def delete(
1911        self,
1912        table: ExpOrStr,
1913        dialect: DialectType = None,
1914        copy: bool = True,
1915        **opts,
1916    ) -> Delete:
1917        """
1918        Create a DELETE expression or replace the table on an existing DELETE expression.
1919
1920        Example:
1921            >>> delete("tbl").sql()
1922            'DELETE FROM tbl'
1923
1924        Args:
1925            table: the table from which to delete.
1926            dialect: the dialect used to parse the input expression.
1927            copy: if `False`, modify this expression instance in-place.
1928            opts: other options to use to parse the input expressions.
1929
1930        Returns:
1931            Delete: the modified expression.
1932        """
1933        return _apply_builder(
1934            expression=table,
1935            instance=self,
1936            arg="this",
1937            dialect=dialect,
1938            into=Table,
1939            copy=copy,
1940            **opts,
1941        )

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:
1943    def where(
1944        self,
1945        *expressions: t.Optional[ExpOrStr],
1946        append: bool = True,
1947        dialect: DialectType = None,
1948        copy: bool = True,
1949        **opts,
1950    ) -> Delete:
1951        """
1952        Append to or set the WHERE expressions.
1953
1954        Example:
1955            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1956            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1957
1958        Args:
1959            *expressions: the SQL code strings to parse.
1960                If an `Expression` instance is passed, it will be used as-is.
1961                Multiple expressions are combined with an AND operator.
1962            append: if `True`, AND the new expressions to any existing expression.
1963                Otherwise, this resets the expression.
1964            dialect: the dialect used to parse the input expressions.
1965            copy: if `False`, modify this expression instance in-place.
1966            opts: other options to use to parse the input expressions.
1967
1968        Returns:
1969            Delete: the modified expression.
1970        """
1971        return _apply_conjunction_builder(
1972            *expressions,
1973            instance=self,
1974            arg="where",
1975            append=append,
1976            into=Where,
1977            dialect=dialect,
1978            copy=copy,
1979            **opts,
1980        )

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):
1983class Drop(Expression):
1984    arg_types = {
1985        "this": False,
1986        "kind": False,
1987        "expressions": False,
1988        "exists": False,
1989        "temporary": False,
1990        "materialized": False,
1991        "cascade": False,
1992        "constraints": False,
1993        "purge": False,
1994        "cluster": False,
1995    }
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False}
key = 'drop'
class Filter(Expression):
1998class Filter(Expression):
1999    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2002class Check(Expression):
2003    pass
key = 'check'
class Connect(Expression):
2007class Connect(Expression):
2008    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2011class CopyParameter(Expression):
2012    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(Expression):
2015class Copy(Expression):
2016    arg_types = {
2017        "this": True,
2018        "kind": True,
2019        "files": True,
2020        "credentials": False,
2021        "format": False,
2022        "params": False,
2023    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2026class Credentials(Expression):
2027    arg_types = {
2028        "credentials": False,
2029        "encryption": False,
2030        "storage": False,
2031        "iam_role": False,
2032        "region": False,
2033    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2036class Prior(Expression):
2037    pass
key = 'prior'
class Directory(Expression):
2040class Directory(Expression):
2041    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2042    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2045class ForeignKey(Expression):
2046    arg_types = {
2047        "expressions": True,
2048        "reference": False,
2049        "delete": False,
2050        "update": False,
2051    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2054class ColumnPrefix(Expression):
2055    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2058class PrimaryKey(Expression):
2059    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2064class Into(Expression):
2065    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2068class From(Expression):
2069    @property
2070    def name(self) -> str:
2071        return self.this.name
2072
2073    @property
2074    def alias_or_name(self) -> str:
2075        return self.this.alias_or_name
name: str
2069    @property
2070    def name(self) -> str:
2071        return self.this.name
alias_or_name: str
2073    @property
2074    def alias_or_name(self) -> str:
2075        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2078class Having(Expression):
2079    pass
key = 'having'
class Hint(Expression):
2082class Hint(Expression):
2083    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2086class JoinHint(Expression):
2087    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2090class Identifier(Expression):
2091    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2092
2093    @property
2094    def quoted(self) -> bool:
2095        return bool(self.args.get("quoted"))
2096
2097    @property
2098    def hashable_args(self) -> t.Any:
2099        return (self.this, self.quoted)
2100
2101    @property
2102    def output_name(self) -> str:
2103        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2093    @property
2094    def quoted(self) -> bool:
2095        return bool(self.args.get("quoted"))
hashable_args: Any
2097    @property
2098    def hashable_args(self) -> t.Any:
2099        return (self.this, self.quoted)
output_name: str
2101    @property
2102    def output_name(self) -> str:
2103        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):
2107class Opclass(Expression):
2108    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2111class Index(Expression):
2112    arg_types = {
2113        "this": False,
2114        "table": False,
2115        "unique": False,
2116        "primary": False,
2117        "amp": False,  # teradata
2118        "params": False,
2119    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2122class IndexParameters(Expression):
2123    arg_types = {
2124        "using": False,
2125        "include": False,
2126        "columns": False,
2127        "with_storage": False,
2128        "partition_by": False,
2129        "tablespace": False,
2130        "where": False,
2131    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False}
key = 'indexparameters'
class Insert(DDL, DML):
2134class Insert(DDL, DML):
2135    arg_types = {
2136        "hint": False,
2137        "with": False,
2138        "is_function": False,
2139        "this": False,
2140        "expression": False,
2141        "conflict": False,
2142        "returning": False,
2143        "overwrite": False,
2144        "exists": False,
2145        "alternative": False,
2146        "where": False,
2147        "ignore": False,
2148        "by_name": False,
2149        "stored": False,
2150    }
2151
2152    def with_(
2153        self,
2154        alias: ExpOrStr,
2155        as_: ExpOrStr,
2156        recursive: t.Optional[bool] = None,
2157        append: bool = True,
2158        dialect: DialectType = None,
2159        copy: bool = True,
2160        **opts,
2161    ) -> Insert:
2162        """
2163        Append to or set the common table expressions.
2164
2165        Example:
2166            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2167            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2168
2169        Args:
2170            alias: the SQL code string to parse as the table name.
2171                If an `Expression` instance is passed, this is used as-is.
2172            as_: the SQL code string to parse as the table expression.
2173                If an `Expression` instance is passed, it will be used as-is.
2174            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2175            append: if `True`, add to any existing expressions.
2176                Otherwise, this resets the expressions.
2177            dialect: the dialect used to parse the input expression.
2178            copy: if `False`, modify this expression instance in-place.
2179            opts: other options to use to parse the input expressions.
2180
2181        Returns:
2182            The modified expression.
2183        """
2184        return _apply_cte_builder(
2185            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2186        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': 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:
2152    def with_(
2153        self,
2154        alias: ExpOrStr,
2155        as_: ExpOrStr,
2156        recursive: t.Optional[bool] = None,
2157        append: bool = True,
2158        dialect: DialectType = None,
2159        copy: bool = True,
2160        **opts,
2161    ) -> Insert:
2162        """
2163        Append to or set the common table expressions.
2164
2165        Example:
2166            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2167            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2168
2169        Args:
2170            alias: the SQL code string to parse as the table name.
2171                If an `Expression` instance is passed, this is used as-is.
2172            as_: the SQL code string to parse as the table expression.
2173                If an `Expression` instance is passed, it will be used as-is.
2174            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2175            append: if `True`, add to any existing expressions.
2176                Otherwise, this resets the expressions.
2177            dialect: the dialect used to parse the input expression.
2178            copy: if `False`, modify this expression instance in-place.
2179            opts: other options to use to parse the input expressions.
2180
2181        Returns:
2182            The modified expression.
2183        """
2184        return _apply_cte_builder(
2185            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2186        )

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):
2189class OnConflict(Expression):
2190    arg_types = {
2191        "duplicate": False,
2192        "expressions": False,
2193        "action": False,
2194        "conflict_keys": False,
2195        "constraint": False,
2196    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2199class Returning(Expression):
2200    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2204class Introducer(Expression):
2205    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2209class National(Expression):
2210    pass
key = 'national'
class LoadData(Expression):
2213class LoadData(Expression):
2214    arg_types = {
2215        "this": True,
2216        "local": False,
2217        "overwrite": False,
2218        "inpath": True,
2219        "partition": False,
2220        "input_format": False,
2221        "serde": False,
2222    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2225class Partition(Expression):
2226    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2229class PartitionRange(Expression):
2230    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2234class PartitionId(Expression):
2235    pass
key = 'partitionid'
class Fetch(Expression):
2238class Fetch(Expression):
2239    arg_types = {
2240        "direction": False,
2241        "count": False,
2242        "percent": False,
2243        "with_ties": False,
2244    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2247class Group(Expression):
2248    arg_types = {
2249        "expressions": False,
2250        "grouping_sets": False,
2251        "cube": False,
2252        "rollup": False,
2253        "totals": False,
2254        "all": False,
2255    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2258class Lambda(Expression):
2259    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2262class Limit(Expression):
2263    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
arg_types = {'this': False, 'expression': True, 'offset': False, 'expressions': False}
key = 'limit'
class Literal(Condition):
2266class Literal(Condition):
2267    arg_types = {"this": True, "is_string": True}
2268
2269    @property
2270    def hashable_args(self) -> t.Any:
2271        return (self.this, self.args.get("is_string"))
2272
2273    @classmethod
2274    def number(cls, number) -> Literal:
2275        return cls(this=str(number), is_string=False)
2276
2277    @classmethod
2278    def string(cls, string) -> Literal:
2279        return cls(this=str(string), is_string=True)
2280
2281    @property
2282    def output_name(self) -> str:
2283        return self.name
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2269    @property
2270    def hashable_args(self) -> t.Any:
2271        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2273    @classmethod
2274    def number(cls, number) -> Literal:
2275        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2277    @classmethod
2278    def string(cls, string) -> Literal:
2279        return cls(this=str(string), is_string=True)
output_name: str
2281    @property
2282    def output_name(self) -> str:
2283        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):
2286class Join(Expression):
2287    arg_types = {
2288        "this": True,
2289        "on": False,
2290        "side": False,
2291        "kind": False,
2292        "using": False,
2293        "method": False,
2294        "global": False,
2295        "hint": False,
2296        "match_condition": False,  # Snowflake
2297    }
2298
2299    @property
2300    def method(self) -> str:
2301        return self.text("method").upper()
2302
2303    @property
2304    def kind(self) -> str:
2305        return self.text("kind").upper()
2306
2307    @property
2308    def side(self) -> str:
2309        return self.text("side").upper()
2310
2311    @property
2312    def hint(self) -> str:
2313        return self.text("hint").upper()
2314
2315    @property
2316    def alias_or_name(self) -> str:
2317        return self.this.alias_or_name
2318
2319    def on(
2320        self,
2321        *expressions: t.Optional[ExpOrStr],
2322        append: bool = True,
2323        dialect: DialectType = None,
2324        copy: bool = True,
2325        **opts,
2326    ) -> Join:
2327        """
2328        Append to or set the ON expressions.
2329
2330        Example:
2331            >>> import sqlglot
2332            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2333            'JOIN x ON y = 1'
2334
2335        Args:
2336            *expressions: the SQL code strings to parse.
2337                If an `Expression` instance is passed, it will be used as-is.
2338                Multiple expressions are combined with an AND operator.
2339            append: if `True`, AND the new expressions to any existing expression.
2340                Otherwise, this resets the expression.
2341            dialect: the dialect used to parse the input expressions.
2342            copy: if `False`, modify this expression instance in-place.
2343            opts: other options to use to parse the input expressions.
2344
2345        Returns:
2346            The modified Join expression.
2347        """
2348        join = _apply_conjunction_builder(
2349            *expressions,
2350            instance=self,
2351            arg="on",
2352            append=append,
2353            dialect=dialect,
2354            copy=copy,
2355            **opts,
2356        )
2357
2358        if join.kind == "CROSS":
2359            join.set("kind", None)
2360
2361        return join
2362
2363    def using(
2364        self,
2365        *expressions: t.Optional[ExpOrStr],
2366        append: bool = True,
2367        dialect: DialectType = None,
2368        copy: bool = True,
2369        **opts,
2370    ) -> Join:
2371        """
2372        Append to or set the USING expressions.
2373
2374        Example:
2375            >>> import sqlglot
2376            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2377            'JOIN x USING (foo, bla)'
2378
2379        Args:
2380            *expressions: the SQL code strings to parse.
2381                If an `Expression` instance is passed, it will be used as-is.
2382            append: if `True`, concatenate the new expressions to the existing "using" list.
2383                Otherwise, this resets the expression.
2384            dialect: the dialect used to parse the input expressions.
2385            copy: if `False`, modify this expression instance in-place.
2386            opts: other options to use to parse the input expressions.
2387
2388        Returns:
2389            The modified Join expression.
2390        """
2391        join = _apply_list_builder(
2392            *expressions,
2393            instance=self,
2394            arg="using",
2395            append=append,
2396            dialect=dialect,
2397            copy=copy,
2398            **opts,
2399        )
2400
2401        if join.kind == "CROSS":
2402            join.set("kind", None)
2403
2404        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False}
method: str
2299    @property
2300    def method(self) -> str:
2301        return self.text("method").upper()
kind: str
2303    @property
2304    def kind(self) -> str:
2305        return self.text("kind").upper()
side: str
2307    @property
2308    def side(self) -> str:
2309        return self.text("side").upper()
hint: str
2311    @property
2312    def hint(self) -> str:
2313        return self.text("hint").upper()
alias_or_name: str
2315    @property
2316    def alias_or_name(self) -> str:
2317        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:
2319    def on(
2320        self,
2321        *expressions: t.Optional[ExpOrStr],
2322        append: bool = True,
2323        dialect: DialectType = None,
2324        copy: bool = True,
2325        **opts,
2326    ) -> Join:
2327        """
2328        Append to or set the ON expressions.
2329
2330        Example:
2331            >>> import sqlglot
2332            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2333            'JOIN x ON y = 1'
2334
2335        Args:
2336            *expressions: the SQL code strings to parse.
2337                If an `Expression` instance is passed, it will be used as-is.
2338                Multiple expressions are combined with an AND operator.
2339            append: if `True`, AND the new expressions to any existing expression.
2340                Otherwise, this resets the expression.
2341            dialect: the dialect used to parse the input expressions.
2342            copy: if `False`, modify this expression instance in-place.
2343            opts: other options to use to parse the input expressions.
2344
2345        Returns:
2346            The modified Join expression.
2347        """
2348        join = _apply_conjunction_builder(
2349            *expressions,
2350            instance=self,
2351            arg="on",
2352            append=append,
2353            dialect=dialect,
2354            copy=copy,
2355            **opts,
2356        )
2357
2358        if join.kind == "CROSS":
2359            join.set("kind", None)
2360
2361        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:
2363    def using(
2364        self,
2365        *expressions: t.Optional[ExpOrStr],
2366        append: bool = True,
2367        dialect: DialectType = None,
2368        copy: bool = True,
2369        **opts,
2370    ) -> Join:
2371        """
2372        Append to or set the USING expressions.
2373
2374        Example:
2375            >>> import sqlglot
2376            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2377            'JOIN x USING (foo, bla)'
2378
2379        Args:
2380            *expressions: the SQL code strings to parse.
2381                If an `Expression` instance is passed, it will be used as-is.
2382            append: if `True`, concatenate the new expressions to the existing "using" list.
2383                Otherwise, this resets the expression.
2384            dialect: the dialect used to parse the input expressions.
2385            copy: if `False`, modify this expression instance in-place.
2386            opts: other options to use to parse the input expressions.
2387
2388        Returns:
2389            The modified Join expression.
2390        """
2391        join = _apply_list_builder(
2392            *expressions,
2393            instance=self,
2394            arg="using",
2395            append=append,
2396            dialect=dialect,
2397            copy=copy,
2398            **opts,
2399        )
2400
2401        if join.kind == "CROSS":
2402            join.set("kind", None)
2403
2404        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):
2407class Lateral(UDTF):
2408    arg_types = {
2409        "this": True,
2410        "view": False,
2411        "outer": False,
2412        "alias": False,
2413        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2414    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2417class MatchRecognizeMeasure(Expression):
2418    arg_types = {
2419        "this": True,
2420        "window_frame": False,
2421    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2424class MatchRecognize(Expression):
2425    arg_types = {
2426        "partition_by": False,
2427        "order": False,
2428        "measures": False,
2429        "rows": False,
2430        "after": False,
2431        "pattern": False,
2432        "define": False,
2433        "alias": False,
2434    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2439class Final(Expression):
2440    pass
key = 'final'
class Offset(Expression):
2443class Offset(Expression):
2444    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2447class Order(Expression):
2448    arg_types = {
2449        "this": False,
2450        "expressions": True,
2451        "interpolate": False,
2452        "siblings": False,
2453    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2457class WithFill(Expression):
2458    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2463class Cluster(Order):
2464    pass
key = 'cluster'
class Distribute(Order):
2467class Distribute(Order):
2468    pass
key = 'distribute'
class Sort(Order):
2471class Sort(Order):
2472    pass
key = 'sort'
class Ordered(Expression):
2475class Ordered(Expression):
2476    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):
2479class Property(Expression):
2480    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2483class AllowedValuesProperty(Expression):
2484    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2487class AlgorithmProperty(Property):
2488    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2491class AutoIncrementProperty(Property):
2492    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2496class AutoRefreshProperty(Property):
2497    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2500class BackupProperty(Property):
2501    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2504class BlockCompressionProperty(Property):
2505    arg_types = {
2506        "autotemp": False,
2507        "always": False,
2508        "default": False,
2509        "manual": False,
2510        "never": False,
2511    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2514class CharacterSetProperty(Property):
2515    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2518class ChecksumProperty(Property):
2519    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2522class CollateProperty(Property):
2523    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2526class CopyGrantsProperty(Property):
2527    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2530class DataBlocksizeProperty(Property):
2531    arg_types = {
2532        "size": False,
2533        "units": False,
2534        "minimum": False,
2535        "maximum": False,
2536        "default": False,
2537    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2540class DataDeletionProperty(Property):
2541    arg_types = {"on": True, "filter_col": False, "retention_period": False}
arg_types = {'on': True, 'filter_col': False, 'retention_period': False}
key = 'datadeletionproperty'
class DefinerProperty(Property):
2544class DefinerProperty(Property):
2545    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2548class DistKeyProperty(Property):
2549    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2552class DistStyleProperty(Property):
2553    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2556class EngineProperty(Property):
2557    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2560class HeapProperty(Property):
2561    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2564class ToTableProperty(Property):
2565    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2568class ExecuteAsProperty(Property):
2569    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2572class ExternalProperty(Property):
2573    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2576class FallbackProperty(Property):
2577    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2580class FileFormatProperty(Property):
2581    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2584class FreespaceProperty(Property):
2585    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2588class GlobalProperty(Property):
2589    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2592class IcebergProperty(Property):
2593    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2596class InheritsProperty(Property):
2597    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2600class InputModelProperty(Property):
2601    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2604class OutputModelProperty(Property):
2605    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2608class IsolatedLoadingProperty(Property):
2609    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2612class JournalProperty(Property):
2613    arg_types = {
2614        "no": False,
2615        "dual": False,
2616        "before": False,
2617        "local": False,
2618        "after": False,
2619    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2622class LanguageProperty(Property):
2623    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2627class ClusteredByProperty(Property):
2628    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2631class DictProperty(Property):
2632    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2635class DictSubProperty(Property):
2636    pass
key = 'dictsubproperty'
class DictRange(Property):
2639class DictRange(Property):
2640    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class OnCluster(Property):
2645class OnCluster(Property):
2646    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2649class LikeProperty(Property):
2650    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2653class LocationProperty(Property):
2654    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2657class LockProperty(Property):
2658    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2661class LockingProperty(Property):
2662    arg_types = {
2663        "this": False,
2664        "kind": True,
2665        "for_or_in": False,
2666        "lock_type": True,
2667        "override": False,
2668    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2671class LogProperty(Property):
2672    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2675class MaterializedProperty(Property):
2676    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2679class MergeBlockRatioProperty(Property):
2680    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):
2683class NoPrimaryIndexProperty(Property):
2684    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2687class OnProperty(Property):
2688    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2691class OnCommitProperty(Property):
2692    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2695class PartitionedByProperty(Property):
2696    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2700class PartitionBoundSpec(Expression):
2701    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2702    arg_types = {
2703        "this": False,
2704        "expression": False,
2705        "from_expressions": False,
2706        "to_expressions": False,
2707    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2710class PartitionedOfProperty(Property):
2711    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2712    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2715class RemoteWithConnectionModelProperty(Property):
2716    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2719class ReturnsProperty(Property):
2720    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
arg_types = {'this': False, 'is_table': False, 'table': False, 'null': False}
key = 'returnsproperty'
class StrictProperty(Property):
2723class StrictProperty(Property):
2724    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2727class RowFormatProperty(Property):
2728    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2731class RowFormatDelimitedProperty(Property):
2732    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2733    arg_types = {
2734        "fields": False,
2735        "escaped": False,
2736        "collection_items": False,
2737        "map_keys": False,
2738        "lines": False,
2739        "null": False,
2740        "serde": False,
2741    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2744class RowFormatSerdeProperty(Property):
2745    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2749class QueryTransform(Expression):
2750    arg_types = {
2751        "expressions": True,
2752        "command_script": True,
2753        "schema": False,
2754        "row_format_before": False,
2755        "record_writer": False,
2756        "row_format_after": False,
2757        "record_reader": False,
2758    }
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):
2761class SampleProperty(Property):
2762    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2765class SchemaCommentProperty(Property):
2766    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2769class SerdeProperties(Property):
2770    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2773class SetProperty(Property):
2774    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2777class SharingProperty(Property):
2778    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2781class SetConfigProperty(Property):
2782    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2785class SettingsProperty(Property):
2786    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2789class SortKeyProperty(Property):
2790    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2793class SqlReadWriteProperty(Property):
2794    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2797class SqlSecurityProperty(Property):
2798    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2801class StabilityProperty(Property):
2802    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2805class TemporaryProperty(Property):
2806    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class TransformModelProperty(Property):
2809class TransformModelProperty(Property):
2810    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2813class TransientProperty(Property):
2814    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2817class UnloggedProperty(Property):
2818    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2822class ViewAttributeProperty(Property):
2823    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2826class VolatileProperty(Property):
2827    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2830class WithDataProperty(Property):
2831    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2834class WithJournalTableProperty(Property):
2835    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2838class WithSystemVersioningProperty(Property):
2839    arg_types = {
2840        "on": False,
2841        "this": False,
2842        "data_consistency": False,
2843        "retention_period": False,
2844        "with": True,
2845    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2848class Properties(Expression):
2849    arg_types = {"expressions": True}
2850
2851    NAME_TO_PROPERTY = {
2852        "ALGORITHM": AlgorithmProperty,
2853        "AUTO_INCREMENT": AutoIncrementProperty,
2854        "CHARACTER SET": CharacterSetProperty,
2855        "CLUSTERED_BY": ClusteredByProperty,
2856        "COLLATE": CollateProperty,
2857        "COMMENT": SchemaCommentProperty,
2858        "DEFINER": DefinerProperty,
2859        "DISTKEY": DistKeyProperty,
2860        "DISTSTYLE": DistStyleProperty,
2861        "ENGINE": EngineProperty,
2862        "EXECUTE AS": ExecuteAsProperty,
2863        "FORMAT": FileFormatProperty,
2864        "LANGUAGE": LanguageProperty,
2865        "LOCATION": LocationProperty,
2866        "LOCK": LockProperty,
2867        "PARTITIONED_BY": PartitionedByProperty,
2868        "RETURNS": ReturnsProperty,
2869        "ROW_FORMAT": RowFormatProperty,
2870        "SORTKEY": SortKeyProperty,
2871    }
2872
2873    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2874
2875    # CREATE property locations
2876    # Form: schema specified
2877    #   create [POST_CREATE]
2878    #     table a [POST_NAME]
2879    #     (b int) [POST_SCHEMA]
2880    #     with ([POST_WITH])
2881    #     index (b) [POST_INDEX]
2882    #
2883    # Form: alias selection
2884    #   create [POST_CREATE]
2885    #     table a [POST_NAME]
2886    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2887    #     index (c) [POST_INDEX]
2888    class Location(AutoName):
2889        POST_CREATE = auto()
2890        POST_NAME = auto()
2891        POST_SCHEMA = auto()
2892        POST_WITH = auto()
2893        POST_ALIAS = auto()
2894        POST_EXPRESSION = auto()
2895        POST_INDEX = auto()
2896        UNSUPPORTED = auto()
2897
2898    @classmethod
2899    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2900        expressions = []
2901        for key, value in properties_dict.items():
2902            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2903            if property_cls:
2904                expressions.append(property_cls(this=convert(value)))
2905            else:
2906                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2907
2908        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'>, 'LOCK': <class 'LockProperty'>, '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 'LockProperty'>: 'LOCK', <class 'PartitionedByProperty'>: 'PARTITIONED_BY', <class 'ReturnsProperty'>: 'RETURNS', <class 'RowFormatProperty'>: 'ROW_FORMAT', <class 'SortKeyProperty'>: 'SORTKEY'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
2898    @classmethod
2899    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2900        expressions = []
2901        for key, value in properties_dict.items():
2902            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2903            if property_cls:
2904                expressions.append(property_cls(this=convert(value)))
2905            else:
2906                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2907
2908        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2888    class Location(AutoName):
2889        POST_CREATE = auto()
2890        POST_NAME = auto()
2891        POST_SCHEMA = auto()
2892        POST_WITH = auto()
2893        POST_ALIAS = auto()
2894        POST_EXPRESSION = auto()
2895        POST_INDEX = auto()
2896        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):
2911class Qualify(Expression):
2912    pass
key = 'qualify'
class InputOutputFormat(Expression):
2915class InputOutputFormat(Expression):
2916    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2920class Return(Expression):
2921    pass
key = 'return'
class Reference(Expression):
2924class Reference(Expression):
2925    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2928class Tuple(Expression):
2929    arg_types = {"expressions": False}
2930
2931    def isin(
2932        self,
2933        *expressions: t.Any,
2934        query: t.Optional[ExpOrStr] = None,
2935        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2936        copy: bool = True,
2937        **opts,
2938    ) -> In:
2939        return In(
2940            this=maybe_copy(self, copy),
2941            expressions=[convert(e, copy=copy) for e in expressions],
2942            query=maybe_parse(query, copy=copy, **opts) if query else None,
2943            unnest=(
2944                Unnest(
2945                    expressions=[
2946                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2947                        for e in ensure_list(unnest)
2948                    ]
2949                )
2950                if unnest
2951                else None
2952            ),
2953        )
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:
2931    def isin(
2932        self,
2933        *expressions: t.Any,
2934        query: t.Optional[ExpOrStr] = None,
2935        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2936        copy: bool = True,
2937        **opts,
2938    ) -> In:
2939        return In(
2940            this=maybe_copy(self, copy),
2941            expressions=[convert(e, copy=copy) for e in expressions],
2942            query=maybe_parse(query, copy=copy, **opts) if query else None,
2943            unnest=(
2944                Unnest(
2945                    expressions=[
2946                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2947                        for e in ensure_list(unnest)
2948                    ]
2949                )
2950                if unnest
2951                else None
2952            ),
2953        )
key = 'tuple'
QUERY_MODIFIERS = {'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': 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, 'options': False}
class QueryOption(Expression):
2984class QueryOption(Expression):
2985    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
2989class WithTableHint(Expression):
2990    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
2994class IndexTableHint(Expression):
2995    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
2999class HistoricalData(Expression):
3000    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3003class Table(Expression):
3004    arg_types = {
3005        "this": False,
3006        "alias": False,
3007        "db": False,
3008        "catalog": False,
3009        "laterals": False,
3010        "joins": False,
3011        "pivots": False,
3012        "hints": False,
3013        "system_time": False,
3014        "version": False,
3015        "format": False,
3016        "pattern": False,
3017        "ordinality": False,
3018        "when": False,
3019        "only": False,
3020        "partition": False,
3021    }
3022
3023    @property
3024    def name(self) -> str:
3025        if isinstance(self.this, Func):
3026            return ""
3027        return self.this.name
3028
3029    @property
3030    def db(self) -> str:
3031        return self.text("db")
3032
3033    @property
3034    def catalog(self) -> str:
3035        return self.text("catalog")
3036
3037    @property
3038    def selects(self) -> t.List[Expression]:
3039        return []
3040
3041    @property
3042    def named_selects(self) -> t.List[str]:
3043        return []
3044
3045    @property
3046    def parts(self) -> t.List[Expression]:
3047        """Return the parts of a table in order catalog, db, table."""
3048        parts: t.List[Expression] = []
3049
3050        for arg in ("catalog", "db", "this"):
3051            part = self.args.get(arg)
3052
3053            if isinstance(part, Dot):
3054                parts.extend(part.flatten())
3055            elif isinstance(part, Expression):
3056                parts.append(part)
3057
3058        return parts
3059
3060    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3061        parts = self.parts
3062        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3063        alias = self.args.get("alias")
3064        if alias:
3065            col = alias_(col, alias.this, copy=copy)
3066        return col
arg_types = {'this': False, '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, 'only': False, 'partition': False}
name: str
3023    @property
3024    def name(self) -> str:
3025        if isinstance(self.this, Func):
3026            return ""
3027        return self.this.name
db: str
3029    @property
3030    def db(self) -> str:
3031        return self.text("db")
catalog: str
3033    @property
3034    def catalog(self) -> str:
3035        return self.text("catalog")
selects: List[Expression]
3037    @property
3038    def selects(self) -> t.List[Expression]:
3039        return []
named_selects: List[str]
3041    @property
3042    def named_selects(self) -> t.List[str]:
3043        return []
parts: List[Expression]
3045    @property
3046    def parts(self) -> t.List[Expression]:
3047        """Return the parts of a table in order catalog, db, table."""
3048        parts: t.List[Expression] = []
3049
3050        for arg in ("catalog", "db", "this"):
3051            part = self.args.get(arg)
3052
3053            if isinstance(part, Dot):
3054                parts.extend(part.flatten())
3055            elif isinstance(part, Expression):
3056                parts.append(part)
3057
3058        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3060    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3061        parts = self.parts
3062        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3063        alias = self.args.get("alias")
3064        if alias:
3065            col = alias_(col, alias.this, copy=copy)
3066        return col
key = 'table'
class Union(Query):
3069class Union(Query):
3070    arg_types = {
3071        "with": False,
3072        "this": True,
3073        "expression": True,
3074        "distinct": False,
3075        "by_name": False,
3076        **QUERY_MODIFIERS,
3077    }
3078
3079    def select(
3080        self,
3081        *expressions: t.Optional[ExpOrStr],
3082        append: bool = True,
3083        dialect: DialectType = None,
3084        copy: bool = True,
3085        **opts,
3086    ) -> Union:
3087        this = maybe_copy(self, copy)
3088        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3089        this.expression.unnest().select(
3090            *expressions, append=append, dialect=dialect, copy=False, **opts
3091        )
3092        return this
3093
3094    @property
3095    def named_selects(self) -> t.List[str]:
3096        return self.this.unnest().named_selects
3097
3098    @property
3099    def is_star(self) -> bool:
3100        return self.this.is_star or self.expression.is_star
3101
3102    @property
3103    def selects(self) -> t.List[Expression]:
3104        return self.this.unnest().selects
3105
3106    @property
3107    def left(self) -> Expression:
3108        return self.this
3109
3110    @property
3111    def right(self) -> Expression:
3112        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, 'prewhere': 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, 'options': False}
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:
3079    def select(
3080        self,
3081        *expressions: t.Optional[ExpOrStr],
3082        append: bool = True,
3083        dialect: DialectType = None,
3084        copy: bool = True,
3085        **opts,
3086    ) -> Union:
3087        this = maybe_copy(self, copy)
3088        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3089        this.expression.unnest().select(
3090            *expressions, append=append, dialect=dialect, copy=False, **opts
3091        )
3092        return this

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 Query expression.

named_selects: List[str]
3094    @property
3095    def named_selects(self) -> t.List[str]:
3096        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3098    @property
3099    def is_star(self) -> bool:
3100        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3102    @property
3103    def selects(self) -> t.List[Expression]:
3104        return self.this.unnest().selects

Returns the query's projections.

left: Expression
3106    @property
3107    def left(self) -> Expression:
3108        return self.this
right: Expression
3110    @property
3111    def right(self) -> Expression:
3112        return self.expression
key = 'union'
class Except(Union):
3115class Except(Union):
3116    pass
key = 'except'
class Intersect(Union):
3119class Intersect(Union):
3120    pass
key = 'intersect'
class Unnest(UDTF):
3123class Unnest(UDTF):
3124    arg_types = {
3125        "expressions": True,
3126        "alias": False,
3127        "offset": False,
3128    }
3129
3130    @property
3131    def selects(self) -> t.List[Expression]:
3132        columns = super().selects
3133        offset = self.args.get("offset")
3134        if offset:
3135            columns = columns + [to_identifier("offset") if offset is True else offset]
3136        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
3130    @property
3131    def selects(self) -> t.List[Expression]:
3132        columns = super().selects
3133        offset = self.args.get("offset")
3134        if offset:
3135            columns = columns + [to_identifier("offset") if offset is True else offset]
3136        return columns
key = 'unnest'
class Update(Expression):
3139class Update(Expression):
3140    arg_types = {
3141        "with": False,
3142        "this": False,
3143        "expressions": True,
3144        "from": False,
3145        "where": False,
3146        "returning": False,
3147        "order": False,
3148        "limit": False,
3149    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
3152class Values(UDTF):
3153    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3156class Var(Expression):
3157    pass
key = 'var'
class Version(Expression):
3160class Version(Expression):
3161    """
3162    Time travel, iceberg, bigquery etc
3163    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3164    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3165    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3166    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3167    this is either TIMESTAMP or VERSION
3168    kind is ("AS OF", "BETWEEN")
3169    """
3170
3171    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3174class Schema(Expression):
3175    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3180class Lock(Expression):
3181    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
3184class Select(Query):
3185    arg_types = {
3186        "with": False,
3187        "kind": False,
3188        "expressions": False,
3189        "hint": False,
3190        "distinct": False,
3191        "into": False,
3192        "from": False,
3193        **QUERY_MODIFIERS,
3194    }
3195
3196    def from_(
3197        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3198    ) -> Select:
3199        """
3200        Set the FROM expression.
3201
3202        Example:
3203            >>> Select().from_("tbl").select("x").sql()
3204            'SELECT x FROM tbl'
3205
3206        Args:
3207            expression : the SQL code strings to parse.
3208                If a `From` instance is passed, this is used as-is.
3209                If another `Expression` instance is passed, it will be wrapped in a `From`.
3210            dialect: the dialect used to parse the input expression.
3211            copy: if `False`, modify this expression instance in-place.
3212            opts: other options to use to parse the input expressions.
3213
3214        Returns:
3215            The modified Select expression.
3216        """
3217        return _apply_builder(
3218            expression=expression,
3219            instance=self,
3220            arg="from",
3221            into=From,
3222            prefix="FROM",
3223            dialect=dialect,
3224            copy=copy,
3225            **opts,
3226        )
3227
3228    def group_by(
3229        self,
3230        *expressions: t.Optional[ExpOrStr],
3231        append: bool = True,
3232        dialect: DialectType = None,
3233        copy: bool = True,
3234        **opts,
3235    ) -> Select:
3236        """
3237        Set the GROUP BY expression.
3238
3239        Example:
3240            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3241            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3242
3243        Args:
3244            *expressions: the SQL code strings to parse.
3245                If a `Group` instance is passed, this is used as-is.
3246                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3247                If nothing is passed in then a group by is not applied to the expression
3248            append: if `True`, add to any existing expressions.
3249                Otherwise, this flattens all the `Group` expression into a single expression.
3250            dialect: the dialect used to parse the input expression.
3251            copy: if `False`, modify this expression instance in-place.
3252            opts: other options to use to parse the input expressions.
3253
3254        Returns:
3255            The modified Select expression.
3256        """
3257        if not expressions:
3258            return self if not copy else self.copy()
3259
3260        return _apply_child_list_builder(
3261            *expressions,
3262            instance=self,
3263            arg="group",
3264            append=append,
3265            copy=copy,
3266            prefix="GROUP BY",
3267            into=Group,
3268            dialect=dialect,
3269            **opts,
3270        )
3271
3272    def sort_by(
3273        self,
3274        *expressions: t.Optional[ExpOrStr],
3275        append: bool = True,
3276        dialect: DialectType = None,
3277        copy: bool = True,
3278        **opts,
3279    ) -> Select:
3280        """
3281        Set the SORT BY expression.
3282
3283        Example:
3284            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3285            'SELECT x FROM tbl SORT BY x DESC'
3286
3287        Args:
3288            *expressions: the SQL code strings to parse.
3289                If a `Group` instance is passed, this is used as-is.
3290                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3291            append: if `True`, add to any existing expressions.
3292                Otherwise, this flattens all the `Order` expression into a single expression.
3293            dialect: the dialect used to parse the input expression.
3294            copy: if `False`, modify this expression instance in-place.
3295            opts: other options to use to parse the input expressions.
3296
3297        Returns:
3298            The modified Select expression.
3299        """
3300        return _apply_child_list_builder(
3301            *expressions,
3302            instance=self,
3303            arg="sort",
3304            append=append,
3305            copy=copy,
3306            prefix="SORT BY",
3307            into=Sort,
3308            dialect=dialect,
3309            **opts,
3310        )
3311
3312    def cluster_by(
3313        self,
3314        *expressions: t.Optional[ExpOrStr],
3315        append: bool = True,
3316        dialect: DialectType = None,
3317        copy: bool = True,
3318        **opts,
3319    ) -> Select:
3320        """
3321        Set the CLUSTER BY expression.
3322
3323        Example:
3324            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3325            'SELECT x FROM tbl CLUSTER BY x DESC'
3326
3327        Args:
3328            *expressions: the SQL code strings to parse.
3329                If a `Group` instance is passed, this is used as-is.
3330                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3331            append: if `True`, add to any existing expressions.
3332                Otherwise, this flattens all the `Order` expression into a single expression.
3333            dialect: the dialect used to parse the input expression.
3334            copy: if `False`, modify this expression instance in-place.
3335            opts: other options to use to parse the input expressions.
3336
3337        Returns:
3338            The modified Select expression.
3339        """
3340        return _apply_child_list_builder(
3341            *expressions,
3342            instance=self,
3343            arg="cluster",
3344            append=append,
3345            copy=copy,
3346            prefix="CLUSTER BY",
3347            into=Cluster,
3348            dialect=dialect,
3349            **opts,
3350        )
3351
3352    def select(
3353        self,
3354        *expressions: t.Optional[ExpOrStr],
3355        append: bool = True,
3356        dialect: DialectType = None,
3357        copy: bool = True,
3358        **opts,
3359    ) -> Select:
3360        return _apply_list_builder(
3361            *expressions,
3362            instance=self,
3363            arg="expressions",
3364            append=append,
3365            dialect=dialect,
3366            into=Expression,
3367            copy=copy,
3368            **opts,
3369        )
3370
3371    def lateral(
3372        self,
3373        *expressions: t.Optional[ExpOrStr],
3374        append: bool = True,
3375        dialect: DialectType = None,
3376        copy: bool = True,
3377        **opts,
3378    ) -> Select:
3379        """
3380        Append to or set the LATERAL expressions.
3381
3382        Example:
3383            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3384            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3385
3386        Args:
3387            *expressions: the SQL code strings to parse.
3388                If an `Expression` instance is passed, it will be used as-is.
3389            append: if `True`, add to any existing expressions.
3390                Otherwise, this resets the expressions.
3391            dialect: the dialect used to parse the input expressions.
3392            copy: if `False`, modify this expression instance in-place.
3393            opts: other options to use to parse the input expressions.
3394
3395        Returns:
3396            The modified Select expression.
3397        """
3398        return _apply_list_builder(
3399            *expressions,
3400            instance=self,
3401            arg="laterals",
3402            append=append,
3403            into=Lateral,
3404            prefix="LATERAL VIEW",
3405            dialect=dialect,
3406            copy=copy,
3407            **opts,
3408        )
3409
3410    def join(
3411        self,
3412        expression: ExpOrStr,
3413        on: t.Optional[ExpOrStr] = None,
3414        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3415        append: bool = True,
3416        join_type: t.Optional[str] = None,
3417        join_alias: t.Optional[Identifier | str] = None,
3418        dialect: DialectType = None,
3419        copy: bool = True,
3420        **opts,
3421    ) -> Select:
3422        """
3423        Append to or set the JOIN expressions.
3424
3425        Example:
3426            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3427            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3428
3429            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3430            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3431
3432            Use `join_type` to change the type of join:
3433
3434            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3435            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3436
3437        Args:
3438            expression: the SQL code string to parse.
3439                If an `Expression` instance is passed, it will be used as-is.
3440            on: optionally specify the join "on" criteria as a SQL string.
3441                If an `Expression` instance is passed, it will be used as-is.
3442            using: optionally specify the join "using" criteria as a SQL string.
3443                If an `Expression` instance is passed, it will be used as-is.
3444            append: if `True`, add to any existing expressions.
3445                Otherwise, this resets the expressions.
3446            join_type: if set, alter the parsed join type.
3447            join_alias: an optional alias for the joined source.
3448            dialect: the dialect used to parse the input expressions.
3449            copy: if `False`, modify this expression instance in-place.
3450            opts: other options to use to parse the input expressions.
3451
3452        Returns:
3453            Select: the modified expression.
3454        """
3455        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3456
3457        try:
3458            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3459        except ParseError:
3460            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3461
3462        join = expression if isinstance(expression, Join) else Join(this=expression)
3463
3464        if isinstance(join.this, Select):
3465            join.this.replace(join.this.subquery())
3466
3467        if join_type:
3468            method: t.Optional[Token]
3469            side: t.Optional[Token]
3470            kind: t.Optional[Token]
3471
3472            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3473
3474            if method:
3475                join.set("method", method.text)
3476            if side:
3477                join.set("side", side.text)
3478            if kind:
3479                join.set("kind", kind.text)
3480
3481        if on:
3482            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3483            join.set("on", on)
3484
3485        if using:
3486            join = _apply_list_builder(
3487                *ensure_list(using),
3488                instance=join,
3489                arg="using",
3490                append=append,
3491                copy=copy,
3492                into=Identifier,
3493                **opts,
3494            )
3495
3496        if join_alias:
3497            join.set("this", alias_(join.this, join_alias, table=True))
3498
3499        return _apply_list_builder(
3500            join,
3501            instance=self,
3502            arg="joins",
3503            append=append,
3504            copy=copy,
3505            **opts,
3506        )
3507
3508    def where(
3509        self,
3510        *expressions: t.Optional[ExpOrStr],
3511        append: bool = True,
3512        dialect: DialectType = None,
3513        copy: bool = True,
3514        **opts,
3515    ) -> Select:
3516        """
3517        Append to or set the WHERE expressions.
3518
3519        Example:
3520            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3521            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3522
3523        Args:
3524            *expressions: the SQL code strings to parse.
3525                If an `Expression` instance is passed, it will be used as-is.
3526                Multiple expressions are combined with an AND operator.
3527            append: if `True`, AND the new expressions to any existing expression.
3528                Otherwise, this resets the expression.
3529            dialect: the dialect used to parse the input expressions.
3530            copy: if `False`, modify this expression instance in-place.
3531            opts: other options to use to parse the input expressions.
3532
3533        Returns:
3534            Select: the modified expression.
3535        """
3536        return _apply_conjunction_builder(
3537            *expressions,
3538            instance=self,
3539            arg="where",
3540            append=append,
3541            into=Where,
3542            dialect=dialect,
3543            copy=copy,
3544            **opts,
3545        )
3546
3547    def having(
3548        self,
3549        *expressions: t.Optional[ExpOrStr],
3550        append: bool = True,
3551        dialect: DialectType = None,
3552        copy: bool = True,
3553        **opts,
3554    ) -> Select:
3555        """
3556        Append to or set the HAVING expressions.
3557
3558        Example:
3559            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3560            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3561
3562        Args:
3563            *expressions: the SQL code strings to parse.
3564                If an `Expression` instance is passed, it will be used as-is.
3565                Multiple expressions are combined with an AND operator.
3566            append: if `True`, AND the new expressions to any existing expression.
3567                Otherwise, this resets the expression.
3568            dialect: the dialect used to parse the input expressions.
3569            copy: if `False`, modify this expression instance in-place.
3570            opts: other options to use to parse the input expressions.
3571
3572        Returns:
3573            The modified Select expression.
3574        """
3575        return _apply_conjunction_builder(
3576            *expressions,
3577            instance=self,
3578            arg="having",
3579            append=append,
3580            into=Having,
3581            dialect=dialect,
3582            copy=copy,
3583            **opts,
3584        )
3585
3586    def window(
3587        self,
3588        *expressions: t.Optional[ExpOrStr],
3589        append: bool = True,
3590        dialect: DialectType = None,
3591        copy: bool = True,
3592        **opts,
3593    ) -> Select:
3594        return _apply_list_builder(
3595            *expressions,
3596            instance=self,
3597            arg="windows",
3598            append=append,
3599            into=Window,
3600            dialect=dialect,
3601            copy=copy,
3602            **opts,
3603        )
3604
3605    def qualify(
3606        self,
3607        *expressions: t.Optional[ExpOrStr],
3608        append: bool = True,
3609        dialect: DialectType = None,
3610        copy: bool = True,
3611        **opts,
3612    ) -> Select:
3613        return _apply_conjunction_builder(
3614            *expressions,
3615            instance=self,
3616            arg="qualify",
3617            append=append,
3618            into=Qualify,
3619            dialect=dialect,
3620            copy=copy,
3621            **opts,
3622        )
3623
3624    def distinct(
3625        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3626    ) -> Select:
3627        """
3628        Set the OFFSET expression.
3629
3630        Example:
3631            >>> Select().from_("tbl").select("x").distinct().sql()
3632            'SELECT DISTINCT x FROM tbl'
3633
3634        Args:
3635            ons: the expressions to distinct on
3636            distinct: whether the Select should be distinct
3637            copy: if `False`, modify this expression instance in-place.
3638
3639        Returns:
3640            Select: the modified expression.
3641        """
3642        instance = maybe_copy(self, copy)
3643        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3644        instance.set("distinct", Distinct(on=on) if distinct else None)
3645        return instance
3646
3647    def ctas(
3648        self,
3649        table: ExpOrStr,
3650        properties: t.Optional[t.Dict] = None,
3651        dialect: DialectType = None,
3652        copy: bool = True,
3653        **opts,
3654    ) -> Create:
3655        """
3656        Convert this expression to a CREATE TABLE AS statement.
3657
3658        Example:
3659            >>> Select().select("*").from_("tbl").ctas("x").sql()
3660            'CREATE TABLE x AS SELECT * FROM tbl'
3661
3662        Args:
3663            table: the SQL code string to parse as the table name.
3664                If another `Expression` instance is passed, it will be used as-is.
3665            properties: an optional mapping of table properties
3666            dialect: the dialect used to parse the input table.
3667            copy: if `False`, modify this expression instance in-place.
3668            opts: other options to use to parse the input table.
3669
3670        Returns:
3671            The new Create expression.
3672        """
3673        instance = maybe_copy(self, copy)
3674        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3675
3676        properties_expression = None
3677        if properties:
3678            properties_expression = Properties.from_dict(properties)
3679
3680        return Create(
3681            this=table_expression,
3682            kind="TABLE",
3683            expression=instance,
3684            properties=properties_expression,
3685        )
3686
3687    def lock(self, update: bool = True, copy: bool = True) -> Select:
3688        """
3689        Set the locking read mode for this expression.
3690
3691        Examples:
3692            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3693            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3694
3695            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3696            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3697
3698        Args:
3699            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3700            copy: if `False`, modify this expression instance in-place.
3701
3702        Returns:
3703            The modified expression.
3704        """
3705        inst = maybe_copy(self, copy)
3706        inst.set("locks", [Lock(update=update)])
3707
3708        return inst
3709
3710    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3711        """
3712        Set hints for this expression.
3713
3714        Examples:
3715            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3716            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3717
3718        Args:
3719            hints: The SQL code strings to parse as the hints.
3720                If an `Expression` instance is passed, it will be used as-is.
3721            dialect: The dialect used to parse the hints.
3722            copy: If `False`, modify this expression instance in-place.
3723
3724        Returns:
3725            The modified expression.
3726        """
3727        inst = maybe_copy(self, copy)
3728        inst.set(
3729            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3730        )
3731
3732        return inst
3733
3734    @property
3735    def named_selects(self) -> t.List[str]:
3736        return [e.output_name for e in self.expressions if e.alias_or_name]
3737
3738    @property
3739    def is_star(self) -> bool:
3740        return any(expression.is_star for expression in self.expressions)
3741
3742    @property
3743    def selects(self) -> t.List[Expression]:
3744        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, 'prewhere': 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, 'options': 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:
3196    def from_(
3197        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3198    ) -> Select:
3199        """
3200        Set the FROM expression.
3201
3202        Example:
3203            >>> Select().from_("tbl").select("x").sql()
3204            'SELECT x FROM tbl'
3205
3206        Args:
3207            expression : the SQL code strings to parse.
3208                If a `From` instance is passed, this is used as-is.
3209                If another `Expression` instance is passed, it will be wrapped in a `From`.
3210            dialect: the dialect used to parse the input expression.
3211            copy: if `False`, modify this expression instance in-place.
3212            opts: other options to use to parse the input expressions.
3213
3214        Returns:
3215            The modified Select expression.
3216        """
3217        return _apply_builder(
3218            expression=expression,
3219            instance=self,
3220            arg="from",
3221            into=From,
3222            prefix="FROM",
3223            dialect=dialect,
3224            copy=copy,
3225            **opts,
3226        )

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:
3228    def group_by(
3229        self,
3230        *expressions: t.Optional[ExpOrStr],
3231        append: bool = True,
3232        dialect: DialectType = None,
3233        copy: bool = True,
3234        **opts,
3235    ) -> Select:
3236        """
3237        Set the GROUP BY expression.
3238
3239        Example:
3240            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3241            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3242
3243        Args:
3244            *expressions: the SQL code strings to parse.
3245                If a `Group` instance is passed, this is used as-is.
3246                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3247                If nothing is passed in then a group by is not applied to the expression
3248            append: if `True`, add to any existing expressions.
3249                Otherwise, this flattens all the `Group` expression into a single expression.
3250            dialect: the dialect used to parse the input expression.
3251            copy: if `False`, modify this expression instance in-place.
3252            opts: other options to use to parse the input expressions.
3253
3254        Returns:
3255            The modified Select expression.
3256        """
3257        if not expressions:
3258            return self if not copy else self.copy()
3259
3260        return _apply_child_list_builder(
3261            *expressions,
3262            instance=self,
3263            arg="group",
3264            append=append,
3265            copy=copy,
3266            prefix="GROUP BY",
3267            into=Group,
3268            dialect=dialect,
3269            **opts,
3270        )

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 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:
3272    def sort_by(
3273        self,
3274        *expressions: t.Optional[ExpOrStr],
3275        append: bool = True,
3276        dialect: DialectType = None,
3277        copy: bool = True,
3278        **opts,
3279    ) -> Select:
3280        """
3281        Set the SORT BY expression.
3282
3283        Example:
3284            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3285            'SELECT x FROM tbl SORT BY x DESC'
3286
3287        Args:
3288            *expressions: the SQL code strings to parse.
3289                If a `Group` instance is passed, this is used as-is.
3290                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3291            append: if `True`, add to any existing expressions.
3292                Otherwise, this flattens all the `Order` expression into a single expression.
3293            dialect: the dialect used to parse the input expression.
3294            copy: if `False`, modify this expression instance in-place.
3295            opts: other options to use to parse the input expressions.
3296
3297        Returns:
3298            The modified Select expression.
3299        """
3300        return _apply_child_list_builder(
3301            *expressions,
3302            instance=self,
3303            arg="sort",
3304            append=append,
3305            copy=copy,
3306            prefix="SORT BY",
3307            into=Sort,
3308            dialect=dialect,
3309            **opts,
3310        )

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:
3312    def cluster_by(
3313        self,
3314        *expressions: t.Optional[ExpOrStr],
3315        append: bool = True,
3316        dialect: DialectType = None,
3317        copy: bool = True,
3318        **opts,
3319    ) -> Select:
3320        """
3321        Set the CLUSTER BY expression.
3322
3323        Example:
3324            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3325            'SELECT x FROM tbl CLUSTER BY x DESC'
3326
3327        Args:
3328            *expressions: the SQL code strings to parse.
3329                If a `Group` instance is passed, this is used as-is.
3330                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3331            append: if `True`, add to any existing expressions.
3332                Otherwise, this flattens all the `Order` expression into a single expression.
3333            dialect: the dialect used to parse the input expression.
3334            copy: if `False`, modify this expression instance in-place.
3335            opts: other options to use to parse the input expressions.
3336
3337        Returns:
3338            The modified Select expression.
3339        """
3340        return _apply_child_list_builder(
3341            *expressions,
3342            instance=self,
3343            arg="cluster",
3344            append=append,
3345            copy=copy,
3346            prefix="CLUSTER BY",
3347            into=Cluster,
3348            dialect=dialect,
3349            **opts,
3350        )

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 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:
3352    def select(
3353        self,
3354        *expressions: t.Optional[ExpOrStr],
3355        append: bool = True,
3356        dialect: DialectType = None,
3357        copy: bool = True,
3358        **opts,
3359    ) -> Select:
3360        return _apply_list_builder(
3361            *expressions,
3362            instance=self,
3363            arg="expressions",
3364            append=append,
3365            dialect=dialect,
3366            into=Expression,
3367            copy=copy,
3368            **opts,
3369        )

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 Query 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:
3371    def lateral(
3372        self,
3373        *expressions: t.Optional[ExpOrStr],
3374        append: bool = True,
3375        dialect: DialectType = None,
3376        copy: bool = True,
3377        **opts,
3378    ) -> Select:
3379        """
3380        Append to or set the LATERAL expressions.
3381
3382        Example:
3383            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3384            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3385
3386        Args:
3387            *expressions: the SQL code strings to parse.
3388                If an `Expression` instance is passed, it will be used as-is.
3389            append: if `True`, add to any existing expressions.
3390                Otherwise, this resets the expressions.
3391            dialect: the dialect used to parse the input expressions.
3392            copy: if `False`, modify this expression instance in-place.
3393            opts: other options to use to parse the input expressions.
3394
3395        Returns:
3396            The modified Select expression.
3397        """
3398        return _apply_list_builder(
3399            *expressions,
3400            instance=self,
3401            arg="laterals",
3402            append=append,
3403            into=Lateral,
3404            prefix="LATERAL VIEW",
3405            dialect=dialect,
3406            copy=copy,
3407            **opts,
3408        )

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:
3410    def join(
3411        self,
3412        expression: ExpOrStr,
3413        on: t.Optional[ExpOrStr] = None,
3414        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3415        append: bool = True,
3416        join_type: t.Optional[str] = None,
3417        join_alias: t.Optional[Identifier | str] = None,
3418        dialect: DialectType = None,
3419        copy: bool = True,
3420        **opts,
3421    ) -> Select:
3422        """
3423        Append to or set the JOIN expressions.
3424
3425        Example:
3426            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3427            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3428
3429            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3430            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3431
3432            Use `join_type` to change the type of join:
3433
3434            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3435            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3436
3437        Args:
3438            expression: the SQL code string to parse.
3439                If an `Expression` instance is passed, it will be used as-is.
3440            on: optionally specify the join "on" criteria as a SQL string.
3441                If an `Expression` instance is passed, it will be used as-is.
3442            using: optionally specify the join "using" criteria as a SQL string.
3443                If an `Expression` instance is passed, it will be used as-is.
3444            append: if `True`, add to any existing expressions.
3445                Otherwise, this resets the expressions.
3446            join_type: if set, alter the parsed join type.
3447            join_alias: an optional alias for the joined source.
3448            dialect: the dialect used to parse the input expressions.
3449            copy: if `False`, modify this expression instance in-place.
3450            opts: other options to use to parse the input expressions.
3451
3452        Returns:
3453            Select: the modified expression.
3454        """
3455        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3456
3457        try:
3458            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3459        except ParseError:
3460            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3461
3462        join = expression if isinstance(expression, Join) else Join(this=expression)
3463
3464        if isinstance(join.this, Select):
3465            join.this.replace(join.this.subquery())
3466
3467        if join_type:
3468            method: t.Optional[Token]
3469            side: t.Optional[Token]
3470            kind: t.Optional[Token]
3471
3472            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3473
3474            if method:
3475                join.set("method", method.text)
3476            if side:
3477                join.set("side", side.text)
3478            if kind:
3479                join.set("kind", kind.text)
3480
3481        if on:
3482            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3483            join.set("on", on)
3484
3485        if using:
3486            join = _apply_list_builder(
3487                *ensure_list(using),
3488                instance=join,
3489                arg="using",
3490                append=append,
3491                copy=copy,
3492                into=Identifier,
3493                **opts,
3494            )
3495
3496        if join_alias:
3497            join.set("this", alias_(join.this, join_alias, table=True))
3498
3499        return _apply_list_builder(
3500            join,
3501            instance=self,
3502            arg="joins",
3503            append=append,
3504            copy=copy,
3505            **opts,
3506        )

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:
3508    def where(
3509        self,
3510        *expressions: t.Optional[ExpOrStr],
3511        append: bool = True,
3512        dialect: DialectType = None,
3513        copy: bool = True,
3514        **opts,
3515    ) -> Select:
3516        """
3517        Append to or set the WHERE expressions.
3518
3519        Example:
3520            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3521            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3522
3523        Args:
3524            *expressions: the SQL code strings to parse.
3525                If an `Expression` instance is passed, it will be used as-is.
3526                Multiple expressions are combined with an AND operator.
3527            append: if `True`, AND the new expressions to any existing expression.
3528                Otherwise, this resets the expression.
3529            dialect: the dialect used to parse the input expressions.
3530            copy: if `False`, modify this expression instance in-place.
3531            opts: other options to use to parse the input expressions.
3532
3533        Returns:
3534            Select: the modified expression.
3535        """
3536        return _apply_conjunction_builder(
3537            *expressions,
3538            instance=self,
3539            arg="where",
3540            append=append,
3541            into=Where,
3542            dialect=dialect,
3543            copy=copy,
3544            **opts,
3545        )

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:
3547    def having(
3548        self,
3549        *expressions: t.Optional[ExpOrStr],
3550        append: bool = True,
3551        dialect: DialectType = None,
3552        copy: bool = True,
3553        **opts,
3554    ) -> Select:
3555        """
3556        Append to or set the HAVING expressions.
3557
3558        Example:
3559            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3560            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3561
3562        Args:
3563            *expressions: the SQL code strings to parse.
3564                If an `Expression` instance is passed, it will be used as-is.
3565                Multiple expressions are combined with an AND operator.
3566            append: if `True`, AND the new expressions to any existing expression.
3567                Otherwise, this resets the expression.
3568            dialect: the dialect used to parse the input expressions.
3569            copy: if `False`, modify this expression instance in-place.
3570            opts: other options to use to parse the input expressions.
3571
3572        Returns:
3573            The modified Select expression.
3574        """
3575        return _apply_conjunction_builder(
3576            *expressions,
3577            instance=self,
3578            arg="having",
3579            append=append,
3580            into=Having,
3581            dialect=dialect,
3582            copy=copy,
3583            **opts,
3584        )

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:
3586    def window(
3587        self,
3588        *expressions: t.Optional[ExpOrStr],
3589        append: bool = True,
3590        dialect: DialectType = None,
3591        copy: bool = True,
3592        **opts,
3593    ) -> Select:
3594        return _apply_list_builder(
3595            *expressions,
3596            instance=self,
3597            arg="windows",
3598            append=append,
3599            into=Window,
3600            dialect=dialect,
3601            copy=copy,
3602            **opts,
3603        )
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:
3605    def qualify(
3606        self,
3607        *expressions: t.Optional[ExpOrStr],
3608        append: bool = True,
3609        dialect: DialectType = None,
3610        copy: bool = True,
3611        **opts,
3612    ) -> Select:
3613        return _apply_conjunction_builder(
3614            *expressions,
3615            instance=self,
3616            arg="qualify",
3617            append=append,
3618            into=Qualify,
3619            dialect=dialect,
3620            copy=copy,
3621            **opts,
3622        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3624    def distinct(
3625        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3626    ) -> Select:
3627        """
3628        Set the OFFSET expression.
3629
3630        Example:
3631            >>> Select().from_("tbl").select("x").distinct().sql()
3632            'SELECT DISTINCT x FROM tbl'
3633
3634        Args:
3635            ons: the expressions to distinct on
3636            distinct: whether the Select should be distinct
3637            copy: if `False`, modify this expression instance in-place.
3638
3639        Returns:
3640            Select: the modified expression.
3641        """
3642        instance = maybe_copy(self, copy)
3643        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3644        instance.set("distinct", Distinct(on=on) if distinct else None)
3645        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:
3647    def ctas(
3648        self,
3649        table: ExpOrStr,
3650        properties: t.Optional[t.Dict] = None,
3651        dialect: DialectType = None,
3652        copy: bool = True,
3653        **opts,
3654    ) -> Create:
3655        """
3656        Convert this expression to a CREATE TABLE AS statement.
3657
3658        Example:
3659            >>> Select().select("*").from_("tbl").ctas("x").sql()
3660            'CREATE TABLE x AS SELECT * FROM tbl'
3661
3662        Args:
3663            table: the SQL code string to parse as the table name.
3664                If another `Expression` instance is passed, it will be used as-is.
3665            properties: an optional mapping of table properties
3666            dialect: the dialect used to parse the input table.
3667            copy: if `False`, modify this expression instance in-place.
3668            opts: other options to use to parse the input table.
3669
3670        Returns:
3671            The new Create expression.
3672        """
3673        instance = maybe_copy(self, copy)
3674        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3675
3676        properties_expression = None
3677        if properties:
3678            properties_expression = Properties.from_dict(properties)
3679
3680        return Create(
3681            this=table_expression,
3682            kind="TABLE",
3683            expression=instance,
3684            properties=properties_expression,
3685        )

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:
3687    def lock(self, update: bool = True, copy: bool = True) -> Select:
3688        """
3689        Set the locking read mode for this expression.
3690
3691        Examples:
3692            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3693            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3694
3695            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3696            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3697
3698        Args:
3699            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3700            copy: if `False`, modify this expression instance in-place.
3701
3702        Returns:
3703            The modified expression.
3704        """
3705        inst = maybe_copy(self, copy)
3706        inst.set("locks", [Lock(update=update)])
3707
3708        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:
3710    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3711        """
3712        Set hints for this expression.
3713
3714        Examples:
3715            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3716            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3717
3718        Args:
3719            hints: The SQL code strings to parse as the hints.
3720                If an `Expression` instance is passed, it will be used as-is.
3721            dialect: The dialect used to parse the hints.
3722            copy: If `False`, modify this expression instance in-place.
3723
3724        Returns:
3725            The modified expression.
3726        """
3727        inst = maybe_copy(self, copy)
3728        inst.set(
3729            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3730        )
3731
3732        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]
3734    @property
3735    def named_selects(self) -> t.List[str]:
3736        return [e.output_name for e in self.expressions if e.alias_or_name]

Returns the output names of the query's projections.

is_star: bool
3738    @property
3739    def is_star(self) -> bool:
3740        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3742    @property
3743    def selects(self) -> t.List[Expression]:
3744        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'Union'>)
class Subquery(DerivedTable, Query):
3750class Subquery(DerivedTable, Query):
3751    arg_types = {
3752        "this": True,
3753        "alias": False,
3754        "with": False,
3755        **QUERY_MODIFIERS,
3756    }
3757
3758    def unnest(self):
3759        """Returns the first non subquery."""
3760        expression = self
3761        while isinstance(expression, Subquery):
3762            expression = expression.this
3763        return expression
3764
3765    def unwrap(self) -> Subquery:
3766        expression = self
3767        while expression.same_parent and expression.is_wrapper:
3768            expression = t.cast(Subquery, expression.parent)
3769        return expression
3770
3771    def select(
3772        self,
3773        *expressions: t.Optional[ExpOrStr],
3774        append: bool = True,
3775        dialect: DialectType = None,
3776        copy: bool = True,
3777        **opts,
3778    ) -> Subquery:
3779        this = maybe_copy(self, copy)
3780        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3781        return this
3782
3783    @property
3784    def is_wrapper(self) -> bool:
3785        """
3786        Whether this Subquery acts as a simple wrapper around another expression.
3787
3788        SELECT * FROM (((SELECT * FROM t)))
3789                      ^
3790                      This corresponds to a "wrapper" Subquery node
3791        """
3792        return all(v is None for k, v in self.args.items() if k != "this")
3793
3794    @property
3795    def is_star(self) -> bool:
3796        return self.this.is_star
3797
3798    @property
3799    def output_name(self) -> str:
3800        return self.alias
arg_types = {'this': True, 'alias': False, 'with': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': 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, 'options': False}
def unnest(self):
3758    def unnest(self):
3759        """Returns the first non subquery."""
3760        expression = self
3761        while isinstance(expression, Subquery):
3762            expression = expression.this
3763        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3765    def unwrap(self) -> Subquery:
3766        expression = self
3767        while expression.same_parent and expression.is_wrapper:
3768            expression = t.cast(Subquery, expression.parent)
3769        return 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) -> Subquery:
3771    def select(
3772        self,
3773        *expressions: t.Optional[ExpOrStr],
3774        append: bool = True,
3775        dialect: DialectType = None,
3776        copy: bool = True,
3777        **opts,
3778    ) -> Subquery:
3779        this = maybe_copy(self, copy)
3780        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3781        return this

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 Query expression.

is_wrapper: bool
3783    @property
3784    def is_wrapper(self) -> bool:
3785        """
3786        Whether this Subquery acts as a simple wrapper around another expression.
3787
3788        SELECT * FROM (((SELECT * FROM t)))
3789                      ^
3790                      This corresponds to a "wrapper" Subquery node
3791        """
3792        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
3794    @property
3795    def is_star(self) -> bool:
3796        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3798    @property
3799    def output_name(self) -> str:
3800        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):
3803class TableSample(Expression):
3804    arg_types = {
3805        "this": False,
3806        "expressions": False,
3807        "method": False,
3808        "bucket_numerator": False,
3809        "bucket_denominator": False,
3810        "bucket_field": False,
3811        "percent": False,
3812        "rows": False,
3813        "size": False,
3814        "seed": False,
3815    }
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):
3818class Tag(Expression):
3819    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3820
3821    arg_types = {
3822        "this": False,
3823        "prefix": False,
3824        "postfix": False,
3825    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3830class Pivot(Expression):
3831    arg_types = {
3832        "this": False,
3833        "alias": False,
3834        "expressions": False,
3835        "field": False,
3836        "unpivot": False,
3837        "using": False,
3838        "group": False,
3839        "columns": False,
3840        "include_nulls": False,
3841    }
3842
3843    @property
3844    def unpivot(self) -> bool:
3845        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
3843    @property
3844    def unpivot(self) -> bool:
3845        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3848class Window(Condition):
3849    arg_types = {
3850        "this": True,
3851        "partition_by": False,
3852        "order": False,
3853        "spec": False,
3854        "alias": False,
3855        "over": False,
3856        "first": False,
3857    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3860class WindowSpec(Expression):
3861    arg_types = {
3862        "kind": False,
3863        "start": False,
3864        "start_side": False,
3865        "end": False,
3866        "end_side": False,
3867    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3870class PreWhere(Expression):
3871    pass
key = 'prewhere'
class Where(Expression):
3874class Where(Expression):
3875    pass
key = 'where'
class Star(Expression):
3878class Star(Expression):
3879    arg_types = {"except": False, "replace": False, "rename": False}
3880
3881    @property
3882    def name(self) -> str:
3883        return "*"
3884
3885    @property
3886    def output_name(self) -> str:
3887        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3881    @property
3882    def name(self) -> str:
3883        return "*"
output_name: str
3885    @property
3886    def output_name(self) -> str:
3887        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):
3890class Parameter(Condition):
3891    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3894class SessionParameter(Condition):
3895    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3898class Placeholder(Condition):
3899    arg_types = {"this": False, "kind": False}
3900
3901    @property
3902    def name(self) -> str:
3903        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3901    @property
3902    def name(self) -> str:
3903        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3906class Null(Condition):
3907    arg_types: t.Dict[str, t.Any] = {}
3908
3909    @property
3910    def name(self) -> str:
3911        return "NULL"
arg_types: Dict[str, Any] = {}
name: str
3909    @property
3910    def name(self) -> str:
3911        return "NULL"
key = 'null'
class Boolean(Condition):
3914class Boolean(Condition):
3915    pass
key = 'boolean'
class DataTypeParam(Expression):
3918class DataTypeParam(Expression):
3919    arg_types = {"this": True, "expression": False}
3920
3921    @property
3922    def name(self) -> str:
3923        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3921    @property
3922    def name(self) -> str:
3923        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3926class DataType(Expression):
3927    arg_types = {
3928        "this": True,
3929        "expressions": False,
3930        "nested": False,
3931        "values": False,
3932        "prefix": False,
3933        "kind": False,
3934    }
3935
3936    class Type(AutoName):
3937        ARRAY = auto()
3938        AGGREGATEFUNCTION = auto()
3939        SIMPLEAGGREGATEFUNCTION = auto()
3940        BIGDECIMAL = auto()
3941        BIGINT = auto()
3942        BIGSERIAL = auto()
3943        BINARY = auto()
3944        BIT = auto()
3945        BOOLEAN = auto()
3946        BPCHAR = auto()
3947        CHAR = auto()
3948        DATE = auto()
3949        DATE32 = auto()
3950        DATEMULTIRANGE = auto()
3951        DATERANGE = auto()
3952        DATETIME = auto()
3953        DATETIME64 = auto()
3954        DECIMAL = auto()
3955        DOUBLE = auto()
3956        ENUM = auto()
3957        ENUM8 = auto()
3958        ENUM16 = auto()
3959        FIXEDSTRING = auto()
3960        FLOAT = auto()
3961        GEOGRAPHY = auto()
3962        GEOMETRY = auto()
3963        HLLSKETCH = auto()
3964        HSTORE = auto()
3965        IMAGE = auto()
3966        INET = auto()
3967        INT = auto()
3968        INT128 = auto()
3969        INT256 = auto()
3970        INT4MULTIRANGE = auto()
3971        INT4RANGE = auto()
3972        INT8MULTIRANGE = auto()
3973        INT8RANGE = auto()
3974        INTERVAL = auto()
3975        IPADDRESS = auto()
3976        IPPREFIX = auto()
3977        IPV4 = auto()
3978        IPV6 = auto()
3979        JSON = auto()
3980        JSONB = auto()
3981        LONGBLOB = auto()
3982        LONGTEXT = auto()
3983        LOWCARDINALITY = auto()
3984        MAP = auto()
3985        MEDIUMBLOB = auto()
3986        MEDIUMINT = auto()
3987        MEDIUMTEXT = auto()
3988        MONEY = auto()
3989        NAME = auto()
3990        NCHAR = auto()
3991        NESTED = auto()
3992        NULL = auto()
3993        NULLABLE = auto()
3994        NUMMULTIRANGE = auto()
3995        NUMRANGE = auto()
3996        NVARCHAR = auto()
3997        OBJECT = auto()
3998        ROWVERSION = auto()
3999        SERIAL = auto()
4000        SET = auto()
4001        SMALLINT = auto()
4002        SMALLMONEY = auto()
4003        SMALLSERIAL = auto()
4004        STRUCT = auto()
4005        SUPER = auto()
4006        TEXT = auto()
4007        TINYBLOB = auto()
4008        TINYTEXT = auto()
4009        TIME = auto()
4010        TIMETZ = auto()
4011        TIMESTAMP = auto()
4012        TIMESTAMPNTZ = auto()
4013        TIMESTAMPLTZ = auto()
4014        TIMESTAMPTZ = auto()
4015        TIMESTAMP_S = auto()
4016        TIMESTAMP_MS = auto()
4017        TIMESTAMP_NS = auto()
4018        TINYINT = auto()
4019        TSMULTIRANGE = auto()
4020        TSRANGE = auto()
4021        TSTZMULTIRANGE = auto()
4022        TSTZRANGE = auto()
4023        UBIGINT = auto()
4024        UINT = auto()
4025        UINT128 = auto()
4026        UINT256 = auto()
4027        UMEDIUMINT = auto()
4028        UDECIMAL = auto()
4029        UNIQUEIDENTIFIER = auto()
4030        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4031        USERDEFINED = "USER-DEFINED"
4032        USMALLINT = auto()
4033        UTINYINT = auto()
4034        UUID = auto()
4035        VARBINARY = auto()
4036        VARCHAR = auto()
4037        VARIANT = auto()
4038        XML = auto()
4039        YEAR = auto()
4040        TDIGEST = auto()
4041
4042    STRUCT_TYPES = {
4043        Type.NESTED,
4044        Type.OBJECT,
4045        Type.STRUCT,
4046    }
4047
4048    NESTED_TYPES = {
4049        *STRUCT_TYPES,
4050        Type.ARRAY,
4051        Type.MAP,
4052    }
4053
4054    TEXT_TYPES = {
4055        Type.CHAR,
4056        Type.NCHAR,
4057        Type.NVARCHAR,
4058        Type.TEXT,
4059        Type.VARCHAR,
4060        Type.NAME,
4061    }
4062
4063    SIGNED_INTEGER_TYPES = {
4064        Type.BIGINT,
4065        Type.INT,
4066        Type.INT128,
4067        Type.INT256,
4068        Type.MEDIUMINT,
4069        Type.SMALLINT,
4070        Type.TINYINT,
4071    }
4072
4073    UNSIGNED_INTEGER_TYPES = {
4074        Type.UBIGINT,
4075        Type.UINT,
4076        Type.UINT128,
4077        Type.UINT256,
4078        Type.UMEDIUMINT,
4079        Type.USMALLINT,
4080        Type.UTINYINT,
4081    }
4082
4083    INTEGER_TYPES = {
4084        *SIGNED_INTEGER_TYPES,
4085        *UNSIGNED_INTEGER_TYPES,
4086        Type.BIT,
4087    }
4088
4089    FLOAT_TYPES = {
4090        Type.DOUBLE,
4091        Type.FLOAT,
4092    }
4093
4094    REAL_TYPES = {
4095        *FLOAT_TYPES,
4096        Type.BIGDECIMAL,
4097        Type.DECIMAL,
4098        Type.MONEY,
4099        Type.SMALLMONEY,
4100        Type.UDECIMAL,
4101    }
4102
4103    NUMERIC_TYPES = {
4104        *INTEGER_TYPES,
4105        *REAL_TYPES,
4106    }
4107
4108    TEMPORAL_TYPES = {
4109        Type.DATE,
4110        Type.DATE32,
4111        Type.DATETIME,
4112        Type.DATETIME64,
4113        Type.TIME,
4114        Type.TIMESTAMP,
4115        Type.TIMESTAMPNTZ,
4116        Type.TIMESTAMPLTZ,
4117        Type.TIMESTAMPTZ,
4118        Type.TIMESTAMP_MS,
4119        Type.TIMESTAMP_NS,
4120        Type.TIMESTAMP_S,
4121        Type.TIMETZ,
4122    }
4123
4124    @classmethod
4125    def build(
4126        cls,
4127        dtype: DATA_TYPE,
4128        dialect: DialectType = None,
4129        udt: bool = False,
4130        copy: bool = True,
4131        **kwargs,
4132    ) -> DataType:
4133        """
4134        Constructs a DataType object.
4135
4136        Args:
4137            dtype: the data type of interest.
4138            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4139            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4140                DataType, thus creating a user-defined type.
4141            copy: whether to copy the data type.
4142            kwargs: additional arguments to pass in the constructor of DataType.
4143
4144        Returns:
4145            The constructed DataType object.
4146        """
4147        from sqlglot import parse_one
4148
4149        if isinstance(dtype, str):
4150            if dtype.upper() == "UNKNOWN":
4151                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4152
4153            try:
4154                data_type_exp = parse_one(
4155                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4156                )
4157            except ParseError:
4158                if udt:
4159                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4160                raise
4161        elif isinstance(dtype, DataType.Type):
4162            data_type_exp = DataType(this=dtype)
4163        elif isinstance(dtype, DataType):
4164            return maybe_copy(dtype, copy)
4165        else:
4166            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4167
4168        return DataType(**{**data_type_exp.args, **kwargs})
4169
4170    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4171        """
4172        Checks whether this DataType matches one of the provided data types. Nested types or precision
4173        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4174
4175        Args:
4176            dtypes: the data types to compare this DataType to.
4177
4178        Returns:
4179            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4180        """
4181        for dtype in dtypes:
4182            other = DataType.build(dtype, copy=False, udt=True)
4183
4184            if (
4185                other.expressions
4186                or self.this == DataType.Type.USERDEFINED
4187                or other.this == DataType.Type.USERDEFINED
4188            ):
4189                matches = self == other
4190            else:
4191                matches = self.this == other.this
4192
4193            if matches:
4194                return True
4195        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>}
NESTED_TYPES = {<Type.MAP: 'MAP'>, <Type.ARRAY: 'ARRAY'>, <Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>}
TEXT_TYPES = {<Type.TEXT: 'TEXT'>, <Type.CHAR: 'CHAR'>, <Type.NAME: 'NAME'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.INT128: 'INT128'>, <Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>}
UNSIGNED_INTEGER_TYPES = {<Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>}
INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UBIGINT: 'UBIGINT'>, <Type.BIT: 'BIT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.UINT128: 'UINT128'>, <Type.INT: 'INT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.MONEY: 'MONEY'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UINT: 'UINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>, <Type.MONEY: 'MONEY'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UBIGINT: 'UBIGINT'>, <Type.BIT: 'BIT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>, <Type.FLOAT: 'FLOAT'>}
TEMPORAL_TYPES = {<Type.TIME: 'TIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME: 'DATETIME'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATETIME64: 'DATETIME64'>}
@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, copy: bool = True, **kwargs) -> DataType:
4124    @classmethod
4125    def build(
4126        cls,
4127        dtype: DATA_TYPE,
4128        dialect: DialectType = None,
4129        udt: bool = False,
4130        copy: bool = True,
4131        **kwargs,
4132    ) -> DataType:
4133        """
4134        Constructs a DataType object.
4135
4136        Args:
4137            dtype: the data type of interest.
4138            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4139            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4140                DataType, thus creating a user-defined type.
4141            copy: whether to copy the data type.
4142            kwargs: additional arguments to pass in the constructor of DataType.
4143
4144        Returns:
4145            The constructed DataType object.
4146        """
4147        from sqlglot import parse_one
4148
4149        if isinstance(dtype, str):
4150            if dtype.upper() == "UNKNOWN":
4151                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4152
4153            try:
4154                data_type_exp = parse_one(
4155                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4156                )
4157            except ParseError:
4158                if udt:
4159                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4160                raise
4161        elif isinstance(dtype, DataType.Type):
4162            data_type_exp = DataType(this=dtype)
4163        elif isinstance(dtype, DataType):
4164            return maybe_copy(dtype, copy)
4165        else:
4166            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4167
4168        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.
  • copy: whether to copy the data type.
  • kwargs: 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:
4170    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4171        """
4172        Checks whether this DataType matches one of the provided data types. Nested types or precision
4173        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4174
4175        Args:
4176            dtypes: the data types to compare this DataType to.
4177
4178        Returns:
4179            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4180        """
4181        for dtype in dtypes:
4182            other = DataType.build(dtype, copy=False, udt=True)
4183
4184            if (
4185                other.expressions
4186                or self.this == DataType.Type.USERDEFINED
4187                or other.this == DataType.Type.USERDEFINED
4188            ):
4189                matches = self == other
4190            else:
4191                matches = self.this == other.this
4192
4193            if matches:
4194                return True
4195        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):
3936    class Type(AutoName):
3937        ARRAY = auto()
3938        AGGREGATEFUNCTION = auto()
3939        SIMPLEAGGREGATEFUNCTION = auto()
3940        BIGDECIMAL = auto()
3941        BIGINT = auto()
3942        BIGSERIAL = auto()
3943        BINARY = auto()
3944        BIT = auto()
3945        BOOLEAN = auto()
3946        BPCHAR = auto()
3947        CHAR = auto()
3948        DATE = auto()
3949        DATE32 = auto()
3950        DATEMULTIRANGE = auto()
3951        DATERANGE = auto()
3952        DATETIME = auto()
3953        DATETIME64 = auto()
3954        DECIMAL = auto()
3955        DOUBLE = auto()
3956        ENUM = auto()
3957        ENUM8 = auto()
3958        ENUM16 = auto()
3959        FIXEDSTRING = auto()
3960        FLOAT = auto()
3961        GEOGRAPHY = auto()
3962        GEOMETRY = auto()
3963        HLLSKETCH = auto()
3964        HSTORE = auto()
3965        IMAGE = auto()
3966        INET = auto()
3967        INT = auto()
3968        INT128 = auto()
3969        INT256 = auto()
3970        INT4MULTIRANGE = auto()
3971        INT4RANGE = auto()
3972        INT8MULTIRANGE = auto()
3973        INT8RANGE = auto()
3974        INTERVAL = auto()
3975        IPADDRESS = auto()
3976        IPPREFIX = auto()
3977        IPV4 = auto()
3978        IPV6 = auto()
3979        JSON = auto()
3980        JSONB = auto()
3981        LONGBLOB = auto()
3982        LONGTEXT = auto()
3983        LOWCARDINALITY = auto()
3984        MAP = auto()
3985        MEDIUMBLOB = auto()
3986        MEDIUMINT = auto()
3987        MEDIUMTEXT = auto()
3988        MONEY = auto()
3989        NAME = auto()
3990        NCHAR = auto()
3991        NESTED = auto()
3992        NULL = auto()
3993        NULLABLE = auto()
3994        NUMMULTIRANGE = auto()
3995        NUMRANGE = auto()
3996        NVARCHAR = auto()
3997        OBJECT = auto()
3998        ROWVERSION = auto()
3999        SERIAL = auto()
4000        SET = auto()
4001        SMALLINT = auto()
4002        SMALLMONEY = auto()
4003        SMALLSERIAL = auto()
4004        STRUCT = auto()
4005        SUPER = auto()
4006        TEXT = auto()
4007        TINYBLOB = auto()
4008        TINYTEXT = auto()
4009        TIME = auto()
4010        TIMETZ = auto()
4011        TIMESTAMP = auto()
4012        TIMESTAMPNTZ = auto()
4013        TIMESTAMPLTZ = auto()
4014        TIMESTAMPTZ = auto()
4015        TIMESTAMP_S = auto()
4016        TIMESTAMP_MS = auto()
4017        TIMESTAMP_NS = auto()
4018        TINYINT = auto()
4019        TSMULTIRANGE = auto()
4020        TSRANGE = auto()
4021        TSTZMULTIRANGE = auto()
4022        TSTZRANGE = auto()
4023        UBIGINT = auto()
4024        UINT = auto()
4025        UINT128 = auto()
4026        UINT256 = auto()
4027        UMEDIUMINT = auto()
4028        UDECIMAL = auto()
4029        UNIQUEIDENTIFIER = auto()
4030        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4031        USERDEFINED = "USER-DEFINED"
4032        USMALLINT = auto()
4033        UTINYINT = auto()
4034        UUID = auto()
4035        VARBINARY = auto()
4036        VARCHAR = auto()
4037        VARIANT = auto()
4038        XML = auto()
4039        YEAR = auto()
4040        TDIGEST = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
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'>
NAME = <Type.NAME: 'NAME'>
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'>
TIMESTAMPNTZ = <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>
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'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
Inherited Members
enum.Enum
name
value
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4202class PseudoType(DataType):
4203    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4207class ObjectIdentifier(DataType):
4208    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4212class SubqueryPredicate(Predicate):
4213    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4216class All(SubqueryPredicate):
4217    pass
key = 'all'
class Any(SubqueryPredicate):
4220class Any(SubqueryPredicate):
4221    pass
key = 'any'
class Exists(SubqueryPredicate):
4224class Exists(SubqueryPredicate):
4225    pass
key = 'exists'
class Command(Expression):
4230class Command(Expression):
4231    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4234class Transaction(Expression):
4235    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4238class Commit(Expression):
4239    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4242class Rollback(Expression):
4243    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4246class AlterTable(Expression):
4247    arg_types = {
4248        "this": True,
4249        "actions": True,
4250        "exists": False,
4251        "only": False,
4252        "options": False,
4253        "cluster": False,
4254    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False}
key = 'altertable'
class AddConstraint(Expression):
4257class AddConstraint(Expression):
4258    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4261class DropPartition(Expression):
4262    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4266class ReplacePartition(Expression):
4267    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4271class Binary(Condition):
4272    arg_types = {"this": True, "expression": True}
4273
4274    @property
4275    def left(self) -> Expression:
4276        return self.this
4277
4278    @property
4279    def right(self) -> Expression:
4280        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4274    @property
4275    def left(self) -> Expression:
4276        return self.this
right: Expression
4278    @property
4279    def right(self) -> Expression:
4280        return self.expression
key = 'binary'
class Add(Binary):
4283class Add(Binary):
4284    pass
key = 'add'
class Connector(Binary):
4287class Connector(Binary):
4288    pass
key = 'connector'
class And(Connector):
4291class And(Connector):
4292    pass
key = 'and'
class Or(Connector):
4295class Or(Connector):
4296    pass
key = 'or'
class BitwiseAnd(Binary):
4299class BitwiseAnd(Binary):
4300    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4303class BitwiseLeftShift(Binary):
4304    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4307class BitwiseOr(Binary):
4308    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4311class BitwiseRightShift(Binary):
4312    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4315class BitwiseXor(Binary):
4316    pass
key = 'bitwisexor'
class Div(Binary):
4319class Div(Binary):
4320    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):
4323class Overlaps(Binary):
4324    pass
key = 'overlaps'
class Dot(Binary):
4327class Dot(Binary):
4328    @property
4329    def is_star(self) -> bool:
4330        return self.expression.is_star
4331
4332    @property
4333    def name(self) -> str:
4334        return self.expression.name
4335
4336    @property
4337    def output_name(self) -> str:
4338        return self.name
4339
4340    @classmethod
4341    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4342        """Build a Dot object with a sequence of expressions."""
4343        if len(expressions) < 2:
4344            raise ValueError("Dot requires >= 2 expressions.")
4345
4346        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4347
4348    @property
4349    def parts(self) -> t.List[Expression]:
4350        """Return the parts of a table / column in order catalog, db, table."""
4351        this, *parts = self.flatten()
4352
4353        parts.reverse()
4354
4355        for arg in COLUMN_PARTS:
4356            part = this.args.get(arg)
4357
4358            if isinstance(part, Expression):
4359                parts.append(part)
4360
4361        parts.reverse()
4362        return parts
is_star: bool
4328    @property
4329    def is_star(self) -> bool:
4330        return self.expression.is_star

Checks whether an expression is a star.

name: str
4332    @property
4333    def name(self) -> str:
4334        return self.expression.name
output_name: str
4336    @property
4337    def output_name(self) -> str:
4338        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:
4340    @classmethod
4341    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4342        """Build a Dot object with a sequence of expressions."""
4343        if len(expressions) < 2:
4344            raise ValueError("Dot requires >= 2 expressions.")
4345
4346        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]
4348    @property
4349    def parts(self) -> t.List[Expression]:
4350        """Return the parts of a table / column in order catalog, db, table."""
4351        this, *parts = self.flatten()
4352
4353        parts.reverse()
4354
4355        for arg in COLUMN_PARTS:
4356            part = this.args.get(arg)
4357
4358            if isinstance(part, Expression):
4359                parts.append(part)
4360
4361        parts.reverse()
4362        return parts

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

key = 'dot'
class DPipe(Binary):
4365class DPipe(Binary):
4366    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4369class EQ(Binary, Predicate):
4370    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4373class NullSafeEQ(Binary, Predicate):
4374    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4377class NullSafeNEQ(Binary, Predicate):
4378    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4382class PropertyEQ(Binary):
4383    pass
key = 'propertyeq'
class Distance(Binary):
4386class Distance(Binary):
4387    pass
key = 'distance'
class Escape(Binary):
4390class Escape(Binary):
4391    pass
key = 'escape'
class Glob(Binary, Predicate):
4394class Glob(Binary, Predicate):
4395    pass
key = 'glob'
class GT(Binary, Predicate):
4398class GT(Binary, Predicate):
4399    pass
key = 'gt'
class GTE(Binary, Predicate):
4402class GTE(Binary, Predicate):
4403    pass
key = 'gte'
class ILike(Binary, Predicate):
4406class ILike(Binary, Predicate):
4407    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4410class ILikeAny(Binary, Predicate):
4411    pass
key = 'ilikeany'
class IntDiv(Binary):
4414class IntDiv(Binary):
4415    pass
key = 'intdiv'
class Is(Binary, Predicate):
4418class Is(Binary, Predicate):
4419    pass
key = 'is'
class Kwarg(Binary):
4422class Kwarg(Binary):
4423    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4426class Like(Binary, Predicate):
4427    pass
key = 'like'
class LikeAny(Binary, Predicate):
4430class LikeAny(Binary, Predicate):
4431    pass
key = 'likeany'
class LT(Binary, Predicate):
4434class LT(Binary, Predicate):
4435    pass
key = 'lt'
class LTE(Binary, Predicate):
4438class LTE(Binary, Predicate):
4439    pass
key = 'lte'
class Mod(Binary):
4442class Mod(Binary):
4443    pass
key = 'mod'
class Mul(Binary):
4446class Mul(Binary):
4447    pass
key = 'mul'
class NEQ(Binary, Predicate):
4450class NEQ(Binary, Predicate):
4451    pass
key = 'neq'
class Operator(Binary):
4455class Operator(Binary):
4456    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4459class SimilarTo(Binary, Predicate):
4460    pass
key = 'similarto'
class Slice(Binary):
4463class Slice(Binary):
4464    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4467class Sub(Binary):
4468    pass
key = 'sub'
class Unary(Condition):
4473class Unary(Condition):
4474    pass
key = 'unary'
class BitwiseNot(Unary):
4477class BitwiseNot(Unary):
4478    pass
key = 'bitwisenot'
class Not(Unary):
4481class Not(Unary):
4482    pass
key = 'not'
class Paren(Unary):
4485class Paren(Unary):
4486    @property
4487    def output_name(self) -> str:
4488        return self.this.name
output_name: str
4486    @property
4487    def output_name(self) -> str:
4488        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):
4491class Neg(Unary):
4492    pass
key = 'neg'
class Alias(Expression):
4495class Alias(Expression):
4496    arg_types = {"this": True, "alias": False}
4497
4498    @property
4499    def output_name(self) -> str:
4500        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4498    @property
4499    def output_name(self) -> str:
4500        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):
4505class PivotAlias(Alias):
4506    pass
key = 'pivotalias'
class Aliases(Expression):
4509class Aliases(Expression):
4510    arg_types = {"this": True, "expressions": True}
4511
4512    @property
4513    def aliases(self):
4514        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4512    @property
4513    def aliases(self):
4514        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4518class AtIndex(Expression):
4519    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4522class AtTimeZone(Expression):
4523    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4526class FromTimeZone(Expression):
4527    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4530class Between(Predicate):
4531    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4534class Bracket(Condition):
4535    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4536    arg_types = {
4537        "this": True,
4538        "expressions": True,
4539        "offset": False,
4540        "safe": False,
4541        "returns_list_for_maps": False,
4542    }
4543
4544    @property
4545    def output_name(self) -> str:
4546        if len(self.expressions) == 1:
4547            return self.expressions[0].output_name
4548
4549        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4544    @property
4545    def output_name(self) -> str:
4546        if len(self.expressions) == 1:
4547            return self.expressions[0].output_name
4548
4549        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):
4552class Distinct(Expression):
4553    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4556class In(Predicate):
4557    arg_types = {
4558        "this": True,
4559        "expressions": False,
4560        "query": False,
4561        "unnest": False,
4562        "field": False,
4563        "is_global": False,
4564    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4568class ForIn(Expression):
4569    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4572class TimeUnit(Expression):
4573    """Automatically converts unit arg into a var."""
4574
4575    arg_types = {"unit": False}
4576
4577    UNABBREVIATED_UNIT_NAME = {
4578        "D": "DAY",
4579        "H": "HOUR",
4580        "M": "MINUTE",
4581        "MS": "MILLISECOND",
4582        "NS": "NANOSECOND",
4583        "Q": "QUARTER",
4584        "S": "SECOND",
4585        "US": "MICROSECOND",
4586        "W": "WEEK",
4587        "Y": "YEAR",
4588    }
4589
4590    VAR_LIKE = (Column, Literal, Var)
4591
4592    def __init__(self, **args):
4593        unit = args.get("unit")
4594        if isinstance(unit, self.VAR_LIKE):
4595            args["unit"] = Var(
4596                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4597            )
4598        elif isinstance(unit, Week):
4599            unit.set("this", Var(this=unit.this.name.upper()))
4600
4601        super().__init__(**args)
4602
4603    @property
4604    def unit(self) -> t.Optional[Var | IntervalSpan]:
4605        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4592    def __init__(self, **args):
4593        unit = args.get("unit")
4594        if isinstance(unit, self.VAR_LIKE):
4595            args["unit"] = Var(
4596                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4597            )
4598        elif isinstance(unit, Week):
4599            unit.set("this", Var(this=unit.this.name.upper()))
4600
4601        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: Union[Var, IntervalSpan, NoneType]
4603    @property
4604    def unit(self) -> t.Optional[Var | IntervalSpan]:
4605        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4608class IntervalOp(TimeUnit):
4609    arg_types = {"unit": True, "expression": True}
4610
4611    def interval(self):
4612        return Interval(
4613            this=self.expression.copy(),
4614            unit=self.unit.copy(),
4615        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4611    def interval(self):
4612        return Interval(
4613            this=self.expression.copy(),
4614            unit=self.unit.copy(),
4615        )
key = 'intervalop'
class IntervalSpan(DataType):
4621class IntervalSpan(DataType):
4622    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4625class Interval(TimeUnit):
4626    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4629class IgnoreNulls(Expression):
4630    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4633class RespectNulls(Expression):
4634    pass
key = 'respectnulls'
class HavingMax(Expression):
4638class HavingMax(Expression):
4639    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4643class Func(Condition):
4644    """
4645    The base class for all function expressions.
4646
4647    Attributes:
4648        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4649            treated as a variable length argument and the argument's value will be stored as a list.
4650        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4651            function expression. These values are used to map this node to a name during parsing as
4652            well as to provide the function's name during SQL string generation. By default the SQL
4653            name is set to the expression's class name transformed to snake case.
4654    """
4655
4656    is_var_len_args = False
4657
4658    @classmethod
4659    def from_arg_list(cls, args):
4660        if cls.is_var_len_args:
4661            all_arg_keys = list(cls.arg_types)
4662            # If this function supports variable length argument treat the last argument as such.
4663            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4664            num_non_var = len(non_var_len_arg_keys)
4665
4666            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4667            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4668        else:
4669            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4670
4671        return cls(**args_dict)
4672
4673    @classmethod
4674    def sql_names(cls):
4675        if cls is Func:
4676            raise NotImplementedError(
4677                "SQL name is only supported by concrete function implementations"
4678            )
4679        if "_sql_names" not in cls.__dict__:
4680            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4681        return cls._sql_names
4682
4683    @classmethod
4684    def sql_name(cls):
4685        return cls.sql_names()[0]
4686
4687    @classmethod
4688    def default_parser_mappings(cls):
4689        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): 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):
4658    @classmethod
4659    def from_arg_list(cls, args):
4660        if cls.is_var_len_args:
4661            all_arg_keys = list(cls.arg_types)
4662            # If this function supports variable length argument treat the last argument as such.
4663            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4664            num_non_var = len(non_var_len_arg_keys)
4665
4666            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4667            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4668        else:
4669            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4670
4671        return cls(**args_dict)
@classmethod
def sql_names(cls):
4673    @classmethod
4674    def sql_names(cls):
4675        if cls is Func:
4676            raise NotImplementedError(
4677                "SQL name is only supported by concrete function implementations"
4678            )
4679        if "_sql_names" not in cls.__dict__:
4680            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4681        return cls._sql_names
@classmethod
def sql_name(cls):
4683    @classmethod
4684    def sql_name(cls):
4685        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4687    @classmethod
4688    def default_parser_mappings(cls):
4689        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4692class AggFunc(Func):
4693    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4696class ParameterizedAgg(AggFunc):
4697    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4700class Abs(Func):
4701    pass
key = 'abs'
class ArgMax(AggFunc):
4704class ArgMax(AggFunc):
4705    arg_types = {"this": True, "expression": True, "count": False}
4706    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4709class ArgMin(AggFunc):
4710    arg_types = {"this": True, "expression": True, "count": False}
4711    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4714class ApproxTopK(AggFunc):
4715    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4718class Flatten(Func):
4719    pass
key = 'flatten'
class Transform(Func):
4723class Transform(Func):
4724    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4727class Anonymous(Func):
4728    arg_types = {"this": True, "expressions": False}
4729    is_var_len_args = True
4730
4731    @property
4732    def name(self) -> str:
4733        return self.this if isinstance(self.this, str) else self.this.name
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
name: str
4731    @property
4732    def name(self) -> str:
4733        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4736class AnonymousAggFunc(AggFunc):
4737    arg_types = {"this": True, "expressions": False}
4738    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4742class CombinedAggFunc(AnonymousAggFunc):
4743    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4746class CombinedParameterizedAgg(ParameterizedAgg):
4747    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):
4752class Hll(AggFunc):
4753    arg_types = {"this": True, "expressions": False}
4754    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4757class ApproxDistinct(AggFunc):
4758    arg_types = {"this": True, "accuracy": False}
4759    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4762class Array(Func):
4763    arg_types = {"expressions": False}
4764    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4768class ToArray(Func):
4769    pass
key = 'toarray'
class ToChar(Func):
4774class ToChar(Func):
4775    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4780class ToNumber(Func):
4781    arg_types = {
4782        "this": True,
4783        "format": False,
4784        "nlsparam": False,
4785        "precision": False,
4786        "scale": False,
4787    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4791class Convert(Func):
4792    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4795class GenerateSeries(Func):
4796    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
arg_types = {'start': True, 'end': True, 'step': False, 'is_end_exclusive': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4799class ArrayAgg(AggFunc):
4800    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4803class ArrayUniqueAgg(AggFunc):
4804    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4807class ArrayAll(Func):
4808    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4812class ArrayAny(Func):
4813    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4816class ArrayConcat(Func):
4817    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4818    arg_types = {"this": True, "expressions": False}
4819    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4822class ArrayConstructCompact(Func):
4823    arg_types = {"expressions": True}
4824    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4827class ArrayContains(Binary, Func):
4828    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4831class ArrayContainsAll(Binary, Func):
4832    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4835class ArrayFilter(Func):
4836    arg_types = {"this": True, "expression": True}
4837    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4840class ArrayToString(Func):
4841    arg_types = {"this": True, "expression": True, "null": False}
4842    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4845class StringToArray(Func):
4846    arg_types = {"this": True, "expression": True, "null": False}
4847    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4850class ArrayOverlaps(Binary, Func):
4851    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4854class ArraySize(Func):
4855    arg_types = {"this": True, "expression": False}
4856    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4859class ArraySort(Func):
4860    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4863class ArraySum(Func):
4864    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4867class ArrayUnionAgg(AggFunc):
4868    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4871class Avg(AggFunc):
4872    pass
key = 'avg'
class AnyValue(AggFunc):
4875class AnyValue(AggFunc):
4876    pass
key = 'anyvalue'
class Lag(AggFunc):
4879class Lag(AggFunc):
4880    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4883class Lead(AggFunc):
4884    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4889class First(AggFunc):
4890    pass
key = 'first'
class Last(AggFunc):
4893class Last(AggFunc):
4894    pass
key = 'last'
class FirstValue(AggFunc):
4897class FirstValue(AggFunc):
4898    pass
key = 'firstvalue'
class LastValue(AggFunc):
4901class LastValue(AggFunc):
4902    pass
key = 'lastvalue'
class NthValue(AggFunc):
4905class NthValue(AggFunc):
4906    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4909class Case(Func):
4910    arg_types = {"this": False, "ifs": True, "default": False}
4911
4912    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4913        instance = maybe_copy(self, copy)
4914        instance.append(
4915            "ifs",
4916            If(
4917                this=maybe_parse(condition, copy=copy, **opts),
4918                true=maybe_parse(then, copy=copy, **opts),
4919            ),
4920        )
4921        return instance
4922
4923    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4924        instance = maybe_copy(self, copy)
4925        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4926        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:
4912    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4913        instance = maybe_copy(self, copy)
4914        instance.append(
4915            "ifs",
4916            If(
4917                this=maybe_parse(condition, copy=copy, **opts),
4918                true=maybe_parse(then, copy=copy, **opts),
4919            ),
4920        )
4921        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4923    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4924        instance = maybe_copy(self, copy)
4925        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4926        return instance
key = 'case'
class Cast(Func):
4929class Cast(Func):
4930    arg_types = {
4931        "this": True,
4932        "to": True,
4933        "format": False,
4934        "safe": False,
4935        "action": False,
4936    }
4937
4938    @property
4939    def name(self) -> str:
4940        return self.this.name
4941
4942    @property
4943    def to(self) -> DataType:
4944        return self.args["to"]
4945
4946    @property
4947    def output_name(self) -> str:
4948        return self.name
4949
4950    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4951        """
4952        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4953        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4954        array<int> != array<float>.
4955
4956        Args:
4957            dtypes: the data types to compare this Cast's DataType to.
4958
4959        Returns:
4960            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4961        """
4962        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4938    @property
4939    def name(self) -> str:
4940        return self.this.name
to: DataType
4942    @property
4943    def to(self) -> DataType:
4944        return self.args["to"]
output_name: str
4946    @property
4947    def output_name(self) -> str:
4948        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:
4950    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4951        """
4952        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4953        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4954        array<int> != array<float>.
4955
4956        Args:
4957            dtypes: the data types to compare this Cast's DataType to.
4958
4959        Returns:
4960            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4961        """
4962        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):
4965class TryCast(Cast):
4966    pass
key = 'trycast'
class Try(Func):
4969class Try(Func):
4970    pass
key = 'try'
class CastToStrType(Func):
4973class CastToStrType(Func):
4974    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4977class Collate(Binary, Func):
4978    pass
key = 'collate'
class Ceil(Func):
4981class Ceil(Func):
4982    arg_types = {"this": True, "decimals": False}
4983    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
4986class Coalesce(Func):
4987    arg_types = {"this": True, "expressions": False}
4988    is_var_len_args = True
4989    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
4992class Chr(Func):
4993    arg_types = {"this": True, "charset": False, "expressions": False}
4994    is_var_len_args = True
4995    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
4998class Concat(Func):
4999    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5000    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5003class ConcatWs(Concat):
5004    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5008class ConnectByRoot(Func):
5009    pass
key = 'connectbyroot'
class Count(AggFunc):
5012class Count(AggFunc):
5013    arg_types = {"this": False, "expressions": False}
5014    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5017class CountIf(AggFunc):
5018    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5022class Cbrt(Func):
5023    pass
key = 'cbrt'
class CurrentDate(Func):
5026class CurrentDate(Func):
5027    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5030class CurrentDatetime(Func):
5031    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5034class CurrentTime(Func):
5035    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5038class CurrentTimestamp(Func):
5039    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5042class CurrentUser(Func):
5043    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5046class DateAdd(Func, IntervalOp):
5047    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5050class DateSub(Func, IntervalOp):
5051    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5054class DateDiff(Func, TimeUnit):
5055    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5056    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5059class DateTrunc(Func):
5060    arg_types = {"unit": True, "this": True, "zone": False}
5061
5062    def __init__(self, **args):
5063        unit = args.get("unit")
5064        if isinstance(unit, TimeUnit.VAR_LIKE):
5065            args["unit"] = Literal.string(
5066                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5067            )
5068        elif isinstance(unit, Week):
5069            unit.set("this", Literal.string(unit.this.name.upper()))
5070
5071        super().__init__(**args)
5072
5073    @property
5074    def unit(self) -> Expression:
5075        return self.args["unit"]
DateTrunc(**args)
5062    def __init__(self, **args):
5063        unit = args.get("unit")
5064        if isinstance(unit, TimeUnit.VAR_LIKE):
5065            args["unit"] = Literal.string(
5066                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5067            )
5068        elif isinstance(unit, Week):
5069            unit.set("this", Literal.string(unit.this.name.upper()))
5070
5071        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5073    @property
5074    def unit(self) -> Expression:
5075        return self.args["unit"]
key = 'datetrunc'
class DatetimeAdd(Func, IntervalOp):
5078class DatetimeAdd(Func, IntervalOp):
5079    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5082class DatetimeSub(Func, IntervalOp):
5083    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5086class DatetimeDiff(Func, TimeUnit):
5087    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5090class DatetimeTrunc(Func, TimeUnit):
5091    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5094class DayOfWeek(Func):
5095    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5098class DayOfMonth(Func):
5099    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5102class DayOfYear(Func):
5103    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5106class ToDays(Func):
5107    pass
key = 'todays'
class WeekOfYear(Func):
5110class WeekOfYear(Func):
5111    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5114class MonthsBetween(Func):
5115    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5118class LastDay(Func, TimeUnit):
5119    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5120    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5123class Extract(Func):
5124    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5127class Timestamp(Func):
5128    arg_types = {"this": False, "expression": False, "with_tz": False}
arg_types = {'this': False, 'expression': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5131class TimestampAdd(Func, TimeUnit):
5132    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5135class TimestampSub(Func, TimeUnit):
5136    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5139class TimestampDiff(Func, TimeUnit):
5140    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5141    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5144class TimestampTrunc(Func, TimeUnit):
5145    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5148class TimeAdd(Func, TimeUnit):
5149    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5152class TimeSub(Func, TimeUnit):
5153    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5156class TimeDiff(Func, TimeUnit):
5157    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5160class TimeTrunc(Func, TimeUnit):
5161    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5164class DateFromParts(Func):
5165    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5166    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5169class TimeFromParts(Func):
5170    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5171    arg_types = {
5172        "hour": True,
5173        "min": True,
5174        "sec": True,
5175        "nano": False,
5176        "fractions": False,
5177        "precision": False,
5178    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5181class DateStrToDate(Func):
5182    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5185class DateToDateStr(Func):
5186    pass
key = 'datetodatestr'
class DateToDi(Func):
5189class DateToDi(Func):
5190    pass
key = 'datetodi'
class Date(Func):
5194class Date(Func):
5195    arg_types = {"this": False, "zone": False, "expressions": False}
5196    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5199class Day(Func):
5200    pass
key = 'day'
class Decode(Func):
5203class Decode(Func):
5204    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5207class DiToDate(Func):
5208    pass
key = 'ditodate'
class Encode(Func):
5211class Encode(Func):
5212    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5215class Exp(Func):
5216    pass
key = 'exp'
class Explode(Func):
5220class Explode(Func):
5221    arg_types = {"this": True, "expressions": False}
5222    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5225class ExplodeOuter(Explode):
5226    pass
key = 'explodeouter'
class Posexplode(Explode):
5229class Posexplode(Explode):
5230    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5233class PosexplodeOuter(Posexplode, ExplodeOuter):
5234    pass
key = 'posexplodeouter'
class Floor(Func):
5237class Floor(Func):
5238    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5241class FromBase64(Func):
5242    pass
key = 'frombase64'
class ToBase64(Func):
5245class ToBase64(Func):
5246    pass
key = 'tobase64'
class GapFill(Func):
5249class GapFill(Func):
5250    arg_types = {
5251        "this": True,
5252        "ts_column": True,
5253        "bucket_width": True,
5254        "partitioning_columns": False,
5255        "value_columns": False,
5256        "origin": False,
5257        "ignore_nulls": False,
5258    }
arg_types = {'this': True, 'ts_column': True, 'bucket_width': True, 'partitioning_columns': False, 'value_columns': False, 'origin': False, 'ignore_nulls': False}
key = 'gapfill'
class GenerateDateArray(Func):
5261class GenerateDateArray(Func):
5262    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5265class Greatest(Func):
5266    arg_types = {"this": True, "expressions": False}
5267    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5270class GroupConcat(AggFunc):
5271    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5274class Hex(Func):
5275    pass
key = 'hex'
class LowerHex(Hex):
5278class LowerHex(Hex):
5279    pass
key = 'lowerhex'
class Xor(Connector, Func):
5282class Xor(Connector, Func):
5283    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5286class If(Func):
5287    arg_types = {"this": True, "true": True, "false": False}
5288    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5291class Nullif(Func):
5292    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5295class Initcap(Func):
5296    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5299class IsNan(Func):
5300    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5303class IsInf(Func):
5304    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5307class JSONPath(Expression):
5308    arg_types = {"expressions": True}
5309
5310    @property
5311    def output_name(self) -> str:
5312        last_segment = self.expressions[-1].this
5313        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5310    @property
5311    def output_name(self) -> str:
5312        last_segment = self.expressions[-1].this
5313        return last_segment if isinstance(last_segment, str) else ""

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 = 'jsonpath'
class JSONPathPart(Expression):
5316class JSONPathPart(Expression):
5317    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5320class JSONPathFilter(JSONPathPart):
5321    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5324class JSONPathKey(JSONPathPart):
5325    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5328class JSONPathRecursive(JSONPathPart):
5329    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5332class JSONPathRoot(JSONPathPart):
5333    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5336class JSONPathScript(JSONPathPart):
5337    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5340class JSONPathSlice(JSONPathPart):
5341    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5344class JSONPathSelector(JSONPathPart):
5345    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5348class JSONPathSubscript(JSONPathPart):
5349    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5352class JSONPathUnion(JSONPathPart):
5353    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5356class JSONPathWildcard(JSONPathPart):
5357    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5360class FormatJson(Expression):
5361    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5364class JSONKeyValue(Expression):
5365    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5368class JSONObject(Func):
5369    arg_types = {
5370        "expressions": False,
5371        "null_handling": False,
5372        "unique_keys": False,
5373        "return_type": False,
5374        "encoding": False,
5375    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5378class JSONObjectAgg(AggFunc):
5379    arg_types = {
5380        "expressions": False,
5381        "null_handling": False,
5382        "unique_keys": False,
5383        "return_type": False,
5384        "encoding": False,
5385    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5389class JSONArray(Func):
5390    arg_types = {
5391        "expressions": True,
5392        "null_handling": False,
5393        "return_type": False,
5394        "strict": False,
5395    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5399class JSONArrayAgg(Func):
5400    arg_types = {
5401        "this": True,
5402        "order": False,
5403        "null_handling": False,
5404        "return_type": False,
5405        "strict": False,
5406    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5411class JSONColumnDef(Expression):
5412    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):
5415class JSONSchema(Expression):
5416    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5420class JSONTable(Func):
5421    arg_types = {
5422        "this": True,
5423        "schema": True,
5424        "path": False,
5425        "error_handling": False,
5426        "empty_handling": False,
5427    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5430class OpenJSONColumnDef(Expression):
5431    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):
5434class OpenJSON(Func):
5435    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary):
5438class JSONBContains(Binary):
5439    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5442class JSONExtract(Binary, Func):
5443    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5444    _sql_names = ["JSON_EXTRACT"]
5445    is_var_len_args = True
5446
5447    @property
5448    def output_name(self) -> str:
5449        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
5447    @property
5448    def output_name(self) -> str:
5449        return self.expression.output_name if not self.expressions else ""

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 = 'jsonextract'
class JSONExtractScalar(Binary, Func):
5452class JSONExtractScalar(Binary, Func):
5453    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5454    _sql_names = ["JSON_EXTRACT_SCALAR"]
5455    is_var_len_args = True
5456
5457    @property
5458    def output_name(self) -> str:
5459        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
5457    @property
5458    def output_name(self) -> str:
5459        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 = 'jsonextractscalar'
class JSONBExtract(Binary, Func):
5462class JSONBExtract(Binary, Func):
5463    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5466class JSONBExtractScalar(Binary, Func):
5467    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5470class JSONFormat(Func):
5471    arg_types = {"this": False, "options": False}
5472    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5476class JSONArrayContains(Binary, Predicate, Func):
5477    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5480class ParseJSON(Func):
5481    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5482    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5483    arg_types = {"this": True, "expressions": False}
5484    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'parsejson'
class Least(Func):
5487class Least(Func):
5488    arg_types = {"this": True, "expressions": False}
5489    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5492class Left(Func):
5493    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5500class Length(Func):
5501    _sql_names = ["LENGTH", "LEN"]
key = 'length'
class Levenshtein(Func):
5504class Levenshtein(Func):
5505    arg_types = {
5506        "this": True,
5507        "expression": False,
5508        "ins_cost": False,
5509        "del_cost": False,
5510        "sub_cost": False,
5511    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5514class Ln(Func):
5515    pass
key = 'ln'
class Log(Func):
5518class Log(Func):
5519    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5522class LogicalOr(AggFunc):
5523    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5526class LogicalAnd(AggFunc):
5527    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5530class Lower(Func):
5531    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5534class Map(Func):
5535    arg_types = {"keys": False, "values": False}
5536
5537    @property
5538    def keys(self) -> t.List[Expression]:
5539        keys = self.args.get("keys")
5540        return keys.expressions if keys else []
5541
5542    @property
5543    def values(self) -> t.List[Expression]:
5544        values = self.args.get("values")
5545        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5537    @property
5538    def keys(self) -> t.List[Expression]:
5539        keys = self.args.get("keys")
5540        return keys.expressions if keys else []
values: List[Expression]
5542    @property
5543    def values(self) -> t.List[Expression]:
5544        values = self.args.get("values")
5545        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5549class ToMap(Func):
5550    pass
key = 'tomap'
class MapFromEntries(Func):
5553class MapFromEntries(Func):
5554    pass
key = 'mapfromentries'
class StarMap(Func):
5557class StarMap(Func):
5558    pass
key = 'starmap'
class VarMap(Func):
5561class VarMap(Func):
5562    arg_types = {"keys": True, "values": True}
5563    is_var_len_args = True
5564
5565    @property
5566    def keys(self) -> t.List[Expression]:
5567        return self.args["keys"].expressions
5568
5569    @property
5570    def values(self) -> t.List[Expression]:
5571        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5565    @property
5566    def keys(self) -> t.List[Expression]:
5567        return self.args["keys"].expressions
values: List[Expression]
5569    @property
5570    def values(self) -> t.List[Expression]:
5571        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5575class MatchAgainst(Func):
5576    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5579class Max(AggFunc):
5580    arg_types = {"this": True, "expressions": False}
5581    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5584class MD5(Func):
5585    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5589class MD5Digest(Func):
5590    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5593class Min(AggFunc):
5594    arg_types = {"this": True, "expressions": False}
5595    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5598class Month(Func):
5599    pass
key = 'month'
class AddMonths(Func):
5602class AddMonths(Func):
5603    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5606class Nvl2(Func):
5607    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5611class Predict(Func):
5612    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5615class Pow(Binary, Func):
5616    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5619class PercentileCont(AggFunc):
5620    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5623class PercentileDisc(AggFunc):
5624    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5627class Quantile(AggFunc):
5628    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5631class ApproxQuantile(Quantile):
5632    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Quarter(Func):
5635class Quarter(Func):
5636    pass
key = 'quarter'
class Rand(Func):
5639class Rand(Func):
5640    _sql_names = ["RAND", "RANDOM"]
5641    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5644class Randn(Func):
5645    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5648class RangeN(Func):
5649    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5652class ReadCSV(Func):
5653    _sql_names = ["READ_CSV"]
5654    is_var_len_args = True
5655    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5658class Reduce(Func):
5659    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):
5662class RegexpExtract(Func):
5663    arg_types = {
5664        "this": True,
5665        "expression": True,
5666        "position": False,
5667        "occurrence": False,
5668        "parameters": False,
5669        "group": False,
5670    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5673class RegexpReplace(Func):
5674    arg_types = {
5675        "this": True,
5676        "expression": True,
5677        "replacement": False,
5678        "position": False,
5679        "occurrence": False,
5680        "modifiers": False,
5681    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5684class RegexpLike(Binary, Func):
5685    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5688class RegexpILike(Binary, Func):
5689    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5694class RegexpSplit(Func):
5695    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5698class Repeat(Func):
5699    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5704class Round(Func):
5705    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5708class RowNumber(Func):
5709    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5712class SafeDivide(Func):
5713    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5716class SHA(Func):
5717    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5720class SHA2(Func):
5721    _sql_names = ["SHA2"]
5722    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5725class Sign(Func):
5726    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5729class SortArray(Func):
5730    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5733class Split(Func):
5734    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5739class Substring(Func):
5740    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5743class StandardHash(Func):
5744    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5747class StartsWith(Func):
5748    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5749    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5752class StrPosition(Func):
5753    arg_types = {
5754        "this": True,
5755        "substr": True,
5756        "position": False,
5757        "instance": False,
5758    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5761class StrToDate(Func):
5762    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'strtodate'
class StrToTime(Func):
5765class StrToTime(Func):
5766    arg_types = {"this": True, "format": True, "zone": False}
arg_types = {'this': True, 'format': True, 'zone': False}
key = 'strtotime'
class StrToUnix(Func):
5771class StrToUnix(Func):
5772    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5777class StrToMap(Func):
5778    arg_types = {
5779        "this": True,
5780        "pair_delim": False,
5781        "key_value_delim": False,
5782        "duplicate_resolution_callback": False,
5783    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5786class NumberToStr(Func):
5787    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5790class FromBase(Func):
5791    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5794class Struct(Func):
5795    arg_types = {"expressions": False}
5796    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5799class StructExtract(Func):
5800    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5805class Stuff(Func):
5806    _sql_names = ["STUFF", "INSERT"]
5807    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):
5810class Sum(AggFunc):
5811    pass
key = 'sum'
class Sqrt(Func):
5814class Sqrt(Func):
5815    pass
key = 'sqrt'
class Stddev(AggFunc):
5818class Stddev(AggFunc):
5819    pass
key = 'stddev'
class StddevPop(AggFunc):
5822class StddevPop(AggFunc):
5823    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5826class StddevSamp(AggFunc):
5827    pass
key = 'stddevsamp'
class TimeToStr(Func):
5830class TimeToStr(Func):
5831    arg_types = {"this": True, "format": True, "culture": False, "timezone": False}
arg_types = {'this': True, 'format': True, 'culture': False, 'timezone': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5834class TimeToTimeStr(Func):
5835    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5838class TimeToUnix(Func):
5839    pass
key = 'timetounix'
class TimeStrToDate(Func):
5842class TimeStrToDate(Func):
5843    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5846class TimeStrToTime(Func):
5847    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5850class TimeStrToUnix(Func):
5851    pass
key = 'timestrtounix'
class Trim(Func):
5854class Trim(Func):
5855    arg_types = {
5856        "this": True,
5857        "expression": False,
5858        "position": False,
5859        "collation": False,
5860    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5863class TsOrDsAdd(Func, TimeUnit):
5864    # return_type is used to correctly cast the arguments of this expression when transpiling it
5865    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5866
5867    @property
5868    def return_type(self) -> DataType:
5869        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
5867    @property
5868    def return_type(self) -> DataType:
5869        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5872class TsOrDsDiff(Func, TimeUnit):
5873    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5876class TsOrDsToDateStr(Func):
5877    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5880class TsOrDsToDate(Func):
5881    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5884class TsOrDsToTime(Func):
5885    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5888class TsOrDsToTimestamp(Func):
5889    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5892class TsOrDiToDi(Func):
5893    pass
key = 'tsorditodi'
class Unhex(Func):
5896class Unhex(Func):
5897    pass
key = 'unhex'
class UnixDate(Func):
5901class UnixDate(Func):
5902    pass
key = 'unixdate'
class UnixToStr(Func):
5905class UnixToStr(Func):
5906    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5911class UnixToTime(Func):
5912    arg_types = {
5913        "this": True,
5914        "scale": False,
5915        "zone": False,
5916        "hours": False,
5917        "minutes": False,
5918        "format": False,
5919    }
5920
5921    SECONDS = Literal.number(0)
5922    DECIS = Literal.number(1)
5923    CENTIS = Literal.number(2)
5924    MILLIS = Literal.number(3)
5925    DECIMILLIS = Literal.number(4)
5926    CENTIMILLIS = Literal.number(5)
5927    MICROS = Literal.number(6)
5928    DECIMICROS = Literal.number(7)
5929    CENTIMICROS = Literal.number(8)
5930    NANOS = Literal.number(9)
arg_types = {'this': True, 'scale': False, 'zone': False, 'hours': False, 'minutes': False, 'format': 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):
5933class UnixToTimeStr(Func):
5934    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5937class TimestampFromParts(Func):
5938    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5939    arg_types = {
5940        "year": True,
5941        "month": True,
5942        "day": True,
5943        "hour": True,
5944        "min": True,
5945        "sec": True,
5946        "nano": False,
5947        "zone": False,
5948        "milli": False,
5949    }
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):
5952class Upper(Func):
5953    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
5956class Corr(Binary, AggFunc):
5957    pass
key = 'corr'
class Variance(AggFunc):
5960class Variance(AggFunc):
5961    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
5964class VariancePop(AggFunc):
5965    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
5968class CovarSamp(Binary, AggFunc):
5969    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
5972class CovarPop(Binary, AggFunc):
5973    pass
key = 'covarpop'
class Week(Func):
5976class Week(Func):
5977    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
5980class XMLTable(Func):
5981    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):
5984class Year(Func):
5985    pass
key = 'year'
class Use(Expression):
5988class Use(Expression):
5989    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
5992class Merge(Expression):
5993    arg_types = {
5994        "this": True,
5995        "using": True,
5996        "on": True,
5997        "expressions": True,
5998        "with": False,
5999    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6002class When(Func):
6003    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):
6008class NextValueFor(Func):
6009    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6014class Semicolon(Expression):
6015    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <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 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <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 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <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 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NthValue'>, <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 'Quarter'>, <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 'Sign'>, <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 'StringToArray'>, <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 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <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'>, 'ADD_MONTHS': <class 'AddMonths'>, '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_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, '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'>, 'CBRT': <class 'Cbrt'>, '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'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, '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'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <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'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, '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'>, 'LOWER_HEX': <class 'LowerHex'>, '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'>, 'NTH_VALUE': <class 'NthValue'>, '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'>, 'QUARTER': <class 'Quarter'>, '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'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, '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'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, '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'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, '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'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY': <class 'Try'>, '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'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, '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'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
PERCENTILES = (<class 'PercentileCont'>, <class 'PercentileDisc'>)
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:
6055def maybe_parse(
6056    sql_or_expression: ExpOrStr,
6057    *,
6058    into: t.Optional[IntoType] = None,
6059    dialect: DialectType = None,
6060    prefix: t.Optional[str] = None,
6061    copy: bool = False,
6062    **opts,
6063) -> Expression:
6064    """Gracefully handle a possible string or expression.
6065
6066    Example:
6067        >>> maybe_parse("1")
6068        Literal(this=1, is_string=False)
6069        >>> maybe_parse(to_identifier("x"))
6070        Identifier(this=x, quoted=False)
6071
6072    Args:
6073        sql_or_expression: the SQL code string or an expression
6074        into: the SQLGlot Expression to parse into
6075        dialect: the dialect used to parse the input expressions (in the case that an
6076            input expression is a SQL string).
6077        prefix: a string to prefix the sql with before it gets parsed
6078            (automatically includes a space)
6079        copy: whether to copy the expression.
6080        **opts: other options to use to parse the input expressions (again, in the case
6081            that an input expression is a SQL string).
6082
6083    Returns:
6084        Expression: the parsed or given expression.
6085    """
6086    if isinstance(sql_or_expression, Expression):
6087        if copy:
6088            return sql_or_expression.copy()
6089        return sql_or_expression
6090
6091    if sql_or_expression is None:
6092        raise ParseError("SQL cannot be None")
6093
6094    import sqlglot
6095
6096    sql = str(sql_or_expression)
6097    if prefix:
6098        sql = f"{prefix} {sql}"
6099
6100    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 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):
6111def maybe_copy(instance, copy=True):
6112    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:
6332def union(
6333    left: ExpOrStr,
6334    right: ExpOrStr,
6335    distinct: bool = True,
6336    dialect: DialectType = None,
6337    copy: bool = True,
6338    **opts,
6339) -> Union:
6340    """
6341    Initializes a syntax tree from one UNION expression.
6342
6343    Example:
6344        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6345        'SELECT * FROM foo UNION SELECT * FROM bla'
6346
6347    Args:
6348        left: the SQL code string corresponding to the left-hand side.
6349            If an `Expression` instance is passed, it will be used as-is.
6350        right: the SQL code string corresponding to the right-hand side.
6351            If an `Expression` instance is passed, it will be used as-is.
6352        distinct: set the DISTINCT flag if and only if this is true.
6353        dialect: the dialect used to parse the input expression.
6354        copy: whether to copy the expression.
6355        opts: other options to use to parse the input expressions.
6356
6357    Returns:
6358        The new Union instance.
6359    """
6360    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6361    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6362
6363    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 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:
6366def intersect(
6367    left: ExpOrStr,
6368    right: ExpOrStr,
6369    distinct: bool = True,
6370    dialect: DialectType = None,
6371    copy: bool = True,
6372    **opts,
6373) -> Intersect:
6374    """
6375    Initializes a syntax tree from one INTERSECT expression.
6376
6377    Example:
6378        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6379        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6380
6381    Args:
6382        left: the SQL code string corresponding to the left-hand side.
6383            If an `Expression` instance is passed, it will be used as-is.
6384        right: the SQL code string corresponding to the right-hand side.
6385            If an `Expression` instance is passed, it will be used as-is.
6386        distinct: set the DISTINCT flag if and only if this is true.
6387        dialect: the dialect used to parse the input expression.
6388        copy: whether to copy the expression.
6389        opts: other options to use to parse the input expressions.
6390
6391    Returns:
6392        The new Intersect instance.
6393    """
6394    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6395    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6396
6397    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 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:
6400def except_(
6401    left: ExpOrStr,
6402    right: ExpOrStr,
6403    distinct: bool = True,
6404    dialect: DialectType = None,
6405    copy: bool = True,
6406    **opts,
6407) -> Except:
6408    """
6409    Initializes a syntax tree from one EXCEPT expression.
6410
6411    Example:
6412        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6413        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6414
6415    Args:
6416        left: the SQL code string corresponding to the left-hand side.
6417            If an `Expression` instance is passed, it will be used as-is.
6418        right: the SQL code string corresponding to the right-hand side.
6419            If an `Expression` instance is passed, it will be used as-is.
6420        distinct: set the DISTINCT flag if and only if this is true.
6421        dialect: the dialect used to parse the input expression.
6422        copy: whether to copy the expression.
6423        opts: other options to use to parse the input expressions.
6424
6425    Returns:
6426        The new Except instance.
6427    """
6428    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6429    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6430
6431    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 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:
6434def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6435    """
6436    Initializes a syntax tree from one or multiple SELECT expressions.
6437
6438    Example:
6439        >>> select("col1", "col2").from_("tbl").sql()
6440        'SELECT col1, col2 FROM tbl'
6441
6442    Args:
6443        *expressions: the SQL code string to parse as the expressions of a
6444            SELECT statement. If an Expression instance is passed, this is used as-is.
6445        dialect: the dialect used to parse the input expressions (in the case that an
6446            input expression is a SQL string).
6447        **opts: other options to use to parse the input expressions (again, in the case
6448            that an input expression is a SQL string).
6449
6450    Returns:
6451        Select: the syntax tree for the SELECT statement.
6452    """
6453    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:
6456def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6457    """
6458    Initializes a syntax tree from a FROM expression.
6459
6460    Example:
6461        >>> from_("tbl").select("col1", "col2").sql()
6462        'SELECT col1, col2 FROM tbl'
6463
6464    Args:
6465        *expression: the SQL code string to parse as the FROM expressions of a
6466            SELECT statement. If an Expression instance is passed, this is used as-is.
6467        dialect: the dialect used to parse the input expression (in the case that the
6468            input expression is a SQL string).
6469        **opts: other options to use to parse the input expressions (again, in the case
6470            that the input expression is a SQL string).
6471
6472    Returns:
6473        Select: the syntax tree for the SELECT statement.
6474    """
6475    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:
6478def update(
6479    table: str | Table,
6480    properties: dict,
6481    where: t.Optional[ExpOrStr] = None,
6482    from_: t.Optional[ExpOrStr] = None,
6483    dialect: DialectType = None,
6484    **opts,
6485) -> Update:
6486    """
6487    Creates an update statement.
6488
6489    Example:
6490        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6491        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6492
6493    Args:
6494        *properties: dictionary of properties to set which are
6495            auto converted to sql objects eg None -> NULL
6496        where: sql conditional parsed into a WHERE statement
6497        from_: sql statement parsed into a FROM statement
6498        dialect: the dialect used to parse the input expressions.
6499        **opts: other options to use to parse the input expressions.
6500
6501    Returns:
6502        Update: the syntax tree for the UPDATE statement.
6503    """
6504    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6505    update_expr.set(
6506        "expressions",
6507        [
6508            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6509            for k, v in properties.items()
6510        ],
6511    )
6512    if from_:
6513        update_expr.set(
6514            "from",
6515            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6516        )
6517    if isinstance(where, Condition):
6518        where = Where(this=where)
6519    if where:
6520        update_expr.set(
6521            "where",
6522            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6523        )
6524    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:
6527def delete(
6528    table: ExpOrStr,
6529    where: t.Optional[ExpOrStr] = None,
6530    returning: t.Optional[ExpOrStr] = None,
6531    dialect: DialectType = None,
6532    **opts,
6533) -> Delete:
6534    """
6535    Builds a delete statement.
6536
6537    Example:
6538        >>> delete("my_table", where="id > 1").sql()
6539        'DELETE FROM my_table WHERE id > 1'
6540
6541    Args:
6542        where: sql conditional parsed into a WHERE statement
6543        returning: sql conditional parsed into a RETURNING statement
6544        dialect: the dialect used to parse the input expressions.
6545        **opts: other options to use to parse the input expressions.
6546
6547    Returns:
6548        Delete: the syntax tree for the DELETE statement.
6549    """
6550    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6551    if where:
6552        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6553    if returning:
6554        delete_expr = t.cast(
6555            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6556        )
6557    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:
6560def insert(
6561    expression: ExpOrStr,
6562    into: ExpOrStr,
6563    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6564    overwrite: t.Optional[bool] = None,
6565    returning: t.Optional[ExpOrStr] = None,
6566    dialect: DialectType = None,
6567    copy: bool = True,
6568    **opts,
6569) -> Insert:
6570    """
6571    Builds an INSERT statement.
6572
6573    Example:
6574        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6575        'INSERT INTO tbl VALUES (1, 2, 3)'
6576
6577    Args:
6578        expression: the sql string or expression of the INSERT statement
6579        into: the tbl to insert data to.
6580        columns: optionally the table's column names.
6581        overwrite: whether to INSERT OVERWRITE or not.
6582        returning: sql conditional parsed into a RETURNING statement
6583        dialect: the dialect used to parse the input expressions.
6584        copy: whether to copy the expression.
6585        **opts: other options to use to parse the input expressions.
6586
6587    Returns:
6588        Insert: the syntax tree for the INSERT statement.
6589    """
6590    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6591    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6592
6593    if columns:
6594        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6595
6596    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6597
6598    if returning:
6599        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6600
6601    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 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:
6604def condition(
6605    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6606) -> Condition:
6607    """
6608    Initialize a logical condition expression.
6609
6610    Example:
6611        >>> condition("x=1").sql()
6612        'x = 1'
6613
6614        This is helpful for composing larger logical syntax trees:
6615        >>> where = condition("x=1")
6616        >>> where = where.and_("y=1")
6617        >>> Select().from_("tbl").select("*").where(where).sql()
6618        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6619
6620    Args:
6621        *expression: the SQL code string to parse.
6622            If an Expression instance is passed, this is used as-is.
6623        dialect: the dialect used to parse the input expression (in the case that the
6624            input expression is a SQL string).
6625        copy: Whether to copy `expression` (only applies to expressions).
6626        **opts: other options to use to parse the input expressions (again, in the case
6627            that the input expression is a SQL string).
6628
6629    Returns:
6630        The new Condition instance
6631    """
6632    return maybe_parse(
6633        expression,
6634        into=Condition,
6635        dialect=dialect,
6636        copy=copy,
6637        **opts,
6638    )

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 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:
6641def and_(
6642    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6643) -> Condition:
6644    """
6645    Combine multiple conditions with an AND logical operator.
6646
6647    Example:
6648        >>> and_("x=1", and_("y=1", "z=1")).sql()
6649        'x = 1 AND (y = 1 AND z = 1)'
6650
6651    Args:
6652        *expressions: the SQL code strings to parse.
6653            If an Expression instance is passed, this is used as-is.
6654        dialect: the dialect used to parse the input expression.
6655        copy: whether to copy `expressions` (only applies to Expressions).
6656        **opts: other options to use to parse the input expressions.
6657
6658    Returns:
6659        The new condition
6660    """
6661    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 to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

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:
6664def or_(
6665    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6666) -> Condition:
6667    """
6668    Combine multiple conditions with an OR logical operator.
6669
6670    Example:
6671        >>> or_("x=1", or_("y=1", "z=1")).sql()
6672        'x = 1 OR (y = 1 OR z = 1)'
6673
6674    Args:
6675        *expressions: the SQL code strings to parse.
6676            If an Expression instance is passed, this is used as-is.
6677        dialect: the dialect used to parse the input expression.
6678        copy: whether to copy `expressions` (only applies to Expressions).
6679        **opts: other options to use to parse the input expressions.
6680
6681    Returns:
6682        The new condition
6683    """
6684    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 to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition

def xor( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6687def xor(
6688    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6689) -> Condition:
6690    """
6691    Combine multiple conditions with an XOR logical operator.
6692
6693    Example:
6694        >>> xor("x=1", xor("y=1", "z=1")).sql()
6695        'x = 1 XOR (y = 1 XOR z = 1)'
6696
6697    Args:
6698        *expressions: the SQL code strings to parse.
6699            If an Expression instance is passed, this is used as-is.
6700        dialect: the dialect used to parse the input expression.
6701        copy: whether to copy `expressions` (only applies to Expressions).
6702        **opts: other options to use to parse the input expressions.
6703
6704    Returns:
6705        The new condition
6706    """
6707    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, **opts))

Combine multiple conditions with an XOR logical operator.

Example:
>>> xor("x=1", xor("y=1", "z=1")).sql()
'x = 1 XOR (y = 1 XOR 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 to copy expressions (only applies to Expressions).
  • **opts: other options to use to parse the input expressions.
Returns:

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:
6710def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6711    """
6712    Wrap a condition with a NOT operator.
6713
6714    Example:
6715        >>> not_("this_suit='black'").sql()
6716        "NOT this_suit = 'black'"
6717
6718    Args:
6719        expression: the SQL code string to parse.
6720            If an Expression instance is passed, this is used as-is.
6721        dialect: the dialect used to parse the input expression.
6722        copy: whether to copy the expression or not.
6723        **opts: other options to use to parse the input expressions.
6724
6725    Returns:
6726        The new condition.
6727    """
6728    this = condition(
6729        expression,
6730        dialect=dialect,
6731        copy=copy,
6732        **opts,
6733    )
6734    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:
6737def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6738    """
6739    Wrap an expression in parentheses.
6740
6741    Example:
6742        >>> paren("5 + 3").sql()
6743        '(5 + 3)'
6744
6745    Args:
6746        expression: the SQL code string to parse.
6747            If an Expression instance is passed, this is used as-is.
6748        copy: whether to copy the expression or not.
6749
6750    Returns:
6751        The wrapped expression.
6752    """
6753    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: Pattern[str] = re.compile('^[_a-zA-Z][\\w]*$')
def to_identifier(name, quoted=None, copy=True):
6769def to_identifier(name, quoted=None, copy=True):
6770    """Builds an identifier.
6771
6772    Args:
6773        name: The name to turn into an identifier.
6774        quoted: Whether to force quote the identifier.
6775        copy: Whether to copy name if it's an Identifier.
6776
6777    Returns:
6778        The identifier ast node.
6779    """
6780
6781    if name is None:
6782        return None
6783
6784    if isinstance(name, Identifier):
6785        identifier = maybe_copy(name, copy)
6786    elif isinstance(name, str):
6787        identifier = Identifier(
6788            this=name,
6789            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6790        )
6791    else:
6792        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6793    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether to force quote the identifier.
  • copy: Whether 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:
6796def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6797    """
6798    Parses a given string into an identifier.
6799
6800    Args:
6801        name: The name to parse into an identifier.
6802        dialect: The dialect to parse against.
6803
6804    Returns:
6805        The identifier ast node.
6806    """
6807    try:
6808        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6809    except ParseError:
6810        expression = to_identifier(name)
6811
6812    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:
6818def to_interval(interval: str | Literal) -> Interval:
6819    """Builds an interval expression from a string like '1 day' or '5 months'."""
6820    if isinstance(interval, Literal):
6821        if not interval.is_string:
6822            raise ValueError("Invalid interval string.")
6823
6824        interval = interval.this
6825
6826    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6827
6828    if not interval_parts:
6829        raise ValueError("Invalid interval string.")
6830
6831    return Interval(
6832        this=Literal.string(interval_parts.group(1)),
6833        unit=Var(this=interval_parts.group(2).upper()),
6834    )

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

def to_table( sql_path: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
6837def to_table(
6838    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6839) -> Table:
6840    """
6841    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6842    If a table is passed in then that table is returned.
6843
6844    Args:
6845        sql_path: a `[catalog].[schema].[table]` string.
6846        dialect: the source dialect according to which the table name will be parsed.
6847        copy: Whether to copy a table if it is passed in.
6848        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6849
6850    Returns:
6851        A table expression.
6852    """
6853    if isinstance(sql_path, Table):
6854        return maybe_copy(sql_path, copy=copy)
6855
6856    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6857
6858    for k, v in kwargs.items():
6859        table.set(k, v)
6860
6861    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 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, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
6864def to_column(
6865    sql_path: str | Column,
6866    quoted: t.Optional[bool] = None,
6867    dialect: DialectType = None,
6868    copy: bool = True,
6869    **kwargs,
6870) -> Column:
6871    """
6872    Create a column from a `[table].[column]` sql path. Table is optional.
6873    If a column is passed in then that column is returned.
6874
6875    Args:
6876        sql_path: a `[table].[column]` string.
6877        quoted: Whether or not to force quote identifiers.
6878        dialect: the source dialect according to which the column name will be parsed.
6879        copy: Whether to copy a column if it is passed in.
6880        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6881
6882    Returns:
6883        A column expression.
6884    """
6885    if isinstance(sql_path, Column):
6886        return maybe_copy(sql_path, copy=copy)
6887
6888    try:
6889        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6890    except ParseError:
6891        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6892
6893    for k, v in kwargs.items():
6894        col.set(k, v)
6895
6896    if quoted:
6897        for i in col.find_all(Identifier):
6898            i.set("quoted", True)
6899
6900    return col

Create a column from a [table].[column] sql path. Table is optional. If a column is passed in then that column is returned.

Arguments:
  • sql_path: a [table].[column] string.
  • quoted: Whether or not to force quote identifiers.
  • dialect: the source dialect according to which the column name will be parsed.
  • copy: Whether to copy a column if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Column expression with.
Returns:

A column expression.

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], 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):
6903def alias_(
6904    expression: ExpOrStr,
6905    alias: t.Optional[str | Identifier],
6906    table: bool | t.Sequence[str | Identifier] = False,
6907    quoted: t.Optional[bool] = None,
6908    dialect: DialectType = None,
6909    copy: bool = True,
6910    **opts,
6911):
6912    """Create an Alias expression.
6913
6914    Example:
6915        >>> alias_('foo', 'bar').sql()
6916        'foo AS bar'
6917
6918        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6919        '(SELECT 1, 2) AS bar(a, b)'
6920
6921    Args:
6922        expression: the SQL code strings to parse.
6923            If an Expression instance is passed, this is used as-is.
6924        alias: the alias name to use. If the name has
6925            special characters it is quoted.
6926        table: Whether to create a table alias, can also be a list of columns.
6927        quoted: whether to quote the alias
6928        dialect: the dialect used to parse the input expression.
6929        copy: Whether to copy the expression.
6930        **opts: other options to use to parse the input expressions.
6931
6932    Returns:
6933        Alias: the aliased expression
6934    """
6935    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6936    alias = to_identifier(alias, quoted=quoted)
6937
6938    if table:
6939        table_alias = TableAlias(this=alias)
6940        exp.set("alias", table_alias)
6941
6942        if not isinstance(table, bool):
6943            for column in table:
6944                table_alias.append("columns", to_identifier(column, quoted=quoted))
6945
6946        return exp
6947
6948    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
6949    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
6950    # for the complete Window expression.
6951    #
6952    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
6953
6954    if "alias" in exp.arg_types and not isinstance(exp, Window):
6955        exp.set("alias", alias)
6956        return exp
6957    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 to create a table alias, can also be a list of columns.
  • quoted: whether to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether 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:
6960def subquery(
6961    expression: ExpOrStr,
6962    alias: t.Optional[Identifier | str] = None,
6963    dialect: DialectType = None,
6964    **opts,
6965) -> Select:
6966    """
6967    Build a subquery expression that's selected from.
6968
6969    Example:
6970        >>> subquery('select x from tbl', 'bar').select('x').sql()
6971        'SELECT x FROM (SELECT x FROM tbl) AS bar'
6972
6973    Args:
6974        expression: the SQL code strings to parse.
6975            If an Expression instance is passed, this is used as-is.
6976        alias: the alias name to use.
6977        dialect: the dialect used to parse the input expression.
6978        **opts: other options to use to parse the input expressions.
6979
6980    Returns:
6981        A new Select instance with the subquery expression included.
6982    """
6983
6984    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
6985    return Select().from_(expression, dialect=dialect, **opts)

Build a subquery expression that's selected from.

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):
7016def column(
7017    col,
7018    table=None,
7019    db=None,
7020    catalog=None,
7021    *,
7022    fields=None,
7023    quoted=None,
7024    copy=True,
7025):
7026    """
7027    Build a Column.
7028
7029    Args:
7030        col: Column name.
7031        table: Table name.
7032        db: Database name.
7033        catalog: Catalog name.
7034        fields: Additional fields using dots.
7035        quoted: Whether to force quotes on the column's identifiers.
7036        copy: Whether to copy identifiers if passed in.
7037
7038    Returns:
7039        The new Column instance.
7040    """
7041    this = Column(
7042        this=to_identifier(col, quoted=quoted, copy=copy),
7043        table=to_identifier(table, quoted=quoted, copy=copy),
7044        db=to_identifier(db, quoted=quoted, copy=copy),
7045        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7046    )
7047
7048    if fields:
7049        this = Dot.build(
7050            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7051        )
7052    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 to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, **opts) -> Cast:
7055def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7056    """Cast an expression to a data type.
7057
7058    Example:
7059        >>> cast('x + 1', 'int').sql()
7060        'CAST(x + 1 AS INT)'
7061
7062    Args:
7063        expression: The expression to cast.
7064        to: The datatype to cast to.
7065        copy: Whether to copy the supplied expressions.
7066
7067    Returns:
7068        The new Cast instance.
7069    """
7070    expr = maybe_parse(expression, copy=copy, **opts)
7071    data_type = DataType.build(to, copy=copy, **opts)
7072
7073    if expr.is_type(data_type):
7074        return expr
7075
7076    expr = Cast(this=expr, to=data_type)
7077    expr.type = data_type
7078
7079    return expr

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.
  • copy: Whether to copy the supplied expressions.
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:
7082def table_(
7083    table: Identifier | str,
7084    db: t.Optional[Identifier | str] = None,
7085    catalog: t.Optional[Identifier | str] = None,
7086    quoted: t.Optional[bool] = None,
7087    alias: t.Optional[Identifier | str] = None,
7088) -> Table:
7089    """Build a Table.
7090
7091    Args:
7092        table: Table name.
7093        db: Database name.
7094        catalog: Catalog name.
7095        quote: Whether to force quotes on the table's identifiers.
7096        alias: Table's alias.
7097
7098    Returns:
7099        The new Table instance.
7100    """
7101    return Table(
7102        this=to_identifier(table, quoted=quoted) if table else None,
7103        db=to_identifier(db, quoted=quoted) if db else None,
7104        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7105        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7106    )

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:
7109def values(
7110    values: t.Iterable[t.Tuple[t.Any, ...]],
7111    alias: t.Optional[str] = None,
7112    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7113) -> Values:
7114    """Build VALUES statement.
7115
7116    Example:
7117        >>> values([(1, '2')]).sql()
7118        "VALUES (1, '2')"
7119
7120    Args:
7121        values: values statements that will be converted to SQL
7122        alias: optional alias
7123        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7124         If either are provided then an alias is also required.
7125
7126    Returns:
7127        Values: the Values expression object
7128    """
7129    if columns and not alias:
7130        raise ValueError("Alias is required when providing columns")
7131
7132    return Values(
7133        expressions=[convert(tup) for tup in values],
7134        alias=(
7135            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7136            if columns
7137            else (TableAlias(this=to_identifier(alias)) if alias else None)
7138        ),
7139    )

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:
7142def var(name: t.Optional[ExpOrStr]) -> Var:
7143    """Build a SQL variable.
7144
7145    Example:
7146        >>> repr(var('x'))
7147        'Var(this=x)'
7148
7149        >>> repr(var(column('x', table='y')))
7150        'Var(this=x)'
7151
7152    Args:
7153        name: The name of the var or an expression who's name will become the var.
7154
7155    Returns:
7156        The new variable node.
7157    """
7158    if not name:
7159        raise ValueError("Cannot convert empty name into var.")
7160
7161    if isinstance(name, Expression):
7162        name = name.name
7163    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, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
7166def rename_table(
7167    old_name: str | Table,
7168    new_name: str | Table,
7169    dialect: DialectType = None,
7170) -> AlterTable:
7171    """Build ALTER TABLE... RENAME... expression
7172
7173    Args:
7174        old_name: The old name of the table
7175        new_name: The new name of the table
7176        dialect: The dialect to parse the table.
7177
7178    Returns:
7179        Alter table expression
7180    """
7181    old_table = to_table(old_name, dialect=dialect)
7182    new_table = to_table(new_name, dialect=dialect)
7183    return AlterTable(
7184        this=old_table,
7185        actions=[
7186            RenameTable(this=new_table),
7187        ],
7188    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
  • dialect: The dialect to parse the table.
Returns:

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
7191def rename_column(
7192    table_name: str | Table,
7193    old_column_name: str | Column,
7194    new_column_name: str | Column,
7195    exists: t.Optional[bool] = None,
7196    dialect: DialectType = None,
7197) -> AlterTable:
7198    """Build ALTER TABLE... RENAME COLUMN... expression
7199
7200    Args:
7201        table_name: Name of the table
7202        old_column: The old name of the column
7203        new_column: The new name of the column
7204        exists: Whether to add the `IF EXISTS` clause
7205        dialect: The dialect to parse the table/column.
7206
7207    Returns:
7208        Alter table expression
7209    """
7210    table = to_table(table_name, dialect=dialect)
7211    old_column = to_column(old_column_name, dialect=dialect)
7212    new_column = to_column(new_column_name, dialect=dialect)
7213    return AlterTable(
7214        this=table,
7215        actions=[
7216            RenameColumn(this=old_column, to=new_column, exists=exists),
7217        ],
7218    )

Build ALTER TABLE... RENAME COLUMN... expression

Arguments:
  • table_name: Name of the table
  • old_column: The old name of the column
  • new_column: The new name of the column
  • exists: Whether to add the IF EXISTS clause
  • dialect: The dialect to parse the table/column.
Returns:

Alter table expression

def convert(value: Any, copy: bool = False) -> Expression:
7221def convert(value: t.Any, copy: bool = False) -> Expression:
7222    """Convert a python value into an expression object.
7223
7224    Raises an error if a conversion is not possible.
7225
7226    Args:
7227        value: A python object.
7228        copy: Whether to copy `value` (only applies to Expressions and collections).
7229
7230    Returns:
7231        The equivalent expression object.
7232    """
7233    if isinstance(value, Expression):
7234        return maybe_copy(value, copy)
7235    if isinstance(value, str):
7236        return Literal.string(value)
7237    if isinstance(value, bool):
7238        return Boolean(this=value)
7239    if value is None or (isinstance(value, float) and math.isnan(value)):
7240        return null()
7241    if isinstance(value, numbers.Number):
7242        return Literal.number(value)
7243    if isinstance(value, bytes):
7244        return HexString(this=value.hex())
7245    if isinstance(value, datetime.datetime):
7246        datetime_literal = Literal.string(
7247            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7248                sep=" "
7249            )
7250        )
7251        return TimeStrToTime(this=datetime_literal)
7252    if isinstance(value, datetime.date):
7253        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7254        return DateStrToDate(this=date_literal)
7255    if isinstance(value, tuple):
7256        if hasattr(value, "_fields"):
7257            return Struct(
7258                expressions=[
7259                    PropertyEQ(
7260                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7261                    )
7262                    for k in value._fields
7263                ]
7264            )
7265        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7266    if isinstance(value, list):
7267        return Array(expressions=[convert(v, copy=copy) for v in value])
7268    if isinstance(value, dict):
7269        return Map(
7270            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7271            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7272        )
7273    if hasattr(value, "__dict__"):
7274        return Struct(
7275            expressions=[
7276                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7277                for k, v in value.__dict__.items()
7278            ]
7279        )
7280    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 to copy value (only applies to Expressions and collections).
Returns:

The equivalent expression object.

def replace_children( expression: Expression, fun: Callable, *args, **kwargs) -> None:
7283def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7284    """
7285    Replace children of an expression with the result of a lambda fun(child) -> exp.
7286    """
7287    for k, v in tuple(expression.args.items()):
7288        is_list_arg = type(v) is list
7289
7290        child_nodes = v if is_list_arg else [v]
7291        new_child_nodes = []
7292
7293        for cn in child_nodes:
7294            if isinstance(cn, Expression):
7295                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7296                    new_child_nodes.append(child_node)
7297            else:
7298                new_child_nodes.append(cn)
7299
7300        expression.set(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 replace_tree( expression: Expression, fun: Callable, prune: Optional[Callable[[Expression], bool]] = None) -> Expression:
7303def replace_tree(
7304    expression: Expression,
7305    fun: t.Callable,
7306    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7307) -> Expression:
7308    """
7309    Replace an entire tree with the result of function calls on each node.
7310
7311    This will be traversed in reverse dfs, so leaves first.
7312    If new nodes are created as a result of function calls, they will also be traversed.
7313    """
7314    stack = list(expression.dfs(prune=prune))
7315
7316    while stack:
7317        node = stack.pop()
7318        new_node = fun(node)
7319
7320        if new_node is not node:
7321            node.replace(new_node)
7322
7323            if isinstance(new_node, Expression):
7324                stack.append(new_node)
7325
7326    return new_node

Replace an entire tree with the result of function calls on each node.

This will be traversed in reverse dfs, so leaves first. If new nodes are created as a result of function calls, they will also be traversed.

def column_table_names( expression: Expression, exclude: str = '') -> Set[str]:
7329def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7330    """
7331    Return all table names referenced through columns in an expression.
7332
7333    Example:
7334        >>> import sqlglot
7335        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7336        ['a', 'c']
7337
7338    Args:
7339        expression: expression to find table names.
7340        exclude: a table name to exclude
7341
7342    Returns:
7343        A list of unique names.
7344    """
7345    return {
7346        table
7347        for table in (column.table for column in expression.find_all(Column))
7348        if table and table != exclude
7349    }

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:
7352def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7353    """Get the full name of a table as a string.
7354
7355    Args:
7356        table: Table expression node or string.
7357        dialect: The dialect to generate the table name for.
7358        identify: Determines when an identifier should be quoted. Possible values are:
7359            False (default): Never quote, except in cases where it's mandatory by the dialect.
7360            True: Always quote.
7361
7362    Examples:
7363        >>> from sqlglot import exp, parse_one
7364        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7365        'a.b.c'
7366
7367    Returns:
7368        The table name.
7369    """
7370
7371    table = maybe_parse(table, into=Table, dialect=dialect)
7372
7373    if not table:
7374        raise ValueError(f"Cannot parse {table}")
7375
7376    return ".".join(
7377        (
7378            part.sql(dialect=dialect, identify=True, copy=False)
7379            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7380            else part.name
7381        )
7382        for part in table.parts
7383    )

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:
7386def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7387    """Returns a case normalized table name without quotes.
7388
7389    Args:
7390        table: the table to normalize
7391        dialect: the dialect to use for normalization rules
7392        copy: whether to copy the expression.
7393
7394    Examples:
7395        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7396        'A-B.c'
7397    """
7398    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7399
7400    return ".".join(
7401        p.name
7402        for p in normalize_identifiers(
7403            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7404        ).parts
7405    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether 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:
7408def replace_tables(
7409    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7410) -> E:
7411    """Replace all tables in expression according to the mapping.
7412
7413    Args:
7414        expression: expression node to be transformed and replaced.
7415        mapping: mapping of table names.
7416        dialect: the dialect of the mapping table
7417        copy: whether to copy the expression.
7418
7419    Examples:
7420        >>> from sqlglot import exp, parse_one
7421        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7422        'SELECT * FROM c /* a.b */'
7423
7424    Returns:
7425        The mapped expression.
7426    """
7427
7428    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7429
7430    def _replace_tables(node: Expression) -> Expression:
7431        if isinstance(node, Table):
7432            original = normalize_table_name(node, dialect=dialect)
7433            new_name = mapping.get(original)
7434
7435            if new_name:
7436                table = to_table(
7437                    new_name,
7438                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7439                    dialect=dialect,
7440                )
7441                table.add_comments([original])
7442                return table
7443        return node
7444
7445    return expression.transform(_replace_tables, copy=copy)  # type: ignore

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 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:
7448def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7449    """Replace placeholders in an expression.
7450
7451    Args:
7452        expression: expression node to be transformed and replaced.
7453        args: positional names that will substitute unnamed placeholders in the given order.
7454        kwargs: keyword arguments that will substitute named placeholders.
7455
7456    Examples:
7457        >>> from sqlglot import exp, parse_one
7458        >>> replace_placeholders(
7459        ...     parse_one("select * from :tbl where ? = ?"),
7460        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7461        ... ).sql()
7462        "SELECT * FROM foo WHERE str_col = 'b'"
7463
7464    Returns:
7465        The mapped expression.
7466    """
7467
7468    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7469        if isinstance(node, Placeholder):
7470            if node.this:
7471                new_name = kwargs.get(node.this)
7472                if new_name is not None:
7473                    return convert(new_name)
7474            else:
7475                try:
7476                    return convert(next(args))
7477                except StopIteration:
7478                    pass
7479        return node
7480
7481    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, Query], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
7484def expand(
7485    expression: Expression,
7486    sources: t.Dict[str, Query],
7487    dialect: DialectType = None,
7488    copy: bool = True,
7489) -> Expression:
7490    """Transforms an expression by expanding all referenced sources into subqueries.
7491
7492    Examples:
7493        >>> from sqlglot import parse_one
7494        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7495        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7496
7497        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7498        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7499
7500    Args:
7501        expression: The expression to expand.
7502        sources: A dictionary of name to Queries.
7503        dialect: The dialect of the sources dict.
7504        copy: Whether to copy the expression during transformation. Defaults to True.
7505
7506    Returns:
7507        The transformed expression.
7508    """
7509    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7510
7511    def _expand(node: Expression):
7512        if isinstance(node, Table):
7513            name = normalize_table_name(node, dialect=dialect)
7514            source = sources.get(name)
7515            if source:
7516                subquery = source.subquery(node.alias or name)
7517                subquery.comments = [f"source: {name}"]
7518                return subquery.transform(_expand, copy=False)
7519        return node
7520
7521    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 Queries.
  • dialect: The dialect of the sources dict.
  • copy: Whether 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:
7524def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7525    """
7526    Returns a Func expression.
7527
7528    Examples:
7529        >>> func("abs", 5).sql()
7530        'ABS(5)'
7531
7532        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7533        'CAST(5 AS DOUBLE)'
7534
7535    Args:
7536        name: the name of the function to build.
7537        args: the args used to instantiate the function of interest.
7538        copy: whether to copy the argument expressions.
7539        dialect: the source dialect.
7540        kwargs: the kwargs used to instantiate the function of interest.
7541
7542    Note:
7543        The arguments `args` and `kwargs` are mutually exclusive.
7544
7545    Returns:
7546        An instance of the function of interest, or an anonymous function, if `name` doesn't
7547        correspond to an existing `sqlglot.expressions.Func` class.
7548    """
7549    if args and kwargs:
7550        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7551
7552    from sqlglot.dialects.dialect import Dialect
7553
7554    dialect = Dialect.get_or_raise(dialect)
7555
7556    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7557    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7558
7559    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7560    if constructor:
7561        if converted:
7562            if "dialect" in constructor.__code__.co_varnames:
7563                function = constructor(converted, dialect=dialect)
7564            else:
7565                function = constructor(converted)
7566        elif constructor.__name__ == "from_arg_list":
7567            function = constructor.__self__(**kwargs)  # type: ignore
7568        else:
7569            constructor = FUNCTION_BY_NAME.get(name.upper())
7570            if constructor:
7571                function = constructor(**kwargs)
7572            else:
7573                raise ValueError(
7574                    f"Unable to convert '{name}' into a Func. Either manually construct "
7575                    "the Func expression of interest or parse the function call."
7576                )
7577    else:
7578        kwargs = kwargs or {"expressions": converted}
7579        function = Anonymous(this=name, **kwargs)
7580
7581    for error_message in function.error_messages(converted):
7582        raise ValueError(error_message)
7583
7584    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 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:
7587def case(
7588    expression: t.Optional[ExpOrStr] = None,
7589    **opts,
7590) -> Case:
7591    """
7592    Initialize a CASE statement.
7593
7594    Example:
7595        case().when("a = 1", "foo").else_("bar")
7596
7597    Args:
7598        expression: Optionally, the input expression (not all dialects support this)
7599        **opts: Extra keyword arguments for parsing `expression`
7600    """
7601    if expression is not None:
7602        this = maybe_parse(expression, **opts)
7603    else:
7604        this = None
7605    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 array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Array:
7608def array(
7609    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7610) -> Array:
7611    """
7612    Returns an array.
7613
7614    Examples:
7615        >>> array(1, 'x').sql()
7616        'ARRAY(1, x)'
7617
7618    Args:
7619        expressions: the expressions to add to the array.
7620        copy: whether to copy the argument expressions.
7621        dialect: the source dialect.
7622        kwargs: the kwargs used to instantiate the function of interest.
7623
7624    Returns:
7625        An array expression.
7626    """
7627    return Array(
7628        expressions=[
7629            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7630            for expression in expressions
7631        ]
7632    )

Returns an array.

Examples:
>>> array(1, 'x').sql()
'ARRAY(1, x)'
Arguments:
  • expressions: the expressions to add to the array.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Tuple:
7635def tuple_(
7636    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7637) -> Tuple:
7638    """
7639    Returns an tuple.
7640
7641    Examples:
7642        >>> tuple_(1, 'x').sql()
7643        '(1, x)'
7644
7645    Args:
7646        expressions: the expressions to add to the tuple.
7647        copy: whether to copy the argument expressions.
7648        dialect: the source dialect.
7649        kwargs: the kwargs used to instantiate the function of interest.
7650
7651    Returns:
7652        A tuple expression.
7653    """
7654    return Tuple(
7655        expressions=[
7656            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7657            for expression in expressions
7658        ]
7659    )

Returns an tuple.

Examples:
>>> tuple_(1, 'x').sql()
'(1, x)'
Arguments:
  • expressions: the expressions to add to the tuple.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

A tuple expression.

def true() -> Boolean:
7662def true() -> Boolean:
7663    """
7664    Returns a true Boolean expression.
7665    """
7666    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7669def false() -> Boolean:
7670    """
7671    Returns a false Boolean expression.
7672    """
7673    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7676def null() -> Null:
7677    """
7678    Returns a Null expression.
7679    """
7680    return Null()

Returns a Null expression.

NONNULL_CONSTANTS = (<class 'Literal'>, <class 'Boolean'>)
CONSTANTS = (<class 'Literal'>, <class 'Boolean'>, <class 'Null'>)