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 decimal import Decimal
  24from enum import auto
  25from functools import reduce
  26
  27from sqlglot.errors import ErrorLevel, ParseError
  28from sqlglot.helper import (
  29    AutoName,
  30    camel_to_snake_case,
  31    ensure_collection,
  32    ensure_list,
  33    seq_get,
  34    subclasses,
  35)
  36from sqlglot.tokens import Token
  37
  38if t.TYPE_CHECKING:
  39    from sqlglot._typing import E, Lit
  40    from sqlglot.dialects.dialect import DialectType
  41
  42    Q = t.TypeVar("Q", bound="Query")
  43    S = t.TypeVar("S", bound="SetOperation")
  44
  45
  46class _Expression(type):
  47    def __new__(cls, clsname, bases, attrs):
  48        klass = super().__new__(cls, clsname, bases, attrs)
  49
  50        # When an Expression class is created, its key is automatically set to be
  51        # the lowercase version of the class' name.
  52        klass.key = clsname.lower()
  53
  54        # This is so that docstrings are not inherited in pdoc
  55        klass.__doc__ = klass.__doc__ or ""
  56
  57        return klass
  58
  59
  60SQLGLOT_META = "sqlglot.meta"
  61TABLE_PARTS = ("this", "db", "catalog")
  62COLUMN_PARTS = ("this", "table", "db", "catalog")
  63
  64
  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"]) or (
 179            isinstance(self, Neg) and self.this.is_number
 180        )
 181
 182    def to_py(self) -> t.Any:
 183        """
 184        Returns a Python object equivalent of the SQL node.
 185        """
 186        raise ValueError(f"{self} cannot be converted to a Python object.")
 187
 188    @property
 189    def is_int(self) -> bool:
 190        """
 191        Checks whether an expression is an integer.
 192        """
 193        return self.is_number and isinstance(self.to_py(), int)
 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        "on": False,
2131    }
2132
2133
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        )
2187
2188
2189class OnConflict(Expression):
2190    arg_types = {
2191        "duplicate": False,
2192        "expressions": False,
2193        "action": False,
2194        "conflict_keys": False,
2195        "constraint": False,
2196    }
2197
2198
2199class Returning(Expression):
2200    arg_types = {"expressions": True, "into": False}
2201
2202
2203# https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html
2204class Introducer(Expression):
2205    arg_types = {"this": True, "expression": True}
2206
2207
2208# national char, like n'utf8'
2209class National(Expression):
2210    pass
2211
2212
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    }
2223
2224
2225class Partition(Expression):
2226    arg_types = {"expressions": True}
2227
2228
2229class PartitionRange(Expression):
2230    arg_types = {"this": True, "expression": True}
2231
2232
2233# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#how-to-set-partition-expression
2234class PartitionId(Expression):
2235    pass
2236
2237
2238class Fetch(Expression):
2239    arg_types = {
2240        "direction": False,
2241        "count": False,
2242        "percent": False,
2243        "with_ties": False,
2244    }
2245
2246
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    }
2256
2257
2258class Lambda(Expression):
2259    arg_types = {"this": True, "expressions": True}
2260
2261
2262class Limit(Expression):
2263    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
2264
2265
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
2284
2285    def to_py(self) -> int | str | Decimal:
2286        if self.is_number:
2287            try:
2288                return int(self.this)
2289            except ValueError:
2290                return Decimal(self.this)
2291        return self.this
2292
2293
2294class Join(Expression):
2295    arg_types = {
2296        "this": True,
2297        "on": False,
2298        "side": False,
2299        "kind": False,
2300        "using": False,
2301        "method": False,
2302        "global": False,
2303        "hint": False,
2304        "match_condition": False,  # Snowflake
2305    }
2306
2307    @property
2308    def method(self) -> str:
2309        return self.text("method").upper()
2310
2311    @property
2312    def kind(self) -> str:
2313        return self.text("kind").upper()
2314
2315    @property
2316    def side(self) -> str:
2317        return self.text("side").upper()
2318
2319    @property
2320    def hint(self) -> str:
2321        return self.text("hint").upper()
2322
2323    @property
2324    def alias_or_name(self) -> str:
2325        return self.this.alias_or_name
2326
2327    def on(
2328        self,
2329        *expressions: t.Optional[ExpOrStr],
2330        append: bool = True,
2331        dialect: DialectType = None,
2332        copy: bool = True,
2333        **opts,
2334    ) -> Join:
2335        """
2336        Append to or set the ON expressions.
2337
2338        Example:
2339            >>> import sqlglot
2340            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2341            'JOIN x ON y = 1'
2342
2343        Args:
2344            *expressions: the SQL code strings to parse.
2345                If an `Expression` instance is passed, it will be used as-is.
2346                Multiple expressions are combined with an AND operator.
2347            append: if `True`, AND the new expressions to any existing expression.
2348                Otherwise, this resets the expression.
2349            dialect: the dialect used to parse the input expressions.
2350            copy: if `False`, modify this expression instance in-place.
2351            opts: other options to use to parse the input expressions.
2352
2353        Returns:
2354            The modified Join expression.
2355        """
2356        join = _apply_conjunction_builder(
2357            *expressions,
2358            instance=self,
2359            arg="on",
2360            append=append,
2361            dialect=dialect,
2362            copy=copy,
2363            **opts,
2364        )
2365
2366        if join.kind == "CROSS":
2367            join.set("kind", None)
2368
2369        return join
2370
2371    def using(
2372        self,
2373        *expressions: t.Optional[ExpOrStr],
2374        append: bool = True,
2375        dialect: DialectType = None,
2376        copy: bool = True,
2377        **opts,
2378    ) -> Join:
2379        """
2380        Append to or set the USING expressions.
2381
2382        Example:
2383            >>> import sqlglot
2384            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2385            'JOIN x USING (foo, bla)'
2386
2387        Args:
2388            *expressions: the SQL code strings to parse.
2389                If an `Expression` instance is passed, it will be used as-is.
2390            append: if `True`, concatenate the new expressions to the existing "using" list.
2391                Otherwise, this resets the expression.
2392            dialect: the dialect used to parse the input expressions.
2393            copy: if `False`, modify this expression instance in-place.
2394            opts: other options to use to parse the input expressions.
2395
2396        Returns:
2397            The modified Join expression.
2398        """
2399        join = _apply_list_builder(
2400            *expressions,
2401            instance=self,
2402            arg="using",
2403            append=append,
2404            dialect=dialect,
2405            copy=copy,
2406            **opts,
2407        )
2408
2409        if join.kind == "CROSS":
2410            join.set("kind", None)
2411
2412        return join
2413
2414
2415class Lateral(UDTF):
2416    arg_types = {
2417        "this": True,
2418        "view": False,
2419        "outer": False,
2420        "alias": False,
2421        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2422    }
2423
2424
2425class MatchRecognizeMeasure(Expression):
2426    arg_types = {
2427        "this": True,
2428        "window_frame": False,
2429    }
2430
2431
2432class MatchRecognize(Expression):
2433    arg_types = {
2434        "partition_by": False,
2435        "order": False,
2436        "measures": False,
2437        "rows": False,
2438        "after": False,
2439        "pattern": False,
2440        "define": False,
2441        "alias": False,
2442    }
2443
2444
2445# Clickhouse FROM FINAL modifier
2446# https://clickhouse.com/docs/en/sql-reference/statements/select/from/#final-modifier
2447class Final(Expression):
2448    pass
2449
2450
2451class Offset(Expression):
2452    arg_types = {"this": False, "expression": True, "expressions": False}
2453
2454
2455class Order(Expression):
2456    arg_types = {
2457        "this": False,
2458        "expressions": True,
2459        "interpolate": False,
2460        "siblings": False,
2461    }
2462
2463
2464# https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier
2465class WithFill(Expression):
2466    arg_types = {"from": False, "to": False, "step": False}
2467
2468
2469# hive specific sorts
2470# https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy
2471class Cluster(Order):
2472    pass
2473
2474
2475class Distribute(Order):
2476    pass
2477
2478
2479class Sort(Order):
2480    pass
2481
2482
2483class Ordered(Expression):
2484    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2485
2486
2487class Property(Expression):
2488    arg_types = {"this": True, "value": True}
2489
2490
2491class AllowedValuesProperty(Expression):
2492    arg_types = {"expressions": True}
2493
2494
2495class AlgorithmProperty(Property):
2496    arg_types = {"this": True}
2497
2498
2499class AutoIncrementProperty(Property):
2500    arg_types = {"this": True}
2501
2502
2503# https://docs.aws.amazon.com/prescriptive-guidance/latest/materialized-views-redshift/refreshing-materialized-views.html
2504class AutoRefreshProperty(Property):
2505    arg_types = {"this": True}
2506
2507
2508class BackupProperty(Property):
2509    arg_types = {"this": True}
2510
2511
2512class BlockCompressionProperty(Property):
2513    arg_types = {
2514        "autotemp": False,
2515        "always": False,
2516        "default": False,
2517        "manual": False,
2518        "never": False,
2519    }
2520
2521
2522class CharacterSetProperty(Property):
2523    arg_types = {"this": True, "default": True}
2524
2525
2526class ChecksumProperty(Property):
2527    arg_types = {"on": False, "default": False}
2528
2529
2530class CollateProperty(Property):
2531    arg_types = {"this": True, "default": False}
2532
2533
2534class CopyGrantsProperty(Property):
2535    arg_types = {}
2536
2537
2538class DataBlocksizeProperty(Property):
2539    arg_types = {
2540        "size": False,
2541        "units": False,
2542        "minimum": False,
2543        "maximum": False,
2544        "default": False,
2545    }
2546
2547
2548class DataDeletionProperty(Property):
2549    arg_types = {"on": True, "filter_col": False, "retention_period": False}
2550
2551
2552class DefinerProperty(Property):
2553    arg_types = {"this": True}
2554
2555
2556class DistKeyProperty(Property):
2557    arg_types = {"this": True}
2558
2559
2560class DistStyleProperty(Property):
2561    arg_types = {"this": True}
2562
2563
2564class EngineProperty(Property):
2565    arg_types = {"this": True}
2566
2567
2568class HeapProperty(Property):
2569    arg_types = {}
2570
2571
2572class ToTableProperty(Property):
2573    arg_types = {"this": True}
2574
2575
2576class ExecuteAsProperty(Property):
2577    arg_types = {"this": True}
2578
2579
2580class ExternalProperty(Property):
2581    arg_types = {"this": False}
2582
2583
2584class FallbackProperty(Property):
2585    arg_types = {"no": True, "protection": False}
2586
2587
2588class FileFormatProperty(Property):
2589    arg_types = {"this": True}
2590
2591
2592class FreespaceProperty(Property):
2593    arg_types = {"this": True, "percent": False}
2594
2595
2596class GlobalProperty(Property):
2597    arg_types = {}
2598
2599
2600class IcebergProperty(Property):
2601    arg_types = {}
2602
2603
2604class InheritsProperty(Property):
2605    arg_types = {"expressions": True}
2606
2607
2608class InputModelProperty(Property):
2609    arg_types = {"this": True}
2610
2611
2612class OutputModelProperty(Property):
2613    arg_types = {"this": True}
2614
2615
2616class IsolatedLoadingProperty(Property):
2617    arg_types = {"no": False, "concurrent": False, "target": False}
2618
2619
2620class JournalProperty(Property):
2621    arg_types = {
2622        "no": False,
2623        "dual": False,
2624        "before": False,
2625        "local": False,
2626        "after": False,
2627    }
2628
2629
2630class LanguageProperty(Property):
2631    arg_types = {"this": True}
2632
2633
2634# spark ddl
2635class ClusteredByProperty(Property):
2636    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
2637
2638
2639class DictProperty(Property):
2640    arg_types = {"this": True, "kind": True, "settings": False}
2641
2642
2643class DictSubProperty(Property):
2644    pass
2645
2646
2647class DictRange(Property):
2648    arg_types = {"this": True, "min": True, "max": True}
2649
2650
2651class DynamicProperty(Property):
2652    arg_types = {}
2653
2654
2655# Clickhouse CREATE ... ON CLUSTER modifier
2656# https://clickhouse.com/docs/en/sql-reference/distributed-ddl
2657class OnCluster(Property):
2658    arg_types = {"this": True}
2659
2660
2661class LikeProperty(Property):
2662    arg_types = {"this": True, "expressions": False}
2663
2664
2665class LocationProperty(Property):
2666    arg_types = {"this": True}
2667
2668
2669class LockProperty(Property):
2670    arg_types = {"this": True}
2671
2672
2673class LockingProperty(Property):
2674    arg_types = {
2675        "this": False,
2676        "kind": True,
2677        "for_or_in": False,
2678        "lock_type": True,
2679        "override": False,
2680    }
2681
2682
2683class LogProperty(Property):
2684    arg_types = {"no": True}
2685
2686
2687class MaterializedProperty(Property):
2688    arg_types = {"this": False}
2689
2690
2691class MergeBlockRatioProperty(Property):
2692    arg_types = {"this": False, "no": False, "default": False, "percent": False}
2693
2694
2695class NoPrimaryIndexProperty(Property):
2696    arg_types = {}
2697
2698
2699class OnProperty(Property):
2700    arg_types = {"this": True}
2701
2702
2703class OnCommitProperty(Property):
2704    arg_types = {"delete": False}
2705
2706
2707class PartitionedByProperty(Property):
2708    arg_types = {"this": True}
2709
2710
2711# https://www.postgresql.org/docs/current/sql-createtable.html
2712class PartitionBoundSpec(Expression):
2713    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2714    arg_types = {
2715        "this": False,
2716        "expression": False,
2717        "from_expressions": False,
2718        "to_expressions": False,
2719    }
2720
2721
2722class PartitionedOfProperty(Property):
2723    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2724    arg_types = {"this": True, "expression": True}
2725
2726
2727class RemoteWithConnectionModelProperty(Property):
2728    arg_types = {"this": True}
2729
2730
2731class ReturnsProperty(Property):
2732    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
2733
2734
2735class StrictProperty(Property):
2736    arg_types = {}
2737
2738
2739class RowFormatProperty(Property):
2740    arg_types = {"this": True}
2741
2742
2743class RowFormatDelimitedProperty(Property):
2744    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2745    arg_types = {
2746        "fields": False,
2747        "escaped": False,
2748        "collection_items": False,
2749        "map_keys": False,
2750        "lines": False,
2751        "null": False,
2752        "serde": False,
2753    }
2754
2755
2756class RowFormatSerdeProperty(Property):
2757    arg_types = {"this": True, "serde_properties": False}
2758
2759
2760# https://spark.apache.org/docs/3.1.2/sql-ref-syntax-qry-select-transform.html
2761class QueryTransform(Expression):
2762    arg_types = {
2763        "expressions": True,
2764        "command_script": True,
2765        "schema": False,
2766        "row_format_before": False,
2767        "record_writer": False,
2768        "row_format_after": False,
2769        "record_reader": False,
2770    }
2771
2772
2773class SampleProperty(Property):
2774    arg_types = {"this": True}
2775
2776
2777class SchemaCommentProperty(Property):
2778    arg_types = {"this": True}
2779
2780
2781class SerdeProperties(Property):
2782    arg_types = {"expressions": True, "with": False}
2783
2784
2785class SetProperty(Property):
2786    arg_types = {"multi": True}
2787
2788
2789class SharingProperty(Property):
2790    arg_types = {"this": False}
2791
2792
2793class SetConfigProperty(Property):
2794    arg_types = {"this": True}
2795
2796
2797class SettingsProperty(Property):
2798    arg_types = {"expressions": True}
2799
2800
2801class SortKeyProperty(Property):
2802    arg_types = {"this": True, "compound": False}
2803
2804
2805class SqlReadWriteProperty(Property):
2806    arg_types = {"this": True}
2807
2808
2809class SqlSecurityProperty(Property):
2810    arg_types = {"definer": True}
2811
2812
2813class StabilityProperty(Property):
2814    arg_types = {"this": True}
2815
2816
2817class TemporaryProperty(Property):
2818    arg_types = {"this": False}
2819
2820
2821class SecureProperty(Property):
2822    arg_types = {}
2823
2824
2825class TransformModelProperty(Property):
2826    arg_types = {"expressions": True}
2827
2828
2829class TransientProperty(Property):
2830    arg_types = {"this": False}
2831
2832
2833class UnloggedProperty(Property):
2834    arg_types = {}
2835
2836
2837# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql?view=sql-server-ver16
2838class ViewAttributeProperty(Property):
2839    arg_types = {"this": True}
2840
2841
2842class VolatileProperty(Property):
2843    arg_types = {"this": False}
2844
2845
2846class WithDataProperty(Property):
2847    arg_types = {"no": True, "statistics": False}
2848
2849
2850class WithJournalTableProperty(Property):
2851    arg_types = {"this": True}
2852
2853
2854class WithSystemVersioningProperty(Property):
2855    arg_types = {
2856        "on": False,
2857        "this": False,
2858        "data_consistency": False,
2859        "retention_period": False,
2860        "with": True,
2861    }
2862
2863
2864class Properties(Expression):
2865    arg_types = {"expressions": True}
2866
2867    NAME_TO_PROPERTY = {
2868        "ALGORITHM": AlgorithmProperty,
2869        "AUTO_INCREMENT": AutoIncrementProperty,
2870        "CHARACTER SET": CharacterSetProperty,
2871        "CLUSTERED_BY": ClusteredByProperty,
2872        "COLLATE": CollateProperty,
2873        "COMMENT": SchemaCommentProperty,
2874        "DEFINER": DefinerProperty,
2875        "DISTKEY": DistKeyProperty,
2876        "DISTSTYLE": DistStyleProperty,
2877        "ENGINE": EngineProperty,
2878        "EXECUTE AS": ExecuteAsProperty,
2879        "FORMAT": FileFormatProperty,
2880        "LANGUAGE": LanguageProperty,
2881        "LOCATION": LocationProperty,
2882        "LOCK": LockProperty,
2883        "PARTITIONED_BY": PartitionedByProperty,
2884        "RETURNS": ReturnsProperty,
2885        "ROW_FORMAT": RowFormatProperty,
2886        "SORTKEY": SortKeyProperty,
2887    }
2888
2889    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2890
2891    # CREATE property locations
2892    # Form: schema specified
2893    #   create [POST_CREATE]
2894    #     table a [POST_NAME]
2895    #     (b int) [POST_SCHEMA]
2896    #     with ([POST_WITH])
2897    #     index (b) [POST_INDEX]
2898    #
2899    # Form: alias selection
2900    #   create [POST_CREATE]
2901    #     table a [POST_NAME]
2902    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2903    #     index (c) [POST_INDEX]
2904    class Location(AutoName):
2905        POST_CREATE = auto()
2906        POST_NAME = auto()
2907        POST_SCHEMA = auto()
2908        POST_WITH = auto()
2909        POST_ALIAS = auto()
2910        POST_EXPRESSION = auto()
2911        POST_INDEX = auto()
2912        UNSUPPORTED = auto()
2913
2914    @classmethod
2915    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2916        expressions = []
2917        for key, value in properties_dict.items():
2918            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2919            if property_cls:
2920                expressions.append(property_cls(this=convert(value)))
2921            else:
2922                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2923
2924        return cls(expressions=expressions)
2925
2926
2927class Qualify(Expression):
2928    pass
2929
2930
2931class InputOutputFormat(Expression):
2932    arg_types = {"input_format": False, "output_format": False}
2933
2934
2935# https://www.ibm.com/docs/en/ias?topic=procedures-return-statement-in-sql
2936class Return(Expression):
2937    pass
2938
2939
2940class Reference(Expression):
2941    arg_types = {"this": True, "expressions": False, "options": False}
2942
2943
2944class Tuple(Expression):
2945    arg_types = {"expressions": False}
2946
2947    def isin(
2948        self,
2949        *expressions: t.Any,
2950        query: t.Optional[ExpOrStr] = None,
2951        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2952        copy: bool = True,
2953        **opts,
2954    ) -> In:
2955        return In(
2956            this=maybe_copy(self, copy),
2957            expressions=[convert(e, copy=copy) for e in expressions],
2958            query=maybe_parse(query, copy=copy, **opts) if query else None,
2959            unnest=(
2960                Unnest(
2961                    expressions=[
2962                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2963                        for e in ensure_list(unnest)
2964                    ]
2965                )
2966                if unnest
2967                else None
2968            ),
2969        )
2970
2971
2972QUERY_MODIFIERS = {
2973    "match": False,
2974    "laterals": False,
2975    "joins": False,
2976    "connect": False,
2977    "pivots": False,
2978    "prewhere": False,
2979    "where": False,
2980    "group": False,
2981    "having": False,
2982    "qualify": False,
2983    "windows": False,
2984    "distribute": False,
2985    "sort": False,
2986    "cluster": False,
2987    "order": False,
2988    "limit": False,
2989    "offset": False,
2990    "locks": False,
2991    "sample": False,
2992    "settings": False,
2993    "format": False,
2994    "options": False,
2995}
2996
2997
2998# https://learn.microsoft.com/en-us/sql/t-sql/queries/option-clause-transact-sql?view=sql-server-ver16
2999# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-ver16
3000class QueryOption(Expression):
3001    arg_types = {"this": True, "expression": False}
3002
3003
3004# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16
3005class WithTableHint(Expression):
3006    arg_types = {"expressions": True}
3007
3008
3009# https://dev.mysql.com/doc/refman/8.0/en/index-hints.html
3010class IndexTableHint(Expression):
3011    arg_types = {"this": True, "expressions": False, "target": False}
3012
3013
3014# https://docs.snowflake.com/en/sql-reference/constructs/at-before
3015class HistoricalData(Expression):
3016    arg_types = {"this": True, "kind": True, "expression": True}
3017
3018
3019class Table(Expression):
3020    arg_types = {
3021        "this": False,
3022        "alias": False,
3023        "db": False,
3024        "catalog": False,
3025        "laterals": False,
3026        "joins": False,
3027        "pivots": False,
3028        "hints": False,
3029        "system_time": False,
3030        "version": False,
3031        "format": False,
3032        "pattern": False,
3033        "ordinality": False,
3034        "when": False,
3035        "only": False,
3036        "partition": False,
3037    }
3038
3039    @property
3040    def name(self) -> str:
3041        if isinstance(self.this, Func):
3042            return ""
3043        return self.this.name
3044
3045    @property
3046    def db(self) -> str:
3047        return self.text("db")
3048
3049    @property
3050    def catalog(self) -> str:
3051        return self.text("catalog")
3052
3053    @property
3054    def selects(self) -> t.List[Expression]:
3055        return []
3056
3057    @property
3058    def named_selects(self) -> t.List[str]:
3059        return []
3060
3061    @property
3062    def parts(self) -> t.List[Expression]:
3063        """Return the parts of a table in order catalog, db, table."""
3064        parts: t.List[Expression] = []
3065
3066        for arg in ("catalog", "db", "this"):
3067            part = self.args.get(arg)
3068
3069            if isinstance(part, Dot):
3070                parts.extend(part.flatten())
3071            elif isinstance(part, Expression):
3072                parts.append(part)
3073
3074        return parts
3075
3076    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3077        parts = self.parts
3078        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3079        alias = self.args.get("alias")
3080        if alias:
3081            col = alias_(col, alias.this, copy=copy)
3082        return col
3083
3084
3085class SetOperation(Query):
3086    arg_types = {
3087        "with": False,
3088        "this": True,
3089        "expression": True,
3090        "distinct": False,
3091        "by_name": False,
3092        **QUERY_MODIFIERS,
3093    }
3094
3095    def select(
3096        self: S,
3097        *expressions: t.Optional[ExpOrStr],
3098        append: bool = True,
3099        dialect: DialectType = None,
3100        copy: bool = True,
3101        **opts,
3102    ) -> S:
3103        this = maybe_copy(self, copy)
3104        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3105        this.expression.unnest().select(
3106            *expressions, append=append, dialect=dialect, copy=False, **opts
3107        )
3108        return this
3109
3110    @property
3111    def named_selects(self) -> t.List[str]:
3112        return self.this.unnest().named_selects
3113
3114    @property
3115    def is_star(self) -> bool:
3116        return self.this.is_star or self.expression.is_star
3117
3118    @property
3119    def selects(self) -> t.List[Expression]:
3120        return self.this.unnest().selects
3121
3122    @property
3123    def left(self) -> Expression:
3124        return self.this
3125
3126    @property
3127    def right(self) -> Expression:
3128        return self.expression
3129
3130
3131class Union(SetOperation):
3132    pass
3133
3134
3135class Except(SetOperation):
3136    pass
3137
3138
3139class Intersect(SetOperation):
3140    pass
3141
3142
3143class Update(Expression):
3144    arg_types = {
3145        "with": False,
3146        "this": False,
3147        "expressions": True,
3148        "from": False,
3149        "where": False,
3150        "returning": False,
3151        "order": False,
3152        "limit": False,
3153    }
3154
3155
3156class Values(UDTF):
3157    arg_types = {"expressions": True, "alias": False}
3158
3159
3160class Var(Expression):
3161    pass
3162
3163
3164class Version(Expression):
3165    """
3166    Time travel, iceberg, bigquery etc
3167    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3168    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3169    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3170    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3171    this is either TIMESTAMP or VERSION
3172    kind is ("AS OF", "BETWEEN")
3173    """
3174
3175    arg_types = {"this": True, "kind": True, "expression": False}
3176
3177
3178class Schema(Expression):
3179    arg_types = {"this": False, "expressions": False}
3180
3181
3182# https://dev.mysql.com/doc/refman/8.0/en/select.html
3183# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html
3184class Lock(Expression):
3185    arg_types = {"update": True, "expressions": False, "wait": False}
3186
3187
3188class Select(Query):
3189    arg_types = {
3190        "with": False,
3191        "kind": False,
3192        "expressions": False,
3193        "hint": False,
3194        "distinct": False,
3195        "into": False,
3196        "from": False,
3197        **QUERY_MODIFIERS,
3198    }
3199
3200    def from_(
3201        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3202    ) -> Select:
3203        """
3204        Set the FROM expression.
3205
3206        Example:
3207            >>> Select().from_("tbl").select("x").sql()
3208            'SELECT x FROM tbl'
3209
3210        Args:
3211            expression : the SQL code strings to parse.
3212                If a `From` instance is passed, this is used as-is.
3213                If another `Expression` instance is passed, it will be wrapped in a `From`.
3214            dialect: the dialect used to parse the input expression.
3215            copy: if `False`, modify this expression instance in-place.
3216            opts: other options to use to parse the input expressions.
3217
3218        Returns:
3219            The modified Select expression.
3220        """
3221        return _apply_builder(
3222            expression=expression,
3223            instance=self,
3224            arg="from",
3225            into=From,
3226            prefix="FROM",
3227            dialect=dialect,
3228            copy=copy,
3229            **opts,
3230        )
3231
3232    def group_by(
3233        self,
3234        *expressions: t.Optional[ExpOrStr],
3235        append: bool = True,
3236        dialect: DialectType = None,
3237        copy: bool = True,
3238        **opts,
3239    ) -> Select:
3240        """
3241        Set the GROUP BY expression.
3242
3243        Example:
3244            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3245            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3246
3247        Args:
3248            *expressions: the SQL code strings to parse.
3249                If a `Group` instance is passed, this is used as-is.
3250                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3251                If nothing is passed in then a group by is not applied to the expression
3252            append: if `True`, add to any existing expressions.
3253                Otherwise, this flattens all the `Group` expression into a single expression.
3254            dialect: the dialect used to parse the input expression.
3255            copy: if `False`, modify this expression instance in-place.
3256            opts: other options to use to parse the input expressions.
3257
3258        Returns:
3259            The modified Select expression.
3260        """
3261        if not expressions:
3262            return self if not copy else self.copy()
3263
3264        return _apply_child_list_builder(
3265            *expressions,
3266            instance=self,
3267            arg="group",
3268            append=append,
3269            copy=copy,
3270            prefix="GROUP BY",
3271            into=Group,
3272            dialect=dialect,
3273            **opts,
3274        )
3275
3276    def sort_by(
3277        self,
3278        *expressions: t.Optional[ExpOrStr],
3279        append: bool = True,
3280        dialect: DialectType = None,
3281        copy: bool = True,
3282        **opts,
3283    ) -> Select:
3284        """
3285        Set the SORT BY expression.
3286
3287        Example:
3288            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3289            'SELECT x FROM tbl SORT BY x DESC'
3290
3291        Args:
3292            *expressions: the SQL code strings to parse.
3293                If a `Group` instance is passed, this is used as-is.
3294                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3295            append: if `True`, add to any existing expressions.
3296                Otherwise, this flattens all the `Order` expression into a single expression.
3297            dialect: the dialect used to parse the input expression.
3298            copy: if `False`, modify this expression instance in-place.
3299            opts: other options to use to parse the input expressions.
3300
3301        Returns:
3302            The modified Select expression.
3303        """
3304        return _apply_child_list_builder(
3305            *expressions,
3306            instance=self,
3307            arg="sort",
3308            append=append,
3309            copy=copy,
3310            prefix="SORT BY",
3311            into=Sort,
3312            dialect=dialect,
3313            **opts,
3314        )
3315
3316    def cluster_by(
3317        self,
3318        *expressions: t.Optional[ExpOrStr],
3319        append: bool = True,
3320        dialect: DialectType = None,
3321        copy: bool = True,
3322        **opts,
3323    ) -> Select:
3324        """
3325        Set the CLUSTER BY expression.
3326
3327        Example:
3328            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3329            'SELECT x FROM tbl CLUSTER BY x DESC'
3330
3331        Args:
3332            *expressions: the SQL code strings to parse.
3333                If a `Group` instance is passed, this is used as-is.
3334                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3335            append: if `True`, add to any existing expressions.
3336                Otherwise, this flattens all the `Order` expression into a single expression.
3337            dialect: the dialect used to parse the input expression.
3338            copy: if `False`, modify this expression instance in-place.
3339            opts: other options to use to parse the input expressions.
3340
3341        Returns:
3342            The modified Select expression.
3343        """
3344        return _apply_child_list_builder(
3345            *expressions,
3346            instance=self,
3347            arg="cluster",
3348            append=append,
3349            copy=copy,
3350            prefix="CLUSTER BY",
3351            into=Cluster,
3352            dialect=dialect,
3353            **opts,
3354        )
3355
3356    def select(
3357        self,
3358        *expressions: t.Optional[ExpOrStr],
3359        append: bool = True,
3360        dialect: DialectType = None,
3361        copy: bool = True,
3362        **opts,
3363    ) -> Select:
3364        return _apply_list_builder(
3365            *expressions,
3366            instance=self,
3367            arg="expressions",
3368            append=append,
3369            dialect=dialect,
3370            into=Expression,
3371            copy=copy,
3372            **opts,
3373        )
3374
3375    def lateral(
3376        self,
3377        *expressions: t.Optional[ExpOrStr],
3378        append: bool = True,
3379        dialect: DialectType = None,
3380        copy: bool = True,
3381        **opts,
3382    ) -> Select:
3383        """
3384        Append to or set the LATERAL expressions.
3385
3386        Example:
3387            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3388            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3389
3390        Args:
3391            *expressions: the SQL code strings to parse.
3392                If an `Expression` instance is passed, it will be used as-is.
3393            append: if `True`, add to any existing expressions.
3394                Otherwise, this resets the expressions.
3395            dialect: the dialect used to parse the input expressions.
3396            copy: if `False`, modify this expression instance in-place.
3397            opts: other options to use to parse the input expressions.
3398
3399        Returns:
3400            The modified Select expression.
3401        """
3402        return _apply_list_builder(
3403            *expressions,
3404            instance=self,
3405            arg="laterals",
3406            append=append,
3407            into=Lateral,
3408            prefix="LATERAL VIEW",
3409            dialect=dialect,
3410            copy=copy,
3411            **opts,
3412        )
3413
3414    def join(
3415        self,
3416        expression: ExpOrStr,
3417        on: t.Optional[ExpOrStr] = None,
3418        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3419        append: bool = True,
3420        join_type: t.Optional[str] = None,
3421        join_alias: t.Optional[Identifier | str] = None,
3422        dialect: DialectType = None,
3423        copy: bool = True,
3424        **opts,
3425    ) -> Select:
3426        """
3427        Append to or set the JOIN expressions.
3428
3429        Example:
3430            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3431            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3432
3433            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3434            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3435
3436            Use `join_type` to change the type of join:
3437
3438            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3439            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3440
3441        Args:
3442            expression: the SQL code string to parse.
3443                If an `Expression` instance is passed, it will be used as-is.
3444            on: optionally specify the join "on" criteria as a SQL string.
3445                If an `Expression` instance is passed, it will be used as-is.
3446            using: optionally specify the join "using" criteria as a SQL string.
3447                If an `Expression` instance is passed, it will be used as-is.
3448            append: if `True`, add to any existing expressions.
3449                Otherwise, this resets the expressions.
3450            join_type: if set, alter the parsed join type.
3451            join_alias: an optional alias for the joined source.
3452            dialect: the dialect used to parse the input expressions.
3453            copy: if `False`, modify this expression instance in-place.
3454            opts: other options to use to parse the input expressions.
3455
3456        Returns:
3457            Select: the modified expression.
3458        """
3459        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3460
3461        try:
3462            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3463        except ParseError:
3464            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3465
3466        join = expression if isinstance(expression, Join) else Join(this=expression)
3467
3468        if isinstance(join.this, Select):
3469            join.this.replace(join.this.subquery())
3470
3471        if join_type:
3472            method: t.Optional[Token]
3473            side: t.Optional[Token]
3474            kind: t.Optional[Token]
3475
3476            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3477
3478            if method:
3479                join.set("method", method.text)
3480            if side:
3481                join.set("side", side.text)
3482            if kind:
3483                join.set("kind", kind.text)
3484
3485        if on:
3486            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3487            join.set("on", on)
3488
3489        if using:
3490            join = _apply_list_builder(
3491                *ensure_list(using),
3492                instance=join,
3493                arg="using",
3494                append=append,
3495                copy=copy,
3496                into=Identifier,
3497                **opts,
3498            )
3499
3500        if join_alias:
3501            join.set("this", alias_(join.this, join_alias, table=True))
3502
3503        return _apply_list_builder(
3504            join,
3505            instance=self,
3506            arg="joins",
3507            append=append,
3508            copy=copy,
3509            **opts,
3510        )
3511
3512    def where(
3513        self,
3514        *expressions: t.Optional[ExpOrStr],
3515        append: bool = True,
3516        dialect: DialectType = None,
3517        copy: bool = True,
3518        **opts,
3519    ) -> Select:
3520        """
3521        Append to or set the WHERE expressions.
3522
3523        Example:
3524            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3525            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3526
3527        Args:
3528            *expressions: the SQL code strings to parse.
3529                If an `Expression` instance is passed, it will be used as-is.
3530                Multiple expressions are combined with an AND operator.
3531            append: if `True`, AND the new expressions to any existing expression.
3532                Otherwise, this resets the expression.
3533            dialect: the dialect used to parse the input expressions.
3534            copy: if `False`, modify this expression instance in-place.
3535            opts: other options to use to parse the input expressions.
3536
3537        Returns:
3538            Select: the modified expression.
3539        """
3540        return _apply_conjunction_builder(
3541            *expressions,
3542            instance=self,
3543            arg="where",
3544            append=append,
3545            into=Where,
3546            dialect=dialect,
3547            copy=copy,
3548            **opts,
3549        )
3550
3551    def having(
3552        self,
3553        *expressions: t.Optional[ExpOrStr],
3554        append: bool = True,
3555        dialect: DialectType = None,
3556        copy: bool = True,
3557        **opts,
3558    ) -> Select:
3559        """
3560        Append to or set the HAVING expressions.
3561
3562        Example:
3563            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3564            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3565
3566        Args:
3567            *expressions: the SQL code strings to parse.
3568                If an `Expression` instance is passed, it will be used as-is.
3569                Multiple expressions are combined with an AND operator.
3570            append: if `True`, AND the new expressions to any existing expression.
3571                Otherwise, this resets the expression.
3572            dialect: the dialect used to parse the input expressions.
3573            copy: if `False`, modify this expression instance in-place.
3574            opts: other options to use to parse the input expressions.
3575
3576        Returns:
3577            The modified Select expression.
3578        """
3579        return _apply_conjunction_builder(
3580            *expressions,
3581            instance=self,
3582            arg="having",
3583            append=append,
3584            into=Having,
3585            dialect=dialect,
3586            copy=copy,
3587            **opts,
3588        )
3589
3590    def window(
3591        self,
3592        *expressions: t.Optional[ExpOrStr],
3593        append: bool = True,
3594        dialect: DialectType = None,
3595        copy: bool = True,
3596        **opts,
3597    ) -> Select:
3598        return _apply_list_builder(
3599            *expressions,
3600            instance=self,
3601            arg="windows",
3602            append=append,
3603            into=Window,
3604            dialect=dialect,
3605            copy=copy,
3606            **opts,
3607        )
3608
3609    def qualify(
3610        self,
3611        *expressions: t.Optional[ExpOrStr],
3612        append: bool = True,
3613        dialect: DialectType = None,
3614        copy: bool = True,
3615        **opts,
3616    ) -> Select:
3617        return _apply_conjunction_builder(
3618            *expressions,
3619            instance=self,
3620            arg="qualify",
3621            append=append,
3622            into=Qualify,
3623            dialect=dialect,
3624            copy=copy,
3625            **opts,
3626        )
3627
3628    def distinct(
3629        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3630    ) -> Select:
3631        """
3632        Set the OFFSET expression.
3633
3634        Example:
3635            >>> Select().from_("tbl").select("x").distinct().sql()
3636            'SELECT DISTINCT x FROM tbl'
3637
3638        Args:
3639            ons: the expressions to distinct on
3640            distinct: whether the Select should be distinct
3641            copy: if `False`, modify this expression instance in-place.
3642
3643        Returns:
3644            Select: the modified expression.
3645        """
3646        instance = maybe_copy(self, copy)
3647        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3648        instance.set("distinct", Distinct(on=on) if distinct else None)
3649        return instance
3650
3651    def ctas(
3652        self,
3653        table: ExpOrStr,
3654        properties: t.Optional[t.Dict] = None,
3655        dialect: DialectType = None,
3656        copy: bool = True,
3657        **opts,
3658    ) -> Create:
3659        """
3660        Convert this expression to a CREATE TABLE AS statement.
3661
3662        Example:
3663            >>> Select().select("*").from_("tbl").ctas("x").sql()
3664            'CREATE TABLE x AS SELECT * FROM tbl'
3665
3666        Args:
3667            table: the SQL code string to parse as the table name.
3668                If another `Expression` instance is passed, it will be used as-is.
3669            properties: an optional mapping of table properties
3670            dialect: the dialect used to parse the input table.
3671            copy: if `False`, modify this expression instance in-place.
3672            opts: other options to use to parse the input table.
3673
3674        Returns:
3675            The new Create expression.
3676        """
3677        instance = maybe_copy(self, copy)
3678        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3679
3680        properties_expression = None
3681        if properties:
3682            properties_expression = Properties.from_dict(properties)
3683
3684        return Create(
3685            this=table_expression,
3686            kind="TABLE",
3687            expression=instance,
3688            properties=properties_expression,
3689        )
3690
3691    def lock(self, update: bool = True, copy: bool = True) -> Select:
3692        """
3693        Set the locking read mode for this expression.
3694
3695        Examples:
3696            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3697            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3698
3699            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3700            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3701
3702        Args:
3703            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3704            copy: if `False`, modify this expression instance in-place.
3705
3706        Returns:
3707            The modified expression.
3708        """
3709        inst = maybe_copy(self, copy)
3710        inst.set("locks", [Lock(update=update)])
3711
3712        return inst
3713
3714    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3715        """
3716        Set hints for this expression.
3717
3718        Examples:
3719            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3720            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3721
3722        Args:
3723            hints: The SQL code strings to parse as the hints.
3724                If an `Expression` instance is passed, it will be used as-is.
3725            dialect: The dialect used to parse the hints.
3726            copy: If `False`, modify this expression instance in-place.
3727
3728        Returns:
3729            The modified expression.
3730        """
3731        inst = maybe_copy(self, copy)
3732        inst.set(
3733            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3734        )
3735
3736        return inst
3737
3738    @property
3739    def named_selects(self) -> t.List[str]:
3740        return [e.output_name for e in self.expressions if e.alias_or_name]
3741
3742    @property
3743    def is_star(self) -> bool:
3744        return any(expression.is_star for expression in self.expressions)
3745
3746    @property
3747    def selects(self) -> t.List[Expression]:
3748        return self.expressions
3749
3750
3751UNWRAPPED_QUERIES = (Select, SetOperation)
3752
3753
3754class Subquery(DerivedTable, Query):
3755    arg_types = {
3756        "this": True,
3757        "alias": False,
3758        "with": False,
3759        **QUERY_MODIFIERS,
3760    }
3761
3762    def unnest(self):
3763        """Returns the first non subquery."""
3764        expression = self
3765        while isinstance(expression, Subquery):
3766            expression = expression.this
3767        return expression
3768
3769    def unwrap(self) -> Subquery:
3770        expression = self
3771        while expression.same_parent and expression.is_wrapper:
3772            expression = t.cast(Subquery, expression.parent)
3773        return expression
3774
3775    def select(
3776        self,
3777        *expressions: t.Optional[ExpOrStr],
3778        append: bool = True,
3779        dialect: DialectType = None,
3780        copy: bool = True,
3781        **opts,
3782    ) -> Subquery:
3783        this = maybe_copy(self, copy)
3784        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3785        return this
3786
3787    @property
3788    def is_wrapper(self) -> bool:
3789        """
3790        Whether this Subquery acts as a simple wrapper around another expression.
3791
3792        SELECT * FROM (((SELECT * FROM t)))
3793                      ^
3794                      This corresponds to a "wrapper" Subquery node
3795        """
3796        return all(v is None for k, v in self.args.items() if k != "this")
3797
3798    @property
3799    def is_star(self) -> bool:
3800        return self.this.is_star
3801
3802    @property
3803    def output_name(self) -> str:
3804        return self.alias
3805
3806
3807class TableSample(Expression):
3808    arg_types = {
3809        "this": False,
3810        "expressions": False,
3811        "method": False,
3812        "bucket_numerator": False,
3813        "bucket_denominator": False,
3814        "bucket_field": False,
3815        "percent": False,
3816        "rows": False,
3817        "size": False,
3818        "seed": False,
3819    }
3820
3821
3822class Tag(Expression):
3823    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3824
3825    arg_types = {
3826        "this": False,
3827        "prefix": False,
3828        "postfix": False,
3829    }
3830
3831
3832# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax
3833# https://duckdb.org/docs/sql/statements/pivot
3834class Pivot(Expression):
3835    arg_types = {
3836        "this": False,
3837        "alias": False,
3838        "expressions": False,
3839        "field": False,
3840        "unpivot": False,
3841        "using": False,
3842        "group": False,
3843        "columns": False,
3844        "include_nulls": False,
3845    }
3846
3847    @property
3848    def unpivot(self) -> bool:
3849        return bool(self.args.get("unpivot"))
3850
3851
3852class Window(Condition):
3853    arg_types = {
3854        "this": True,
3855        "partition_by": False,
3856        "order": False,
3857        "spec": False,
3858        "alias": False,
3859        "over": False,
3860        "first": False,
3861    }
3862
3863
3864class WindowSpec(Expression):
3865    arg_types = {
3866        "kind": False,
3867        "start": False,
3868        "start_side": False,
3869        "end": False,
3870        "end_side": False,
3871    }
3872
3873
3874class PreWhere(Expression):
3875    pass
3876
3877
3878class Where(Expression):
3879    pass
3880
3881
3882class Star(Expression):
3883    arg_types = {"except": False, "replace": False, "rename": False}
3884
3885    @property
3886    def name(self) -> str:
3887        return "*"
3888
3889    @property
3890    def output_name(self) -> str:
3891        return self.name
3892
3893
3894class Parameter(Condition):
3895    arg_types = {"this": True, "expression": False}
3896
3897
3898class SessionParameter(Condition):
3899    arg_types = {"this": True, "kind": False}
3900
3901
3902class Placeholder(Condition):
3903    arg_types = {"this": False, "kind": False}
3904
3905    @property
3906    def name(self) -> str:
3907        return self.this or "?"
3908
3909
3910class Null(Condition):
3911    arg_types: t.Dict[str, t.Any] = {}
3912
3913    @property
3914    def name(self) -> str:
3915        return "NULL"
3916
3917    def to_py(self) -> Lit[None]:
3918        return None
3919
3920
3921class Boolean(Condition):
3922    def to_py(self) -> bool:
3923        return self.this
3924
3925
3926class DataTypeParam(Expression):
3927    arg_types = {"this": True, "expression": False}
3928
3929    @property
3930    def name(self) -> str:
3931        return self.this.name
3932
3933
3934class DataType(Expression):
3935    arg_types = {
3936        "this": True,
3937        "expressions": False,
3938        "nested": False,
3939        "values": False,
3940        "prefix": False,
3941        "kind": False,
3942    }
3943
3944    class Type(AutoName):
3945        ARRAY = auto()
3946        AGGREGATEFUNCTION = auto()
3947        SIMPLEAGGREGATEFUNCTION = auto()
3948        BIGDECIMAL = auto()
3949        BIGINT = auto()
3950        BIGSERIAL = auto()
3951        BINARY = auto()
3952        BIT = auto()
3953        BOOLEAN = auto()
3954        BPCHAR = auto()
3955        CHAR = auto()
3956        DATE = auto()
3957        DATE32 = auto()
3958        DATEMULTIRANGE = auto()
3959        DATERANGE = auto()
3960        DATETIME = auto()
3961        DATETIME64 = auto()
3962        DECIMAL = auto()
3963        DOUBLE = auto()
3964        ENUM = auto()
3965        ENUM8 = auto()
3966        ENUM16 = auto()
3967        FIXEDSTRING = auto()
3968        FLOAT = auto()
3969        GEOGRAPHY = auto()
3970        GEOMETRY = auto()
3971        HLLSKETCH = auto()
3972        HSTORE = auto()
3973        IMAGE = auto()
3974        INET = auto()
3975        INT = auto()
3976        INT128 = auto()
3977        INT256 = auto()
3978        INT4MULTIRANGE = auto()
3979        INT4RANGE = auto()
3980        INT8MULTIRANGE = auto()
3981        INT8RANGE = auto()
3982        INTERVAL = auto()
3983        IPADDRESS = auto()
3984        IPPREFIX = auto()
3985        IPV4 = auto()
3986        IPV6 = auto()
3987        JSON = auto()
3988        JSONB = auto()
3989        LIST = auto()
3990        LONGBLOB = auto()
3991        LONGTEXT = auto()
3992        LOWCARDINALITY = auto()
3993        MAP = auto()
3994        MEDIUMBLOB = auto()
3995        MEDIUMINT = auto()
3996        MEDIUMTEXT = auto()
3997        MONEY = auto()
3998        NAME = auto()
3999        NCHAR = auto()
4000        NESTED = auto()
4001        NULL = auto()
4002        NULLABLE = auto()
4003        NUMMULTIRANGE = auto()
4004        NUMRANGE = auto()
4005        NVARCHAR = auto()
4006        OBJECT = auto()
4007        ROWVERSION = auto()
4008        SERIAL = auto()
4009        SET = auto()
4010        SMALLINT = auto()
4011        SMALLMONEY = auto()
4012        SMALLSERIAL = auto()
4013        STRUCT = auto()
4014        SUPER = auto()
4015        TEXT = auto()
4016        TINYBLOB = auto()
4017        TINYTEXT = auto()
4018        TIME = auto()
4019        TIMETZ = auto()
4020        TIMESTAMP = auto()
4021        TIMESTAMPNTZ = auto()
4022        TIMESTAMPLTZ = auto()
4023        TIMESTAMPTZ = auto()
4024        TIMESTAMP_S = auto()
4025        TIMESTAMP_MS = auto()
4026        TIMESTAMP_NS = auto()
4027        TINYINT = auto()
4028        TSMULTIRANGE = auto()
4029        TSRANGE = auto()
4030        TSTZMULTIRANGE = auto()
4031        TSTZRANGE = auto()
4032        UBIGINT = auto()
4033        UINT = auto()
4034        UINT128 = auto()
4035        UINT256 = auto()
4036        UMEDIUMINT = auto()
4037        UDECIMAL = auto()
4038        UNIQUEIDENTIFIER = auto()
4039        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4040        USERDEFINED = "USER-DEFINED"
4041        USMALLINT = auto()
4042        UTINYINT = auto()
4043        UUID = auto()
4044        VARBINARY = auto()
4045        VARCHAR = auto()
4046        VARIANT = auto()
4047        XML = auto()
4048        YEAR = auto()
4049        TDIGEST = auto()
4050
4051    STRUCT_TYPES = {
4052        Type.NESTED,
4053        Type.OBJECT,
4054        Type.STRUCT,
4055    }
4056
4057    NESTED_TYPES = {
4058        *STRUCT_TYPES,
4059        Type.ARRAY,
4060        Type.MAP,
4061    }
4062
4063    TEXT_TYPES = {
4064        Type.CHAR,
4065        Type.NCHAR,
4066        Type.NVARCHAR,
4067        Type.TEXT,
4068        Type.VARCHAR,
4069        Type.NAME,
4070    }
4071
4072    SIGNED_INTEGER_TYPES = {
4073        Type.BIGINT,
4074        Type.INT,
4075        Type.INT128,
4076        Type.INT256,
4077        Type.MEDIUMINT,
4078        Type.SMALLINT,
4079        Type.TINYINT,
4080    }
4081
4082    UNSIGNED_INTEGER_TYPES = {
4083        Type.UBIGINT,
4084        Type.UINT,
4085        Type.UINT128,
4086        Type.UINT256,
4087        Type.UMEDIUMINT,
4088        Type.USMALLINT,
4089        Type.UTINYINT,
4090    }
4091
4092    INTEGER_TYPES = {
4093        *SIGNED_INTEGER_TYPES,
4094        *UNSIGNED_INTEGER_TYPES,
4095        Type.BIT,
4096    }
4097
4098    FLOAT_TYPES = {
4099        Type.DOUBLE,
4100        Type.FLOAT,
4101    }
4102
4103    REAL_TYPES = {
4104        *FLOAT_TYPES,
4105        Type.BIGDECIMAL,
4106        Type.DECIMAL,
4107        Type.MONEY,
4108        Type.SMALLMONEY,
4109        Type.UDECIMAL,
4110    }
4111
4112    NUMERIC_TYPES = {
4113        *INTEGER_TYPES,
4114        *REAL_TYPES,
4115    }
4116
4117    TEMPORAL_TYPES = {
4118        Type.DATE,
4119        Type.DATE32,
4120        Type.DATETIME,
4121        Type.DATETIME64,
4122        Type.TIME,
4123        Type.TIMESTAMP,
4124        Type.TIMESTAMPNTZ,
4125        Type.TIMESTAMPLTZ,
4126        Type.TIMESTAMPTZ,
4127        Type.TIMESTAMP_MS,
4128        Type.TIMESTAMP_NS,
4129        Type.TIMESTAMP_S,
4130        Type.TIMETZ,
4131    }
4132
4133    @classmethod
4134    def build(
4135        cls,
4136        dtype: DATA_TYPE,
4137        dialect: DialectType = None,
4138        udt: bool = False,
4139        copy: bool = True,
4140        **kwargs,
4141    ) -> DataType:
4142        """
4143        Constructs a DataType object.
4144
4145        Args:
4146            dtype: the data type of interest.
4147            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4148            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4149                DataType, thus creating a user-defined type.
4150            copy: whether to copy the data type.
4151            kwargs: additional arguments to pass in the constructor of DataType.
4152
4153        Returns:
4154            The constructed DataType object.
4155        """
4156        from sqlglot import parse_one
4157
4158        if isinstance(dtype, str):
4159            if dtype.upper() == "UNKNOWN":
4160                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4161
4162            try:
4163                data_type_exp = parse_one(
4164                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4165                )
4166            except ParseError:
4167                if udt:
4168                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4169                raise
4170        elif isinstance(dtype, DataType.Type):
4171            data_type_exp = DataType(this=dtype)
4172        elif isinstance(dtype, DataType):
4173            return maybe_copy(dtype, copy)
4174        else:
4175            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4176
4177        return DataType(**{**data_type_exp.args, **kwargs})
4178
4179    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4180        """
4181        Checks whether this DataType matches one of the provided data types. Nested types or precision
4182        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4183
4184        Args:
4185            dtypes: the data types to compare this DataType to.
4186
4187        Returns:
4188            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4189        """
4190        for dtype in dtypes:
4191            other = DataType.build(dtype, copy=False, udt=True)
4192
4193            if (
4194                other.expressions
4195                or self.this == DataType.Type.USERDEFINED
4196                or other.this == DataType.Type.USERDEFINED
4197            ):
4198                matches = self == other
4199            else:
4200                matches = self.this == other.this
4201
4202            if matches:
4203                return True
4204        return False
4205
4206
4207DATA_TYPE = t.Union[str, DataType, DataType.Type]
4208
4209
4210# https://www.postgresql.org/docs/15/datatype-pseudo.html
4211class PseudoType(DataType):
4212    arg_types = {"this": True}
4213
4214
4215# https://www.postgresql.org/docs/15/datatype-oid.html
4216class ObjectIdentifier(DataType):
4217    arg_types = {"this": True}
4218
4219
4220# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
4221class SubqueryPredicate(Predicate):
4222    pass
4223
4224
4225class All(SubqueryPredicate):
4226    pass
4227
4228
4229class Any(SubqueryPredicate):
4230    pass
4231
4232
4233class Exists(SubqueryPredicate):
4234    pass
4235
4236
4237# Commands to interact with the databases or engines. For most of the command
4238# expressions we parse whatever comes after the command's name as a string.
4239class Command(Expression):
4240    arg_types = {"this": True, "expression": False}
4241
4242
4243class Transaction(Expression):
4244    arg_types = {"this": False, "modes": False, "mark": False}
4245
4246
4247class Commit(Expression):
4248    arg_types = {"chain": False, "this": False, "durability": False}
4249
4250
4251class Rollback(Expression):
4252    arg_types = {"savepoint": False, "this": False}
4253
4254
4255class AlterTable(Expression):
4256    arg_types = {
4257        "this": True,
4258        "actions": True,
4259        "exists": False,
4260        "only": False,
4261        "options": False,
4262        "cluster": False,
4263    }
4264
4265
4266class AddConstraint(Expression):
4267    arg_types = {"expressions": True}
4268
4269
4270class DropPartition(Expression):
4271    arg_types = {"expressions": True, "exists": False}
4272
4273
4274# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#replace-partition
4275class ReplacePartition(Expression):
4276    arg_types = {"expression": True, "source": True}
4277
4278
4279# Binary expressions like (ADD a b)
4280class Binary(Condition):
4281    arg_types = {"this": True, "expression": True}
4282
4283    @property
4284    def left(self) -> Expression:
4285        return self.this
4286
4287    @property
4288    def right(self) -> Expression:
4289        return self.expression
4290
4291
4292class Add(Binary):
4293    pass
4294
4295
4296class Connector(Binary):
4297    pass
4298
4299
4300class And(Connector):
4301    pass
4302
4303
4304class Or(Connector):
4305    pass
4306
4307
4308class BitwiseAnd(Binary):
4309    pass
4310
4311
4312class BitwiseLeftShift(Binary):
4313    pass
4314
4315
4316class BitwiseOr(Binary):
4317    pass
4318
4319
4320class BitwiseRightShift(Binary):
4321    pass
4322
4323
4324class BitwiseXor(Binary):
4325    pass
4326
4327
4328class Div(Binary):
4329    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
4330
4331
4332class Overlaps(Binary):
4333    pass
4334
4335
4336class Dot(Binary):
4337    @property
4338    def is_star(self) -> bool:
4339        return self.expression.is_star
4340
4341    @property
4342    def name(self) -> str:
4343        return self.expression.name
4344
4345    @property
4346    def output_name(self) -> str:
4347        return self.name
4348
4349    @classmethod
4350    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4351        """Build a Dot object with a sequence of expressions."""
4352        if len(expressions) < 2:
4353            raise ValueError("Dot requires >= 2 expressions.")
4354
4355        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4356
4357    @property
4358    def parts(self) -> t.List[Expression]:
4359        """Return the parts of a table / column in order catalog, db, table."""
4360        this, *parts = self.flatten()
4361
4362        parts.reverse()
4363
4364        for arg in COLUMN_PARTS:
4365            part = this.args.get(arg)
4366
4367            if isinstance(part, Expression):
4368                parts.append(part)
4369
4370        parts.reverse()
4371        return parts
4372
4373
4374class DPipe(Binary):
4375    arg_types = {"this": True, "expression": True, "safe": False}
4376
4377
4378class EQ(Binary, Predicate):
4379    pass
4380
4381
4382class NullSafeEQ(Binary, Predicate):
4383    pass
4384
4385
4386class NullSafeNEQ(Binary, Predicate):
4387    pass
4388
4389
4390# Represents e.g. := in DuckDB which is mostly used for setting parameters
4391class PropertyEQ(Binary):
4392    pass
4393
4394
4395class Distance(Binary):
4396    pass
4397
4398
4399class Escape(Binary):
4400    pass
4401
4402
4403class Glob(Binary, Predicate):
4404    pass
4405
4406
4407class GT(Binary, Predicate):
4408    pass
4409
4410
4411class GTE(Binary, Predicate):
4412    pass
4413
4414
4415class ILike(Binary, Predicate):
4416    pass
4417
4418
4419class ILikeAny(Binary, Predicate):
4420    pass
4421
4422
4423class IntDiv(Binary):
4424    pass
4425
4426
4427class Is(Binary, Predicate):
4428    pass
4429
4430
4431class Kwarg(Binary):
4432    """Kwarg in special functions like func(kwarg => y)."""
4433
4434
4435class Like(Binary, Predicate):
4436    pass
4437
4438
4439class LikeAny(Binary, Predicate):
4440    pass
4441
4442
4443class LT(Binary, Predicate):
4444    pass
4445
4446
4447class LTE(Binary, Predicate):
4448    pass
4449
4450
4451class Mod(Binary):
4452    pass
4453
4454
4455class Mul(Binary):
4456    pass
4457
4458
4459class NEQ(Binary, Predicate):
4460    pass
4461
4462
4463# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
4464class Operator(Binary):
4465    arg_types = {"this": True, "operator": True, "expression": True}
4466
4467
4468class SimilarTo(Binary, Predicate):
4469    pass
4470
4471
4472class Slice(Binary):
4473    arg_types = {"this": False, "expression": False}
4474
4475
4476class Sub(Binary):
4477    pass
4478
4479
4480# Unary Expressions
4481# (NOT a)
4482class Unary(Condition):
4483    pass
4484
4485
4486class BitwiseNot(Unary):
4487    pass
4488
4489
4490class Not(Unary):
4491    pass
4492
4493
4494class Paren(Unary):
4495    @property
4496    def output_name(self) -> str:
4497        return self.this.name
4498
4499
4500class Neg(Unary):
4501    def to_py(self) -> int | Decimal:
4502        if self.is_number:
4503            return self.this.to_py() * -1
4504        return super().to_py()
4505
4506
4507class Alias(Expression):
4508    arg_types = {"this": True, "alias": False}
4509
4510    @property
4511    def output_name(self) -> str:
4512        return self.alias
4513
4514
4515# BigQuery requires the UNPIVOT column list aliases to be either strings or ints, but
4516# other dialects require identifiers. This enables us to transpile between them easily.
4517class PivotAlias(Alias):
4518    pass
4519
4520
4521class Aliases(Expression):
4522    arg_types = {"this": True, "expressions": True}
4523
4524    @property
4525    def aliases(self):
4526        return self.expressions
4527
4528
4529# https://docs.aws.amazon.com/redshift/latest/dg/query-super.html
4530class AtIndex(Expression):
4531    arg_types = {"this": True, "expression": True}
4532
4533
4534class AtTimeZone(Expression):
4535    arg_types = {"this": True, "zone": True}
4536
4537
4538class FromTimeZone(Expression):
4539    arg_types = {"this": True, "zone": True}
4540
4541
4542class Between(Predicate):
4543    arg_types = {"this": True, "low": True, "high": True}
4544
4545
4546class Bracket(Condition):
4547    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4548    arg_types = {
4549        "this": True,
4550        "expressions": True,
4551        "offset": False,
4552        "safe": False,
4553        "returns_list_for_maps": False,
4554    }
4555
4556    @property
4557    def output_name(self) -> str:
4558        if len(self.expressions) == 1:
4559            return self.expressions[0].output_name
4560
4561        return super().output_name
4562
4563
4564class Distinct(Expression):
4565    arg_types = {"expressions": False, "on": False}
4566
4567
4568class In(Predicate):
4569    arg_types = {
4570        "this": True,
4571        "expressions": False,
4572        "query": False,
4573        "unnest": False,
4574        "field": False,
4575        "is_global": False,
4576    }
4577
4578
4579# https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#for-in
4580class ForIn(Expression):
4581    arg_types = {"this": True, "expression": True}
4582
4583
4584class TimeUnit(Expression):
4585    """Automatically converts unit arg into a var."""
4586
4587    arg_types = {"unit": False}
4588
4589    UNABBREVIATED_UNIT_NAME = {
4590        "D": "DAY",
4591        "H": "HOUR",
4592        "M": "MINUTE",
4593        "MS": "MILLISECOND",
4594        "NS": "NANOSECOND",
4595        "Q": "QUARTER",
4596        "S": "SECOND",
4597        "US": "MICROSECOND",
4598        "W": "WEEK",
4599        "Y": "YEAR",
4600    }
4601
4602    VAR_LIKE = (Column, Literal, Var)
4603
4604    def __init__(self, **args):
4605        unit = args.get("unit")
4606        if isinstance(unit, self.VAR_LIKE):
4607            args["unit"] = Var(
4608                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4609            )
4610        elif isinstance(unit, Week):
4611            unit.set("this", Var(this=unit.this.name.upper()))
4612
4613        super().__init__(**args)
4614
4615    @property
4616    def unit(self) -> t.Optional[Var | IntervalSpan]:
4617        return self.args.get("unit")
4618
4619
4620class IntervalOp(TimeUnit):
4621    arg_types = {"unit": True, "expression": True}
4622
4623    def interval(self):
4624        return Interval(
4625            this=self.expression.copy(),
4626            unit=self.unit.copy(),
4627        )
4628
4629
4630# https://www.oracletutorial.com/oracle-basics/oracle-interval/
4631# https://trino.io/docs/current/language/types.html#interval-day-to-second
4632# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
4633class IntervalSpan(DataType):
4634    arg_types = {"this": True, "expression": True}
4635
4636
4637class Interval(TimeUnit):
4638    arg_types = {"this": False, "unit": False}
4639
4640
4641class IgnoreNulls(Expression):
4642    pass
4643
4644
4645class RespectNulls(Expression):
4646    pass
4647
4648
4649# https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate-function-calls#max_min_clause
4650class HavingMax(Expression):
4651    arg_types = {"this": True, "expression": True, "max": True}
4652
4653
4654# Functions
4655class Func(Condition):
4656    """
4657    The base class for all function expressions.
4658
4659    Attributes:
4660        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4661            treated as a variable length argument and the argument's value will be stored as a list.
4662        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4663            function expression. These values are used to map this node to a name during parsing as
4664            well as to provide the function's name during SQL string generation. By default the SQL
4665            name is set to the expression's class name transformed to snake case.
4666    """
4667
4668    is_var_len_args = False
4669
4670    @classmethod
4671    def from_arg_list(cls, args):
4672        if cls.is_var_len_args:
4673            all_arg_keys = list(cls.arg_types)
4674            # If this function supports variable length argument treat the last argument as such.
4675            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4676            num_non_var = len(non_var_len_arg_keys)
4677
4678            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4679            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4680        else:
4681            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4682
4683        return cls(**args_dict)
4684
4685    @classmethod
4686    def sql_names(cls):
4687        if cls is Func:
4688            raise NotImplementedError(
4689                "SQL name is only supported by concrete function implementations"
4690            )
4691        if "_sql_names" not in cls.__dict__:
4692            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4693        return cls._sql_names
4694
4695    @classmethod
4696    def sql_name(cls):
4697        return cls.sql_names()[0]
4698
4699    @classmethod
4700    def default_parser_mappings(cls):
4701        return {name: cls.from_arg_list for name in cls.sql_names()}
4702
4703
4704class AggFunc(Func):
4705    pass
4706
4707
4708class ParameterizedAgg(AggFunc):
4709    arg_types = {"this": True, "expressions": True, "params": True}
4710
4711
4712class Abs(Func):
4713    pass
4714
4715
4716class ArgMax(AggFunc):
4717    arg_types = {"this": True, "expression": True, "count": False}
4718    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
4719
4720
4721class ArgMin(AggFunc):
4722    arg_types = {"this": True, "expression": True, "count": False}
4723    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
4724
4725
4726class ApproxTopK(AggFunc):
4727    arg_types = {"this": True, "expression": False, "counters": False}
4728
4729
4730class Flatten(Func):
4731    pass
4732
4733
4734# https://spark.apache.org/docs/latest/api/sql/index.html#transform
4735class Transform(Func):
4736    arg_types = {"this": True, "expression": True}
4737
4738
4739class Anonymous(Func):
4740    arg_types = {"this": True, "expressions": False}
4741    is_var_len_args = True
4742
4743    @property
4744    def name(self) -> str:
4745        return self.this if isinstance(self.this, str) else self.this.name
4746
4747
4748class AnonymousAggFunc(AggFunc):
4749    arg_types = {"this": True, "expressions": False}
4750    is_var_len_args = True
4751
4752
4753# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
4754class CombinedAggFunc(AnonymousAggFunc):
4755    arg_types = {"this": True, "expressions": False, "parts": True}
4756
4757
4758class CombinedParameterizedAgg(ParameterizedAgg):
4759    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
4760
4761
4762# https://docs.snowflake.com/en/sql-reference/functions/hll
4763# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
4764class Hll(AggFunc):
4765    arg_types = {"this": True, "expressions": False}
4766    is_var_len_args = True
4767
4768
4769class ApproxDistinct(AggFunc):
4770    arg_types = {"this": True, "accuracy": False}
4771    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
4772
4773
4774class Array(Func):
4775    arg_types = {"expressions": False}
4776    is_var_len_args = True
4777
4778
4779# https://docs.snowflake.com/en/sql-reference/functions/to_array
4780class ToArray(Func):
4781    pass
4782
4783
4784# https://materialize.com/docs/sql/types/list/
4785class List(Func):
4786    arg_types = {"expressions": False}
4787    is_var_len_args = True
4788
4789
4790# https://docs.snowflake.com/en/sql-reference/functions/to_char
4791# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
4792class ToChar(Func):
4793    arg_types = {"this": True, "format": False, "nlsparam": False}
4794
4795
4796# https://docs.snowflake.com/en/sql-reference/functions/to_decimal
4797# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_NUMBER.html
4798class ToNumber(Func):
4799    arg_types = {
4800        "this": True,
4801        "format": False,
4802        "nlsparam": False,
4803        "precision": False,
4804        "scale": False,
4805    }
4806
4807
4808# https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#syntax
4809class Convert(Func):
4810    arg_types = {"this": True, "expression": True, "style": False}
4811
4812
4813class GenerateSeries(Func):
4814    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
4815
4816
4817class ArrayAgg(AggFunc):
4818    pass
4819
4820
4821class ArrayUniqueAgg(AggFunc):
4822    pass
4823
4824
4825class ArrayAll(Func):
4826    arg_types = {"this": True, "expression": True}
4827
4828
4829# Represents Python's `any(f(x) for x in array)`, where `array` is `this` and `f` is `expression`
4830class ArrayAny(Func):
4831    arg_types = {"this": True, "expression": True}
4832
4833
4834class ArrayConcat(Func):
4835    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4836    arg_types = {"this": True, "expressions": False}
4837    is_var_len_args = True
4838
4839
4840class ArrayConstructCompact(Func):
4841    arg_types = {"expressions": True}
4842    is_var_len_args = True
4843
4844
4845class ArrayContains(Binary, Func):
4846    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
4847
4848
4849class ArrayContainsAll(Binary, Func):
4850    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
4851
4852
4853class ArrayFilter(Func):
4854    arg_types = {"this": True, "expression": True}
4855    _sql_names = ["FILTER", "ARRAY_FILTER"]
4856
4857
4858class ArrayToString(Func):
4859    arg_types = {"this": True, "expression": True, "null": False}
4860    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
4861
4862
4863class StringToArray(Func):
4864    arg_types = {"this": True, "expression": True, "null": False}
4865    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
4866
4867
4868class ArrayOverlaps(Binary, Func):
4869    pass
4870
4871
4872class ArraySize(Func):
4873    arg_types = {"this": True, "expression": False}
4874    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
4875
4876
4877class ArraySort(Func):
4878    arg_types = {"this": True, "expression": False}
4879
4880
4881class ArraySum(Func):
4882    arg_types = {"this": True, "expression": False}
4883
4884
4885class ArrayUnionAgg(AggFunc):
4886    pass
4887
4888
4889class Avg(AggFunc):
4890    pass
4891
4892
4893class AnyValue(AggFunc):
4894    pass
4895
4896
4897class Lag(AggFunc):
4898    arg_types = {"this": True, "offset": False, "default": False}
4899
4900
4901class Lead(AggFunc):
4902    arg_types = {"this": True, "offset": False, "default": False}
4903
4904
4905# some dialects have a distinction between first and first_value, usually first is an aggregate func
4906# and first_value is a window func
4907class First(AggFunc):
4908    pass
4909
4910
4911class Last(AggFunc):
4912    pass
4913
4914
4915class FirstValue(AggFunc):
4916    pass
4917
4918
4919class LastValue(AggFunc):
4920    pass
4921
4922
4923class NthValue(AggFunc):
4924    arg_types = {"this": True, "offset": True}
4925
4926
4927class Case(Func):
4928    arg_types = {"this": False, "ifs": True, "default": False}
4929
4930    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4931        instance = maybe_copy(self, copy)
4932        instance.append(
4933            "ifs",
4934            If(
4935                this=maybe_parse(condition, copy=copy, **opts),
4936                true=maybe_parse(then, copy=copy, **opts),
4937            ),
4938        )
4939        return instance
4940
4941    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4942        instance = maybe_copy(self, copy)
4943        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4944        return instance
4945
4946
4947class Cast(Func):
4948    arg_types = {
4949        "this": True,
4950        "to": True,
4951        "format": False,
4952        "safe": False,
4953        "action": False,
4954    }
4955
4956    @property
4957    def name(self) -> str:
4958        return self.this.name
4959
4960    @property
4961    def to(self) -> DataType:
4962        return self.args["to"]
4963
4964    @property
4965    def output_name(self) -> str:
4966        return self.name
4967
4968    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4969        """
4970        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4971        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4972        array<int> != array<float>.
4973
4974        Args:
4975            dtypes: the data types to compare this Cast's DataType to.
4976
4977        Returns:
4978            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4979        """
4980        return self.to.is_type(*dtypes)
4981
4982
4983class TryCast(Cast):
4984    pass
4985
4986
4987class Try(Func):
4988    pass
4989
4990
4991class CastToStrType(Func):
4992    arg_types = {"this": True, "to": True}
4993
4994
4995class Collate(Binary, Func):
4996    pass
4997
4998
4999class Ceil(Func):
5000    arg_types = {"this": True, "decimals": False}
5001    _sql_names = ["CEIL", "CEILING"]
5002
5003
5004class Coalesce(Func):
5005    arg_types = {"this": True, "expressions": False}
5006    is_var_len_args = True
5007    _sql_names = ["COALESCE", "IFNULL", "NVL"]
5008
5009
5010class Chr(Func):
5011    arg_types = {"this": True, "charset": False, "expressions": False}
5012    is_var_len_args = True
5013    _sql_names = ["CHR", "CHAR"]
5014
5015
5016class Concat(Func):
5017    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5018    is_var_len_args = True
5019
5020
5021class ConcatWs(Concat):
5022    _sql_names = ["CONCAT_WS"]
5023
5024
5025# https://docs.oracle.com/cd/B13789_01/server.101/b10759/operators004.htm#i1035022
5026class ConnectByRoot(Func):
5027    pass
5028
5029
5030class Count(AggFunc):
5031    arg_types = {"this": False, "expressions": False}
5032    is_var_len_args = True
5033
5034
5035class CountIf(AggFunc):
5036    _sql_names = ["COUNT_IF", "COUNTIF"]
5037
5038
5039# cube root
5040class Cbrt(Func):
5041    pass
5042
5043
5044class CurrentDate(Func):
5045    arg_types = {"this": False}
5046
5047
5048class CurrentDatetime(Func):
5049    arg_types = {"this": False}
5050
5051
5052class CurrentTime(Func):
5053    arg_types = {"this": False}
5054
5055
5056class CurrentTimestamp(Func):
5057    arg_types = {"this": False, "transaction": False}
5058
5059
5060class CurrentUser(Func):
5061    arg_types = {"this": False}
5062
5063
5064class DateAdd(Func, IntervalOp):
5065    arg_types = {"this": True, "expression": True, "unit": False}
5066
5067
5068class DateSub(Func, IntervalOp):
5069    arg_types = {"this": True, "expression": True, "unit": False}
5070
5071
5072class DateDiff(Func, TimeUnit):
5073    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5074    arg_types = {"this": True, "expression": True, "unit": False}
5075
5076
5077class DateTrunc(Func):
5078    arg_types = {"unit": True, "this": True, "zone": False}
5079
5080    def __init__(self, **args):
5081        unit = args.get("unit")
5082        if isinstance(unit, TimeUnit.VAR_LIKE):
5083            args["unit"] = Literal.string(
5084                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5085            )
5086        elif isinstance(unit, Week):
5087            unit.set("this", Literal.string(unit.this.name.upper()))
5088
5089        super().__init__(**args)
5090
5091    @property
5092    def unit(self) -> Expression:
5093        return self.args["unit"]
5094
5095
5096# https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions#datetime
5097# expression can either be time_expr or time_zone
5098class Datetime(Func):
5099    arg_types = {"this": True, "expression": False}
5100
5101
5102class DatetimeAdd(Func, IntervalOp):
5103    arg_types = {"this": True, "expression": True, "unit": False}
5104
5105
5106class DatetimeSub(Func, IntervalOp):
5107    arg_types = {"this": True, "expression": True, "unit": False}
5108
5109
5110class DatetimeDiff(Func, TimeUnit):
5111    arg_types = {"this": True, "expression": True, "unit": False}
5112
5113
5114class DatetimeTrunc(Func, TimeUnit):
5115    arg_types = {"this": True, "unit": True, "zone": False}
5116
5117
5118class DayOfWeek(Func):
5119    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
5120
5121
5122class DayOfMonth(Func):
5123    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
5124
5125
5126class DayOfYear(Func):
5127    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
5128
5129
5130class ToDays(Func):
5131    pass
5132
5133
5134class WeekOfYear(Func):
5135    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
5136
5137
5138class MonthsBetween(Func):
5139    arg_types = {"this": True, "expression": True, "roundoff": False}
5140
5141
5142class LastDay(Func, TimeUnit):
5143    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5144    arg_types = {"this": True, "unit": False}
5145
5146
5147class Extract(Func):
5148    arg_types = {"this": True, "expression": True}
5149
5150
5151class Timestamp(Func):
5152    arg_types = {"this": False, "zone": False, "with_tz": False}
5153
5154
5155class TimestampAdd(Func, TimeUnit):
5156    arg_types = {"this": True, "expression": True, "unit": False}
5157
5158
5159class TimestampSub(Func, TimeUnit):
5160    arg_types = {"this": True, "expression": True, "unit": False}
5161
5162
5163class TimestampDiff(Func, TimeUnit):
5164    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5165    arg_types = {"this": True, "expression": True, "unit": False}
5166
5167
5168class TimestampTrunc(Func, TimeUnit):
5169    arg_types = {"this": True, "unit": True, "zone": False}
5170
5171
5172class TimeAdd(Func, TimeUnit):
5173    arg_types = {"this": True, "expression": True, "unit": False}
5174
5175
5176class TimeSub(Func, TimeUnit):
5177    arg_types = {"this": True, "expression": True, "unit": False}
5178
5179
5180class TimeDiff(Func, TimeUnit):
5181    arg_types = {"this": True, "expression": True, "unit": False}
5182
5183
5184class TimeTrunc(Func, TimeUnit):
5185    arg_types = {"this": True, "unit": True, "zone": False}
5186
5187
5188class DateFromParts(Func):
5189    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5190    arg_types = {"year": True, "month": True, "day": True}
5191
5192
5193class TimeFromParts(Func):
5194    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5195    arg_types = {
5196        "hour": True,
5197        "min": True,
5198        "sec": True,
5199        "nano": False,
5200        "fractions": False,
5201        "precision": False,
5202    }
5203
5204
5205class DateStrToDate(Func):
5206    pass
5207
5208
5209class DateToDateStr(Func):
5210    pass
5211
5212
5213class DateToDi(Func):
5214    pass
5215
5216
5217# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
5218class Date(Func):
5219    arg_types = {"this": False, "zone": False, "expressions": False}
5220    is_var_len_args = True
5221
5222
5223class Day(Func):
5224    pass
5225
5226
5227class Decode(Func):
5228    arg_types = {"this": True, "charset": True, "replace": False}
5229
5230
5231class DiToDate(Func):
5232    pass
5233
5234
5235class Encode(Func):
5236    arg_types = {"this": True, "charset": True}
5237
5238
5239class Exp(Func):
5240    pass
5241
5242
5243# https://docs.snowflake.com/en/sql-reference/functions/flatten
5244class Explode(Func):
5245    arg_types = {"this": True, "expressions": False}
5246    is_var_len_args = True
5247
5248
5249class ExplodeOuter(Explode):
5250    pass
5251
5252
5253class Posexplode(Explode):
5254    pass
5255
5256
5257class PosexplodeOuter(Posexplode, ExplodeOuter):
5258    pass
5259
5260
5261class Unnest(Func, UDTF):
5262    arg_types = {
5263        "expressions": True,
5264        "alias": False,
5265        "offset": False,
5266    }
5267
5268    @property
5269    def selects(self) -> t.List[Expression]:
5270        columns = super().selects
5271        offset = self.args.get("offset")
5272        if offset:
5273            columns = columns + [to_identifier("offset") if offset is True else offset]
5274        return columns
5275
5276
5277class Floor(Func):
5278    arg_types = {"this": True, "decimals": False}
5279
5280
5281class FromBase64(Func):
5282    pass
5283
5284
5285class ToBase64(Func):
5286    pass
5287
5288
5289class GapFill(Func):
5290    arg_types = {
5291        "this": True,
5292        "ts_column": True,
5293        "bucket_width": True,
5294        "partitioning_columns": False,
5295        "value_columns": False,
5296        "origin": False,
5297        "ignore_nulls": False,
5298    }
5299
5300
5301class GenerateDateArray(Func):
5302    arg_types = {"start": True, "end": True, "interval": False}
5303
5304
5305class Greatest(Func):
5306    arg_types = {"this": True, "expressions": False}
5307    is_var_len_args = True
5308
5309
5310class GroupConcat(AggFunc):
5311    arg_types = {"this": True, "separator": False}
5312
5313
5314class Hex(Func):
5315    pass
5316
5317
5318class LowerHex(Hex):
5319    pass
5320
5321
5322class Xor(Connector, Func):
5323    arg_types = {"this": False, "expression": False, "expressions": False}
5324
5325
5326class If(Func):
5327    arg_types = {"this": True, "true": True, "false": False}
5328    _sql_names = ["IF", "IIF"]
5329
5330
5331class Nullif(Func):
5332    arg_types = {"this": True, "expression": True}
5333
5334
5335class Initcap(Func):
5336    arg_types = {"this": True, "expression": False}
5337
5338
5339class IsNan(Func):
5340    _sql_names = ["IS_NAN", "ISNAN"]
5341
5342
5343class IsInf(Func):
5344    _sql_names = ["IS_INF", "ISINF"]
5345
5346
5347class JSONPath(Expression):
5348    arg_types = {"expressions": True}
5349
5350    @property
5351    def output_name(self) -> str:
5352        last_segment = self.expressions[-1].this
5353        return last_segment if isinstance(last_segment, str) else ""
5354
5355
5356class JSONPathPart(Expression):
5357    arg_types = {}
5358
5359
5360class JSONPathFilter(JSONPathPart):
5361    arg_types = {"this": True}
5362
5363
5364class JSONPathKey(JSONPathPart):
5365    arg_types = {"this": True}
5366
5367
5368class JSONPathRecursive(JSONPathPart):
5369    arg_types = {"this": False}
5370
5371
5372class JSONPathRoot(JSONPathPart):
5373    pass
5374
5375
5376class JSONPathScript(JSONPathPart):
5377    arg_types = {"this": True}
5378
5379
5380class JSONPathSlice(JSONPathPart):
5381    arg_types = {"start": False, "end": False, "step": False}
5382
5383
5384class JSONPathSelector(JSONPathPart):
5385    arg_types = {"this": True}
5386
5387
5388class JSONPathSubscript(JSONPathPart):
5389    arg_types = {"this": True}
5390
5391
5392class JSONPathUnion(JSONPathPart):
5393    arg_types = {"expressions": True}
5394
5395
5396class JSONPathWildcard(JSONPathPart):
5397    pass
5398
5399
5400class FormatJson(Expression):
5401    pass
5402
5403
5404class JSONKeyValue(Expression):
5405    arg_types = {"this": True, "expression": True}
5406
5407
5408class JSONObject(Func):
5409    arg_types = {
5410        "expressions": False,
5411        "null_handling": False,
5412        "unique_keys": False,
5413        "return_type": False,
5414        "encoding": False,
5415    }
5416
5417
5418class JSONObjectAgg(AggFunc):
5419    arg_types = {
5420        "expressions": False,
5421        "null_handling": False,
5422        "unique_keys": False,
5423        "return_type": False,
5424        "encoding": False,
5425    }
5426
5427
5428# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
5429class JSONArray(Func):
5430    arg_types = {
5431        "expressions": True,
5432        "null_handling": False,
5433        "return_type": False,
5434        "strict": False,
5435    }
5436
5437
5438# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
5439class JSONArrayAgg(Func):
5440    arg_types = {
5441        "this": True,
5442        "order": False,
5443        "null_handling": False,
5444        "return_type": False,
5445        "strict": False,
5446    }
5447
5448
5449# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
5450# Note: parsing of JSON column definitions is currently incomplete.
5451class JSONColumnDef(Expression):
5452    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
5453
5454
5455class JSONSchema(Expression):
5456    arg_types = {"expressions": True}
5457
5458
5459# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
5460class JSONTable(Func):
5461    arg_types = {
5462        "this": True,
5463        "schema": True,
5464        "path": False,
5465        "error_handling": False,
5466        "empty_handling": False,
5467    }
5468
5469
5470class OpenJSONColumnDef(Expression):
5471    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
5472
5473
5474class OpenJSON(Func):
5475    arg_types = {"this": True, "path": False, "expressions": False}
5476
5477
5478class JSONBContains(Binary, Func):
5479    _sql_names = ["JSONB_CONTAINS"]
5480
5481
5482class JSONExtract(Binary, Func):
5483    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5484    _sql_names = ["JSON_EXTRACT"]
5485    is_var_len_args = True
5486
5487    @property
5488    def output_name(self) -> str:
5489        return self.expression.output_name if not self.expressions else ""
5490
5491
5492class JSONExtractScalar(Binary, Func):
5493    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5494    _sql_names = ["JSON_EXTRACT_SCALAR"]
5495    is_var_len_args = True
5496
5497    @property
5498    def output_name(self) -> str:
5499        return self.expression.output_name
5500
5501
5502class JSONBExtract(Binary, Func):
5503    _sql_names = ["JSONB_EXTRACT"]
5504
5505
5506class JSONBExtractScalar(Binary, Func):
5507    _sql_names = ["JSONB_EXTRACT_SCALAR"]
5508
5509
5510class JSONFormat(Func):
5511    arg_types = {"this": False, "options": False}
5512    _sql_names = ["JSON_FORMAT"]
5513
5514
5515# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
5516class JSONArrayContains(Binary, Predicate, Func):
5517    _sql_names = ["JSON_ARRAY_CONTAINS"]
5518
5519
5520class ParseJSON(Func):
5521    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5522    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5523    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5524    arg_types = {"this": True, "expression": False, "safe": False}
5525
5526
5527class Least(Func):
5528    arg_types = {"this": True, "expressions": False}
5529    is_var_len_args = True
5530
5531
5532class Left(Func):
5533    arg_types = {"this": True, "expression": True}
5534
5535
5536class Right(Func):
5537    arg_types = {"this": True, "expression": True}
5538
5539
5540class Length(Func):
5541    arg_types = {"this": True, "binary": False}
5542    _sql_names = ["LENGTH", "LEN"]
5543
5544
5545class Levenshtein(Func):
5546    arg_types = {
5547        "this": True,
5548        "expression": False,
5549        "ins_cost": False,
5550        "del_cost": False,
5551        "sub_cost": False,
5552    }
5553
5554
5555class Ln(Func):
5556    pass
5557
5558
5559class Log(Func):
5560    arg_types = {"this": True, "expression": False}
5561
5562
5563class LogicalOr(AggFunc):
5564    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
5565
5566
5567class LogicalAnd(AggFunc):
5568    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
5569
5570
5571class Lower(Func):
5572    _sql_names = ["LOWER", "LCASE"]
5573
5574
5575class Map(Func):
5576    arg_types = {"keys": False, "values": False}
5577
5578    @property
5579    def keys(self) -> t.List[Expression]:
5580        keys = self.args.get("keys")
5581        return keys.expressions if keys else []
5582
5583    @property
5584    def values(self) -> t.List[Expression]:
5585        values = self.args.get("values")
5586        return values.expressions if values else []
5587
5588
5589# Represents the MAP {...} syntax in DuckDB - basically convert a struct to a MAP
5590class ToMap(Func):
5591    pass
5592
5593
5594class MapFromEntries(Func):
5595    pass
5596
5597
5598# https://learn.microsoft.com/en-us/sql/t-sql/language-elements/scope-resolution-operator-transact-sql?view=sql-server-ver16
5599class ScopeResolution(Expression):
5600    arg_types = {"this": False, "expression": True}
5601
5602
5603class StarMap(Func):
5604    pass
5605
5606
5607class VarMap(Func):
5608    arg_types = {"keys": True, "values": True}
5609    is_var_len_args = True
5610
5611    @property
5612    def keys(self) -> t.List[Expression]:
5613        return self.args["keys"].expressions
5614
5615    @property
5616    def values(self) -> t.List[Expression]:
5617        return self.args["values"].expressions
5618
5619
5620# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
5621class MatchAgainst(Func):
5622    arg_types = {"this": True, "expressions": True, "modifier": False}
5623
5624
5625class Max(AggFunc):
5626    arg_types = {"this": True, "expressions": False}
5627    is_var_len_args = True
5628
5629
5630class MD5(Func):
5631    _sql_names = ["MD5"]
5632
5633
5634# Represents the variant of the MD5 function that returns a binary value
5635class MD5Digest(Func):
5636    _sql_names = ["MD5_DIGEST"]
5637
5638
5639class Min(AggFunc):
5640    arg_types = {"this": True, "expressions": False}
5641    is_var_len_args = True
5642
5643
5644class Month(Func):
5645    pass
5646
5647
5648class AddMonths(Func):
5649    arg_types = {"this": True, "expression": True}
5650
5651
5652class Nvl2(Func):
5653    arg_types = {"this": True, "true": True, "false": False}
5654
5655
5656# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
5657class Predict(Func):
5658    arg_types = {"this": True, "expression": True, "params_struct": False}
5659
5660
5661class Pow(Binary, Func):
5662    _sql_names = ["POWER", "POW"]
5663
5664
5665class PercentileCont(AggFunc):
5666    arg_types = {"this": True, "expression": False}
5667
5668
5669class PercentileDisc(AggFunc):
5670    arg_types = {"this": True, "expression": False}
5671
5672
5673class Quantile(AggFunc):
5674    arg_types = {"this": True, "quantile": True}
5675
5676
5677class ApproxQuantile(Quantile):
5678    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
5679
5680
5681class Quarter(Func):
5682    pass
5683
5684
5685class Rand(Func):
5686    _sql_names = ["RAND", "RANDOM"]
5687    arg_types = {"this": False}
5688
5689
5690class Randn(Func):
5691    arg_types = {"this": False}
5692
5693
5694class RangeN(Func):
5695    arg_types = {"this": True, "expressions": True, "each": False}
5696
5697
5698class ReadCSV(Func):
5699    _sql_names = ["READ_CSV"]
5700    is_var_len_args = True
5701    arg_types = {"this": True, "expressions": False}
5702
5703
5704class Reduce(Func):
5705    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
5706
5707
5708class RegexpExtract(Func):
5709    arg_types = {
5710        "this": True,
5711        "expression": True,
5712        "position": False,
5713        "occurrence": False,
5714        "parameters": False,
5715        "group": False,
5716    }
5717
5718
5719class RegexpReplace(Func):
5720    arg_types = {
5721        "this": True,
5722        "expression": True,
5723        "replacement": False,
5724        "position": False,
5725        "occurrence": False,
5726        "modifiers": False,
5727    }
5728
5729
5730class RegexpLike(Binary, Func):
5731    arg_types = {"this": True, "expression": True, "flag": False}
5732
5733
5734class RegexpILike(Binary, Func):
5735    arg_types = {"this": True, "expression": True, "flag": False}
5736
5737
5738# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
5739# limit is the number of times a pattern is applied
5740class RegexpSplit(Func):
5741    arg_types = {"this": True, "expression": True, "limit": False}
5742
5743
5744class Repeat(Func):
5745    arg_types = {"this": True, "times": True}
5746
5747
5748# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
5749# tsql third argument function == trunctaion if not 0
5750class Round(Func):
5751    arg_types = {"this": True, "decimals": False, "truncate": False}
5752
5753
5754class RowNumber(Func):
5755    arg_types: t.Dict[str, t.Any] = {}
5756
5757
5758class SafeDivide(Func):
5759    arg_types = {"this": True, "expression": True}
5760
5761
5762class SHA(Func):
5763    _sql_names = ["SHA", "SHA1"]
5764
5765
5766class SHA2(Func):
5767    _sql_names = ["SHA2"]
5768    arg_types = {"this": True, "length": False}
5769
5770
5771class Sign(Func):
5772    _sql_names = ["SIGN", "SIGNUM"]
5773
5774
5775class SortArray(Func):
5776    arg_types = {"this": True, "asc": False}
5777
5778
5779class Split(Func):
5780    arg_types = {"this": True, "expression": True, "limit": False}
5781
5782
5783# Start may be omitted in the case of postgres
5784# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
5785class Substring(Func):
5786    arg_types = {"this": True, "start": False, "length": False}
5787
5788
5789class StandardHash(Func):
5790    arg_types = {"this": True, "expression": False}
5791
5792
5793class StartsWith(Func):
5794    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5795    arg_types = {"this": True, "expression": True}
5796
5797
5798class StrPosition(Func):
5799    arg_types = {
5800        "this": True,
5801        "substr": True,
5802        "position": False,
5803        "instance": False,
5804    }
5805
5806
5807class StrToDate(Func):
5808    arg_types = {"this": True, "format": False, "safe": False}
5809
5810
5811class StrToTime(Func):
5812    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
5813
5814
5815# Spark allows unix_timestamp()
5816# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
5817class StrToUnix(Func):
5818    arg_types = {"this": False, "format": False}
5819
5820
5821# https://prestodb.io/docs/current/functions/string.html
5822# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
5823class StrToMap(Func):
5824    arg_types = {
5825        "this": True,
5826        "pair_delim": False,
5827        "key_value_delim": False,
5828        "duplicate_resolution_callback": False,
5829    }
5830
5831
5832class NumberToStr(Func):
5833    arg_types = {"this": True, "format": True, "culture": False}
5834
5835
5836class FromBase(Func):
5837    arg_types = {"this": True, "expression": True}
5838
5839
5840class Struct(Func):
5841    arg_types = {"expressions": False}
5842    is_var_len_args = True
5843
5844
5845class StructExtract(Func):
5846    arg_types = {"this": True, "expression": True}
5847
5848
5849# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
5850# https://docs.snowflake.com/en/sql-reference/functions/insert
5851class Stuff(Func):
5852    _sql_names = ["STUFF", "INSERT"]
5853    arg_types = {"this": True, "start": True, "length": True, "expression": True}
5854
5855
5856class Sum(AggFunc):
5857    pass
5858
5859
5860class Sqrt(Func):
5861    pass
5862
5863
5864class Stddev(AggFunc):
5865    pass
5866
5867
5868class StddevPop(AggFunc):
5869    pass
5870
5871
5872class StddevSamp(AggFunc):
5873    pass
5874
5875
5876# https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions#time
5877class Time(Func):
5878    arg_types = {"this": False, "zone": False}
5879
5880
5881class TimeToStr(Func):
5882    arg_types = {"this": True, "format": True, "culture": False, "timezone": False}
5883
5884
5885class TimeToTimeStr(Func):
5886    pass
5887
5888
5889class TimeToUnix(Func):
5890    pass
5891
5892
5893class TimeStrToDate(Func):
5894    pass
5895
5896
5897class TimeStrToTime(Func):
5898    pass
5899
5900
5901class TimeStrToUnix(Func):
5902    pass
5903
5904
5905class Trim(Func):
5906    arg_types = {
5907        "this": True,
5908        "expression": False,
5909        "position": False,
5910        "collation": False,
5911    }
5912
5913
5914class TsOrDsAdd(Func, TimeUnit):
5915    # return_type is used to correctly cast the arguments of this expression when transpiling it
5916    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5917
5918    @property
5919    def return_type(self) -> DataType:
5920        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
5921
5922
5923class TsOrDsDiff(Func, TimeUnit):
5924    arg_types = {"this": True, "expression": True, "unit": False}
5925
5926
5927class TsOrDsToDateStr(Func):
5928    pass
5929
5930
5931class TsOrDsToDate(Func):
5932    arg_types = {"this": True, "format": False, "safe": False}
5933
5934
5935class TsOrDsToTime(Func):
5936    pass
5937
5938
5939class TsOrDsToTimestamp(Func):
5940    pass
5941
5942
5943class TsOrDiToDi(Func):
5944    pass
5945
5946
5947class Unhex(Func):
5948    pass
5949
5950
5951# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
5952class UnixDate(Func):
5953    pass
5954
5955
5956class UnixToStr(Func):
5957    arg_types = {"this": True, "format": False}
5958
5959
5960# https://prestodb.io/docs/current/functions/datetime.html
5961# presto has weird zone/hours/minutes
5962class UnixToTime(Func):
5963    arg_types = {
5964        "this": True,
5965        "scale": False,
5966        "zone": False,
5967        "hours": False,
5968        "minutes": False,
5969        "format": False,
5970    }
5971
5972    SECONDS = Literal.number(0)
5973    DECIS = Literal.number(1)
5974    CENTIS = Literal.number(2)
5975    MILLIS = Literal.number(3)
5976    DECIMILLIS = Literal.number(4)
5977    CENTIMILLIS = Literal.number(5)
5978    MICROS = Literal.number(6)
5979    DECIMICROS = Literal.number(7)
5980    CENTIMICROS = Literal.number(8)
5981    NANOS = Literal.number(9)
5982
5983
5984class UnixToTimeStr(Func):
5985    pass
5986
5987
5988class TimestampFromParts(Func):
5989    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5990    arg_types = {
5991        "year": True,
5992        "month": True,
5993        "day": True,
5994        "hour": True,
5995        "min": True,
5996        "sec": True,
5997        "nano": False,
5998        "zone": False,
5999        "milli": False,
6000    }
6001
6002
6003class Upper(Func):
6004    _sql_names = ["UPPER", "UCASE"]
6005
6006
6007class Corr(Binary, AggFunc):
6008    pass
6009
6010
6011class Variance(AggFunc):
6012    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
6013
6014
6015class VariancePop(AggFunc):
6016    _sql_names = ["VARIANCE_POP", "VAR_POP"]
6017
6018
6019class CovarSamp(Binary, AggFunc):
6020    pass
6021
6022
6023class CovarPop(Binary, AggFunc):
6024    pass
6025
6026
6027class Week(Func):
6028    arg_types = {"this": True, "mode": False}
6029
6030
6031class XMLTable(Func):
6032    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
6033
6034
6035class Year(Func):
6036    pass
6037
6038
6039class Use(Expression):
6040    arg_types = {"this": True, "kind": False}
6041
6042
6043class Merge(Expression):
6044    arg_types = {
6045        "this": True,
6046        "using": True,
6047        "on": True,
6048        "expressions": True,
6049        "with": False,
6050    }
6051
6052
6053class When(Func):
6054    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
6055
6056
6057# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
6058# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
6059class NextValueFor(Func):
6060    arg_types = {"this": True, "order": False}
6061
6062
6063# Refers to a trailing semi-colon. This is only used to preserve trailing comments
6064# select 1; -- my comment
6065class Semicolon(Expression):
6066    arg_types = {}
6067
6068
6069def _norm_arg(arg):
6070    return arg.lower() if type(arg) is str else arg
6071
6072
6073ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
6074FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
6075
6076JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
6077
6078PERCENTILES = (PercentileCont, PercentileDisc)
6079
6080
6081# Helpers
6082@t.overload
6083def maybe_parse(
6084    sql_or_expression: ExpOrStr,
6085    *,
6086    into: t.Type[E],
6087    dialect: DialectType = None,
6088    prefix: t.Optional[str] = None,
6089    copy: bool = False,
6090    **opts,
6091) -> E: ...
6092
6093
6094@t.overload
6095def maybe_parse(
6096    sql_or_expression: str | E,
6097    *,
6098    into: t.Optional[IntoType] = None,
6099    dialect: DialectType = None,
6100    prefix: t.Optional[str] = None,
6101    copy: bool = False,
6102    **opts,
6103) -> E: ...
6104
6105
6106def maybe_parse(
6107    sql_or_expression: ExpOrStr,
6108    *,
6109    into: t.Optional[IntoType] = None,
6110    dialect: DialectType = None,
6111    prefix: t.Optional[str] = None,
6112    copy: bool = False,
6113    **opts,
6114) -> Expression:
6115    """Gracefully handle a possible string or expression.
6116
6117    Example:
6118        >>> maybe_parse("1")
6119        Literal(this=1, is_string=False)
6120        >>> maybe_parse(to_identifier("x"))
6121        Identifier(this=x, quoted=False)
6122
6123    Args:
6124        sql_or_expression: the SQL code string or an expression
6125        into: the SQLGlot Expression to parse into
6126        dialect: the dialect used to parse the input expressions (in the case that an
6127            input expression is a SQL string).
6128        prefix: a string to prefix the sql with before it gets parsed
6129            (automatically includes a space)
6130        copy: whether to copy the expression.
6131        **opts: other options to use to parse the input expressions (again, in the case
6132            that an input expression is a SQL string).
6133
6134    Returns:
6135        Expression: the parsed or given expression.
6136    """
6137    if isinstance(sql_or_expression, Expression):
6138        if copy:
6139            return sql_or_expression.copy()
6140        return sql_or_expression
6141
6142    if sql_or_expression is None:
6143        raise ParseError("SQL cannot be None")
6144
6145    import sqlglot
6146
6147    sql = str(sql_or_expression)
6148    if prefix:
6149        sql = f"{prefix} {sql}"
6150
6151    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
6152
6153
6154@t.overload
6155def maybe_copy(instance: None, copy: bool = True) -> None: ...
6156
6157
6158@t.overload
6159def maybe_copy(instance: E, copy: bool = True) -> E: ...
6160
6161
6162def maybe_copy(instance, copy=True):
6163    return instance.copy() if copy and instance else instance
6164
6165
6166def _to_s(node: t.Any, verbose: bool = False, level: int = 0) -> str:
6167    """Generate a textual representation of an Expression tree"""
6168    indent = "\n" + ("  " * (level + 1))
6169    delim = f",{indent}"
6170
6171    if isinstance(node, Expression):
6172        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
6173
6174        if (node.type or verbose) and not isinstance(node, DataType):
6175            args["_type"] = node.type
6176        if node.comments or verbose:
6177            args["_comments"] = node.comments
6178
6179        if verbose:
6180            args["_id"] = id(node)
6181
6182        # Inline leaves for a more compact representation
6183        if node.is_leaf():
6184            indent = ""
6185            delim = ", "
6186
6187        items = delim.join([f"{k}={_to_s(v, verbose, level + 1)}" for k, v in args.items()])
6188        return f"{node.__class__.__name__}({indent}{items})"
6189
6190    if isinstance(node, list):
6191        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
6192        items = f"{indent}{items}" if items else ""
6193        return f"[{items}]"
6194
6195    # Indent multiline strings to match the current level
6196    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
6197
6198
6199def _is_wrong_expression(expression, into):
6200    return isinstance(expression, Expression) and not isinstance(expression, into)
6201
6202
6203def _apply_builder(
6204    expression,
6205    instance,
6206    arg,
6207    copy=True,
6208    prefix=None,
6209    into=None,
6210    dialect=None,
6211    into_arg="this",
6212    **opts,
6213):
6214    if _is_wrong_expression(expression, into):
6215        expression = into(**{into_arg: expression})
6216    instance = maybe_copy(instance, copy)
6217    expression = maybe_parse(
6218        sql_or_expression=expression,
6219        prefix=prefix,
6220        into=into,
6221        dialect=dialect,
6222        **opts,
6223    )
6224    instance.set(arg, expression)
6225    return instance
6226
6227
6228def _apply_child_list_builder(
6229    *expressions,
6230    instance,
6231    arg,
6232    append=True,
6233    copy=True,
6234    prefix=None,
6235    into=None,
6236    dialect=None,
6237    properties=None,
6238    **opts,
6239):
6240    instance = maybe_copy(instance, copy)
6241    parsed = []
6242    properties = {} if properties is None else properties
6243
6244    for expression in expressions:
6245        if expression is not None:
6246            if _is_wrong_expression(expression, into):
6247                expression = into(expressions=[expression])
6248
6249            expression = maybe_parse(
6250                expression,
6251                into=into,
6252                dialect=dialect,
6253                prefix=prefix,
6254                **opts,
6255            )
6256            for k, v in expression.args.items():
6257                if k == "expressions":
6258                    parsed.extend(v)
6259                else:
6260                    properties[k] = v
6261
6262    existing = instance.args.get(arg)
6263    if append and existing:
6264        parsed = existing.expressions + parsed
6265
6266    child = into(expressions=parsed)
6267    for k, v in properties.items():
6268        child.set(k, v)
6269    instance.set(arg, child)
6270
6271    return instance
6272
6273
6274def _apply_list_builder(
6275    *expressions,
6276    instance,
6277    arg,
6278    append=True,
6279    copy=True,
6280    prefix=None,
6281    into=None,
6282    dialect=None,
6283    **opts,
6284):
6285    inst = maybe_copy(instance, copy)
6286
6287    expressions = [
6288        maybe_parse(
6289            sql_or_expression=expression,
6290            into=into,
6291            prefix=prefix,
6292            dialect=dialect,
6293            **opts,
6294        )
6295        for expression in expressions
6296        if expression is not None
6297    ]
6298
6299    existing_expressions = inst.args.get(arg)
6300    if append and existing_expressions:
6301        expressions = existing_expressions + expressions
6302
6303    inst.set(arg, expressions)
6304    return inst
6305
6306
6307def _apply_conjunction_builder(
6308    *expressions,
6309    instance,
6310    arg,
6311    into=None,
6312    append=True,
6313    copy=True,
6314    dialect=None,
6315    **opts,
6316):
6317    expressions = [exp for exp in expressions if exp is not None and exp != ""]
6318    if not expressions:
6319        return instance
6320
6321    inst = maybe_copy(instance, copy)
6322
6323    existing = inst.args.get(arg)
6324    if append and existing is not None:
6325        expressions = [existing.this if into else existing] + list(expressions)
6326
6327    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
6328
6329    inst.set(arg, into(this=node) if into else node)
6330    return inst
6331
6332
6333def _apply_cte_builder(
6334    instance: E,
6335    alias: ExpOrStr,
6336    as_: ExpOrStr,
6337    recursive: t.Optional[bool] = None,
6338    append: bool = True,
6339    dialect: DialectType = None,
6340    copy: bool = True,
6341    **opts,
6342) -> E:
6343    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
6344    as_expression = maybe_parse(as_, dialect=dialect, **opts)
6345    cte = CTE(this=as_expression, alias=alias_expression)
6346    return _apply_child_list_builder(
6347        cte,
6348        instance=instance,
6349        arg="with",
6350        append=append,
6351        copy=copy,
6352        into=With,
6353        properties={"recursive": recursive or False},
6354    )
6355
6356
6357def _combine(
6358    expressions: t.Sequence[t.Optional[ExpOrStr]],
6359    operator: t.Type[Connector],
6360    dialect: DialectType = None,
6361    copy: bool = True,
6362    **opts,
6363) -> Expression:
6364    conditions = [
6365        condition(expression, dialect=dialect, copy=copy, **opts)
6366        for expression in expressions
6367        if expression is not None
6368    ]
6369
6370    this, *rest = conditions
6371    if rest:
6372        this = _wrap(this, Connector)
6373    for expression in rest:
6374        this = operator(this=this, expression=_wrap(expression, Connector))
6375
6376    return this
6377
6378
6379def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
6380    return Paren(this=expression) if isinstance(expression, kind) else expression
6381
6382
6383def union(
6384    left: ExpOrStr,
6385    right: ExpOrStr,
6386    distinct: bool = True,
6387    dialect: DialectType = None,
6388    copy: bool = True,
6389    **opts,
6390) -> Union:
6391    """
6392    Initializes a syntax tree from one UNION expression.
6393
6394    Example:
6395        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6396        'SELECT * FROM foo UNION SELECT * FROM bla'
6397
6398    Args:
6399        left: the SQL code string corresponding to the left-hand side.
6400            If an `Expression` instance is passed, it will be used as-is.
6401        right: the SQL code string corresponding to the right-hand side.
6402            If an `Expression` instance is passed, it will be used as-is.
6403        distinct: set the DISTINCT flag if and only if this is true.
6404        dialect: the dialect used to parse the input expression.
6405        copy: whether to copy the expression.
6406        opts: other options to use to parse the input expressions.
6407
6408    Returns:
6409        The new Union instance.
6410    """
6411    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6412    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6413
6414    return Union(this=left, expression=right, distinct=distinct)
6415
6416
6417def intersect(
6418    left: ExpOrStr,
6419    right: ExpOrStr,
6420    distinct: bool = True,
6421    dialect: DialectType = None,
6422    copy: bool = True,
6423    **opts,
6424) -> Intersect:
6425    """
6426    Initializes a syntax tree from one INTERSECT expression.
6427
6428    Example:
6429        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6430        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6431
6432    Args:
6433        left: the SQL code string corresponding to the left-hand side.
6434            If an `Expression` instance is passed, it will be used as-is.
6435        right: the SQL code string corresponding to the right-hand side.
6436            If an `Expression` instance is passed, it will be used as-is.
6437        distinct: set the DISTINCT flag if and only if this is true.
6438        dialect: the dialect used to parse the input expression.
6439        copy: whether to copy the expression.
6440        opts: other options to use to parse the input expressions.
6441
6442    Returns:
6443        The new Intersect instance.
6444    """
6445    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6446    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6447
6448    return Intersect(this=left, expression=right, distinct=distinct)
6449
6450
6451def except_(
6452    left: ExpOrStr,
6453    right: ExpOrStr,
6454    distinct: bool = True,
6455    dialect: DialectType = None,
6456    copy: bool = True,
6457    **opts,
6458) -> Except:
6459    """
6460    Initializes a syntax tree from one EXCEPT expression.
6461
6462    Example:
6463        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6464        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6465
6466    Args:
6467        left: the SQL code string corresponding to the left-hand side.
6468            If an `Expression` instance is passed, it will be used as-is.
6469        right: the SQL code string corresponding to the right-hand side.
6470            If an `Expression` instance is passed, it will be used as-is.
6471        distinct: set the DISTINCT flag if and only if this is true.
6472        dialect: the dialect used to parse the input expression.
6473        copy: whether to copy the expression.
6474        opts: other options to use to parse the input expressions.
6475
6476    Returns:
6477        The new Except instance.
6478    """
6479    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6480    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6481
6482    return Except(this=left, expression=right, distinct=distinct)
6483
6484
6485def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6486    """
6487    Initializes a syntax tree from one or multiple SELECT expressions.
6488
6489    Example:
6490        >>> select("col1", "col2").from_("tbl").sql()
6491        'SELECT col1, col2 FROM tbl'
6492
6493    Args:
6494        *expressions: the SQL code string to parse as the expressions of a
6495            SELECT statement. If an Expression instance is passed, this is used as-is.
6496        dialect: the dialect used to parse the input expressions (in the case that an
6497            input expression is a SQL string).
6498        **opts: other options to use to parse the input expressions (again, in the case
6499            that an input expression is a SQL string).
6500
6501    Returns:
6502        Select: the syntax tree for the SELECT statement.
6503    """
6504    return Select().select(*expressions, dialect=dialect, **opts)
6505
6506
6507def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6508    """
6509    Initializes a syntax tree from a FROM expression.
6510
6511    Example:
6512        >>> from_("tbl").select("col1", "col2").sql()
6513        'SELECT col1, col2 FROM tbl'
6514
6515    Args:
6516        *expression: the SQL code string to parse as the FROM expressions of a
6517            SELECT statement. If an Expression instance is passed, this is used as-is.
6518        dialect: the dialect used to parse the input expression (in the case that the
6519            input expression is a SQL string).
6520        **opts: other options to use to parse the input expressions (again, in the case
6521            that the input expression is a SQL string).
6522
6523    Returns:
6524        Select: the syntax tree for the SELECT statement.
6525    """
6526    return Select().from_(expression, dialect=dialect, **opts)
6527
6528
6529def update(
6530    table: str | Table,
6531    properties: dict,
6532    where: t.Optional[ExpOrStr] = None,
6533    from_: t.Optional[ExpOrStr] = None,
6534    dialect: DialectType = None,
6535    **opts,
6536) -> Update:
6537    """
6538    Creates an update statement.
6539
6540    Example:
6541        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6542        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6543
6544    Args:
6545        *properties: dictionary of properties to set which are
6546            auto converted to sql objects eg None -> NULL
6547        where: sql conditional parsed into a WHERE statement
6548        from_: sql statement parsed into a FROM statement
6549        dialect: the dialect used to parse the input expressions.
6550        **opts: other options to use to parse the input expressions.
6551
6552    Returns:
6553        Update: the syntax tree for the UPDATE statement.
6554    """
6555    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6556    update_expr.set(
6557        "expressions",
6558        [
6559            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6560            for k, v in properties.items()
6561        ],
6562    )
6563    if from_:
6564        update_expr.set(
6565            "from",
6566            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6567        )
6568    if isinstance(where, Condition):
6569        where = Where(this=where)
6570    if where:
6571        update_expr.set(
6572            "where",
6573            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6574        )
6575    return update_expr
6576
6577
6578def delete(
6579    table: ExpOrStr,
6580    where: t.Optional[ExpOrStr] = None,
6581    returning: t.Optional[ExpOrStr] = None,
6582    dialect: DialectType = None,
6583    **opts,
6584) -> Delete:
6585    """
6586    Builds a delete statement.
6587
6588    Example:
6589        >>> delete("my_table", where="id > 1").sql()
6590        'DELETE FROM my_table WHERE id > 1'
6591
6592    Args:
6593        where: sql conditional parsed into a WHERE statement
6594        returning: sql conditional parsed into a RETURNING statement
6595        dialect: the dialect used to parse the input expressions.
6596        **opts: other options to use to parse the input expressions.
6597
6598    Returns:
6599        Delete: the syntax tree for the DELETE statement.
6600    """
6601    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6602    if where:
6603        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6604    if returning:
6605        delete_expr = t.cast(
6606            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6607        )
6608    return delete_expr
6609
6610
6611def insert(
6612    expression: ExpOrStr,
6613    into: ExpOrStr,
6614    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6615    overwrite: t.Optional[bool] = None,
6616    returning: t.Optional[ExpOrStr] = None,
6617    dialect: DialectType = None,
6618    copy: bool = True,
6619    **opts,
6620) -> Insert:
6621    """
6622    Builds an INSERT statement.
6623
6624    Example:
6625        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6626        'INSERT INTO tbl VALUES (1, 2, 3)'
6627
6628    Args:
6629        expression: the sql string or expression of the INSERT statement
6630        into: the tbl to insert data to.
6631        columns: optionally the table's column names.
6632        overwrite: whether to INSERT OVERWRITE or not.
6633        returning: sql conditional parsed into a RETURNING statement
6634        dialect: the dialect used to parse the input expressions.
6635        copy: whether to copy the expression.
6636        **opts: other options to use to parse the input expressions.
6637
6638    Returns:
6639        Insert: the syntax tree for the INSERT statement.
6640    """
6641    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6642    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6643
6644    if columns:
6645        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6646
6647    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6648
6649    if returning:
6650        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6651
6652    return insert
6653
6654
6655def condition(
6656    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6657) -> Condition:
6658    """
6659    Initialize a logical condition expression.
6660
6661    Example:
6662        >>> condition("x=1").sql()
6663        'x = 1'
6664
6665        This is helpful for composing larger logical syntax trees:
6666        >>> where = condition("x=1")
6667        >>> where = where.and_("y=1")
6668        >>> Select().from_("tbl").select("*").where(where).sql()
6669        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6670
6671    Args:
6672        *expression: the SQL code string to parse.
6673            If an Expression instance is passed, this is used as-is.
6674        dialect: the dialect used to parse the input expression (in the case that the
6675            input expression is a SQL string).
6676        copy: Whether to copy `expression` (only applies to expressions).
6677        **opts: other options to use to parse the input expressions (again, in the case
6678            that the input expression is a SQL string).
6679
6680    Returns:
6681        The new Condition instance
6682    """
6683    return maybe_parse(
6684        expression,
6685        into=Condition,
6686        dialect=dialect,
6687        copy=copy,
6688        **opts,
6689    )
6690
6691
6692def and_(
6693    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6694) -> Condition:
6695    """
6696    Combine multiple conditions with an AND logical operator.
6697
6698    Example:
6699        >>> and_("x=1", and_("y=1", "z=1")).sql()
6700        'x = 1 AND (y = 1 AND z = 1)'
6701
6702    Args:
6703        *expressions: the SQL code strings to parse.
6704            If an Expression instance is passed, this is used as-is.
6705        dialect: the dialect used to parse the input expression.
6706        copy: whether to copy `expressions` (only applies to Expressions).
6707        **opts: other options to use to parse the input expressions.
6708
6709    Returns:
6710        The new condition
6711    """
6712    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
6713
6714
6715def or_(
6716    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6717) -> Condition:
6718    """
6719    Combine multiple conditions with an OR logical operator.
6720
6721    Example:
6722        >>> or_("x=1", or_("y=1", "z=1")).sql()
6723        'x = 1 OR (y = 1 OR z = 1)'
6724
6725    Args:
6726        *expressions: the SQL code strings to parse.
6727            If an Expression instance is passed, this is used as-is.
6728        dialect: the dialect used to parse the input expression.
6729        copy: whether to copy `expressions` (only applies to Expressions).
6730        **opts: other options to use to parse the input expressions.
6731
6732    Returns:
6733        The new condition
6734    """
6735    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
6736
6737
6738def xor(
6739    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6740) -> Condition:
6741    """
6742    Combine multiple conditions with an XOR logical operator.
6743
6744    Example:
6745        >>> xor("x=1", xor("y=1", "z=1")).sql()
6746        'x = 1 XOR (y = 1 XOR z = 1)'
6747
6748    Args:
6749        *expressions: the SQL code strings to parse.
6750            If an Expression instance is passed, this is used as-is.
6751        dialect: the dialect used to parse the input expression.
6752        copy: whether to copy `expressions` (only applies to Expressions).
6753        **opts: other options to use to parse the input expressions.
6754
6755    Returns:
6756        The new condition
6757    """
6758    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, **opts))
6759
6760
6761def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6762    """
6763    Wrap a condition with a NOT operator.
6764
6765    Example:
6766        >>> not_("this_suit='black'").sql()
6767        "NOT this_suit = 'black'"
6768
6769    Args:
6770        expression: the SQL code string to parse.
6771            If an Expression instance is passed, this is used as-is.
6772        dialect: the dialect used to parse the input expression.
6773        copy: whether to copy the expression or not.
6774        **opts: other options to use to parse the input expressions.
6775
6776    Returns:
6777        The new condition.
6778    """
6779    this = condition(
6780        expression,
6781        dialect=dialect,
6782        copy=copy,
6783        **opts,
6784    )
6785    return Not(this=_wrap(this, Connector))
6786
6787
6788def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6789    """
6790    Wrap an expression in parentheses.
6791
6792    Example:
6793        >>> paren("5 + 3").sql()
6794        '(5 + 3)'
6795
6796    Args:
6797        expression: the SQL code string to parse.
6798            If an Expression instance is passed, this is used as-is.
6799        copy: whether to copy the expression or not.
6800
6801    Returns:
6802        The wrapped expression.
6803    """
6804    return Paren(this=maybe_parse(expression, copy=copy))
6805
6806
6807SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
6808
6809
6810@t.overload
6811def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
6812
6813
6814@t.overload
6815def to_identifier(
6816    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
6817) -> Identifier: ...
6818
6819
6820def to_identifier(name, quoted=None, copy=True):
6821    """Builds an identifier.
6822
6823    Args:
6824        name: The name to turn into an identifier.
6825        quoted: Whether to force quote the identifier.
6826        copy: Whether to copy name if it's an Identifier.
6827
6828    Returns:
6829        The identifier ast node.
6830    """
6831
6832    if name is None:
6833        return None
6834
6835    if isinstance(name, Identifier):
6836        identifier = maybe_copy(name, copy)
6837    elif isinstance(name, str):
6838        identifier = Identifier(
6839            this=name,
6840            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6841        )
6842    else:
6843        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6844    return identifier
6845
6846
6847def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6848    """
6849    Parses a given string into an identifier.
6850
6851    Args:
6852        name: The name to parse into an identifier.
6853        dialect: The dialect to parse against.
6854
6855    Returns:
6856        The identifier ast node.
6857    """
6858    try:
6859        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6860    except ParseError:
6861        expression = to_identifier(name)
6862
6863    return expression
6864
6865
6866INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
6867
6868
6869def to_interval(interval: str | Literal) -> Interval:
6870    """Builds an interval expression from a string like '1 day' or '5 months'."""
6871    if isinstance(interval, Literal):
6872        if not interval.is_string:
6873            raise ValueError("Invalid interval string.")
6874
6875        interval = interval.this
6876
6877    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6878
6879    if not interval_parts:
6880        raise ValueError("Invalid interval string.")
6881
6882    return Interval(
6883        this=Literal.string(interval_parts.group(1)),
6884        unit=Var(this=interval_parts.group(2).upper()),
6885    )
6886
6887
6888def to_table(
6889    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6890) -> Table:
6891    """
6892    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6893    If a table is passed in then that table is returned.
6894
6895    Args:
6896        sql_path: a `[catalog].[schema].[table]` string.
6897        dialect: the source dialect according to which the table name will be parsed.
6898        copy: Whether to copy a table if it is passed in.
6899        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6900
6901    Returns:
6902        A table expression.
6903    """
6904    if isinstance(sql_path, Table):
6905        return maybe_copy(sql_path, copy=copy)
6906
6907    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6908
6909    for k, v in kwargs.items():
6910        table.set(k, v)
6911
6912    return table
6913
6914
6915def to_column(
6916    sql_path: str | Column,
6917    quoted: t.Optional[bool] = None,
6918    dialect: DialectType = None,
6919    copy: bool = True,
6920    **kwargs,
6921) -> Column:
6922    """
6923    Create a column from a `[table].[column]` sql path. Table is optional.
6924    If a column is passed in then that column is returned.
6925
6926    Args:
6927        sql_path: a `[table].[column]` string.
6928        quoted: Whether or not to force quote identifiers.
6929        dialect: the source dialect according to which the column name will be parsed.
6930        copy: Whether to copy a column if it is passed in.
6931        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6932
6933    Returns:
6934        A column expression.
6935    """
6936    if isinstance(sql_path, Column):
6937        return maybe_copy(sql_path, copy=copy)
6938
6939    try:
6940        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6941    except ParseError:
6942        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6943
6944    for k, v in kwargs.items():
6945        col.set(k, v)
6946
6947    if quoted:
6948        for i in col.find_all(Identifier):
6949            i.set("quoted", True)
6950
6951    return col
6952
6953
6954def alias_(
6955    expression: ExpOrStr,
6956    alias: t.Optional[str | Identifier],
6957    table: bool | t.Sequence[str | Identifier] = False,
6958    quoted: t.Optional[bool] = None,
6959    dialect: DialectType = None,
6960    copy: bool = True,
6961    **opts,
6962):
6963    """Create an Alias expression.
6964
6965    Example:
6966        >>> alias_('foo', 'bar').sql()
6967        'foo AS bar'
6968
6969        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6970        '(SELECT 1, 2) AS bar(a, b)'
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. If the name has
6976            special characters it is quoted.
6977        table: Whether to create a table alias, can also be a list of columns.
6978        quoted: whether to quote the alias
6979        dialect: the dialect used to parse the input expression.
6980        copy: Whether to copy the expression.
6981        **opts: other options to use to parse the input expressions.
6982
6983    Returns:
6984        Alias: the aliased expression
6985    """
6986    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6987    alias = to_identifier(alias, quoted=quoted)
6988
6989    if table:
6990        table_alias = TableAlias(this=alias)
6991        exp.set("alias", table_alias)
6992
6993        if not isinstance(table, bool):
6994            for column in table:
6995                table_alias.append("columns", to_identifier(column, quoted=quoted))
6996
6997        return exp
6998
6999    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7000    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7001    # for the complete Window expression.
7002    #
7003    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7004
7005    if "alias" in exp.arg_types and not isinstance(exp, Window):
7006        exp.set("alias", alias)
7007        return exp
7008    return Alias(this=exp, alias=alias)
7009
7010
7011def subquery(
7012    expression: ExpOrStr,
7013    alias: t.Optional[Identifier | str] = None,
7014    dialect: DialectType = None,
7015    **opts,
7016) -> Select:
7017    """
7018    Build a subquery expression that's selected from.
7019
7020    Example:
7021        >>> subquery('select x from tbl', 'bar').select('x').sql()
7022        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7023
7024    Args:
7025        expression: the SQL code strings to parse.
7026            If an Expression instance is passed, this is used as-is.
7027        alias: the alias name to use.
7028        dialect: the dialect used to parse the input expression.
7029        **opts: other options to use to parse the input expressions.
7030
7031    Returns:
7032        A new Select instance with the subquery expression included.
7033    """
7034
7035    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7036    return Select().from_(expression, dialect=dialect, **opts)
7037
7038
7039@t.overload
7040def column(
7041    col: str | Identifier,
7042    table: t.Optional[str | Identifier] = None,
7043    db: t.Optional[str | Identifier] = None,
7044    catalog: t.Optional[str | Identifier] = None,
7045    *,
7046    fields: t.Collection[t.Union[str, Identifier]],
7047    quoted: t.Optional[bool] = None,
7048    copy: bool = True,
7049) -> Dot:
7050    pass
7051
7052
7053@t.overload
7054def column(
7055    col: str | Identifier,
7056    table: t.Optional[str | Identifier] = None,
7057    db: t.Optional[str | Identifier] = None,
7058    catalog: t.Optional[str | Identifier] = None,
7059    *,
7060    fields: Lit[None] = None,
7061    quoted: t.Optional[bool] = None,
7062    copy: bool = True,
7063) -> Column:
7064    pass
7065
7066
7067def column(
7068    col,
7069    table=None,
7070    db=None,
7071    catalog=None,
7072    *,
7073    fields=None,
7074    quoted=None,
7075    copy=True,
7076):
7077    """
7078    Build a Column.
7079
7080    Args:
7081        col: Column name.
7082        table: Table name.
7083        db: Database name.
7084        catalog: Catalog name.
7085        fields: Additional fields using dots.
7086        quoted: Whether to force quotes on the column's identifiers.
7087        copy: Whether to copy identifiers if passed in.
7088
7089    Returns:
7090        The new Column instance.
7091    """
7092    this = Column(
7093        this=to_identifier(col, quoted=quoted, copy=copy),
7094        table=to_identifier(table, quoted=quoted, copy=copy),
7095        db=to_identifier(db, quoted=quoted, copy=copy),
7096        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7097    )
7098
7099    if fields:
7100        this = Dot.build(
7101            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7102        )
7103    return this
7104
7105
7106def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7107    """Cast an expression to a data type.
7108
7109    Example:
7110        >>> cast('x + 1', 'int').sql()
7111        'CAST(x + 1 AS INT)'
7112
7113    Args:
7114        expression: The expression to cast.
7115        to: The datatype to cast to.
7116        copy: Whether to copy the supplied expressions.
7117
7118    Returns:
7119        The new Cast instance.
7120    """
7121    expr = maybe_parse(expression, copy=copy, **opts)
7122    data_type = DataType.build(to, copy=copy, **opts)
7123
7124    if expr.is_type(data_type):
7125        return expr
7126
7127    expr = Cast(this=expr, to=data_type)
7128    expr.type = data_type
7129
7130    return expr
7131
7132
7133def table_(
7134    table: Identifier | str,
7135    db: t.Optional[Identifier | str] = None,
7136    catalog: t.Optional[Identifier | str] = None,
7137    quoted: t.Optional[bool] = None,
7138    alias: t.Optional[Identifier | str] = None,
7139) -> Table:
7140    """Build a Table.
7141
7142    Args:
7143        table: Table name.
7144        db: Database name.
7145        catalog: Catalog name.
7146        quote: Whether to force quotes on the table's identifiers.
7147        alias: Table's alias.
7148
7149    Returns:
7150        The new Table instance.
7151    """
7152    return Table(
7153        this=to_identifier(table, quoted=quoted) if table else None,
7154        db=to_identifier(db, quoted=quoted) if db else None,
7155        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7156        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7157    )
7158
7159
7160def values(
7161    values: t.Iterable[t.Tuple[t.Any, ...]],
7162    alias: t.Optional[str] = None,
7163    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7164) -> Values:
7165    """Build VALUES statement.
7166
7167    Example:
7168        >>> values([(1, '2')]).sql()
7169        "VALUES (1, '2')"
7170
7171    Args:
7172        values: values statements that will be converted to SQL
7173        alias: optional alias
7174        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7175         If either are provided then an alias is also required.
7176
7177    Returns:
7178        Values: the Values expression object
7179    """
7180    if columns and not alias:
7181        raise ValueError("Alias is required when providing columns")
7182
7183    return Values(
7184        expressions=[convert(tup) for tup in values],
7185        alias=(
7186            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7187            if columns
7188            else (TableAlias(this=to_identifier(alias)) if alias else None)
7189        ),
7190    )
7191
7192
7193def var(name: t.Optional[ExpOrStr]) -> Var:
7194    """Build a SQL variable.
7195
7196    Example:
7197        >>> repr(var('x'))
7198        'Var(this=x)'
7199
7200        >>> repr(var(column('x', table='y')))
7201        'Var(this=x)'
7202
7203    Args:
7204        name: The name of the var or an expression who's name will become the var.
7205
7206    Returns:
7207        The new variable node.
7208    """
7209    if not name:
7210        raise ValueError("Cannot convert empty name into var.")
7211
7212    if isinstance(name, Expression):
7213        name = name.name
7214    return Var(this=name)
7215
7216
7217def rename_table(
7218    old_name: str | Table,
7219    new_name: str | Table,
7220    dialect: DialectType = None,
7221) -> AlterTable:
7222    """Build ALTER TABLE... RENAME... expression
7223
7224    Args:
7225        old_name: The old name of the table
7226        new_name: The new name of the table
7227        dialect: The dialect to parse the table.
7228
7229    Returns:
7230        Alter table expression
7231    """
7232    old_table = to_table(old_name, dialect=dialect)
7233    new_table = to_table(new_name, dialect=dialect)
7234    return AlterTable(
7235        this=old_table,
7236        actions=[
7237            RenameTable(this=new_table),
7238        ],
7239    )
7240
7241
7242def rename_column(
7243    table_name: str | Table,
7244    old_column_name: str | Column,
7245    new_column_name: str | Column,
7246    exists: t.Optional[bool] = None,
7247    dialect: DialectType = None,
7248) -> AlterTable:
7249    """Build ALTER TABLE... RENAME COLUMN... expression
7250
7251    Args:
7252        table_name: Name of the table
7253        old_column: The old name of the column
7254        new_column: The new name of the column
7255        exists: Whether to add the `IF EXISTS` clause
7256        dialect: The dialect to parse the table/column.
7257
7258    Returns:
7259        Alter table expression
7260    """
7261    table = to_table(table_name, dialect=dialect)
7262    old_column = to_column(old_column_name, dialect=dialect)
7263    new_column = to_column(new_column_name, dialect=dialect)
7264    return AlterTable(
7265        this=table,
7266        actions=[
7267            RenameColumn(this=old_column, to=new_column, exists=exists),
7268        ],
7269    )
7270
7271
7272def convert(value: t.Any, copy: bool = False) -> Expression:
7273    """Convert a python value into an expression object.
7274
7275    Raises an error if a conversion is not possible.
7276
7277    Args:
7278        value: A python object.
7279        copy: Whether to copy `value` (only applies to Expressions and collections).
7280
7281    Returns:
7282        The equivalent expression object.
7283    """
7284    if isinstance(value, Expression):
7285        return maybe_copy(value, copy)
7286    if isinstance(value, str):
7287        return Literal.string(value)
7288    if isinstance(value, bool):
7289        return Boolean(this=value)
7290    if value is None or (isinstance(value, float) and math.isnan(value)):
7291        return null()
7292    if isinstance(value, numbers.Number):
7293        return Literal.number(value)
7294    if isinstance(value, bytes):
7295        return HexString(this=value.hex())
7296    if isinstance(value, datetime.datetime):
7297        datetime_literal = Literal.string(
7298            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7299                sep=" "
7300            )
7301        )
7302        return TimeStrToTime(this=datetime_literal)
7303    if isinstance(value, datetime.date):
7304        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7305        return DateStrToDate(this=date_literal)
7306    if isinstance(value, tuple):
7307        if hasattr(value, "_fields"):
7308            return Struct(
7309                expressions=[
7310                    PropertyEQ(
7311                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7312                    )
7313                    for k in value._fields
7314                ]
7315            )
7316        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7317    if isinstance(value, list):
7318        return Array(expressions=[convert(v, copy=copy) for v in value])
7319    if isinstance(value, dict):
7320        return Map(
7321            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7322            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7323        )
7324    if hasattr(value, "__dict__"):
7325        return Struct(
7326            expressions=[
7327                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7328                for k, v in value.__dict__.items()
7329            ]
7330        )
7331    raise ValueError(f"Cannot convert {value}")
7332
7333
7334def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7335    """
7336    Replace children of an expression with the result of a lambda fun(child) -> exp.
7337    """
7338    for k, v in tuple(expression.args.items()):
7339        is_list_arg = type(v) is list
7340
7341        child_nodes = v if is_list_arg else [v]
7342        new_child_nodes = []
7343
7344        for cn in child_nodes:
7345            if isinstance(cn, Expression):
7346                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7347                    new_child_nodes.append(child_node)
7348            else:
7349                new_child_nodes.append(cn)
7350
7351        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))
7352
7353
7354def replace_tree(
7355    expression: Expression,
7356    fun: t.Callable,
7357    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7358) -> Expression:
7359    """
7360    Replace an entire tree with the result of function calls on each node.
7361
7362    This will be traversed in reverse dfs, so leaves first.
7363    If new nodes are created as a result of function calls, they will also be traversed.
7364    """
7365    stack = list(expression.dfs(prune=prune))
7366
7367    while stack:
7368        node = stack.pop()
7369        new_node = fun(node)
7370
7371        if new_node is not node:
7372            node.replace(new_node)
7373
7374            if isinstance(new_node, Expression):
7375                stack.append(new_node)
7376
7377    return new_node
7378
7379
7380def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7381    """
7382    Return all table names referenced through columns in an expression.
7383
7384    Example:
7385        >>> import sqlglot
7386        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7387        ['a', 'c']
7388
7389    Args:
7390        expression: expression to find table names.
7391        exclude: a table name to exclude
7392
7393    Returns:
7394        A list of unique names.
7395    """
7396    return {
7397        table
7398        for table in (column.table for column in expression.find_all(Column))
7399        if table and table != exclude
7400    }
7401
7402
7403def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7404    """Get the full name of a table as a string.
7405
7406    Args:
7407        table: Table expression node or string.
7408        dialect: The dialect to generate the table name for.
7409        identify: Determines when an identifier should be quoted. Possible values are:
7410            False (default): Never quote, except in cases where it's mandatory by the dialect.
7411            True: Always quote.
7412
7413    Examples:
7414        >>> from sqlglot import exp, parse_one
7415        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7416        'a.b.c'
7417
7418    Returns:
7419        The table name.
7420    """
7421
7422    table = maybe_parse(table, into=Table, dialect=dialect)
7423
7424    if not table:
7425        raise ValueError(f"Cannot parse {table}")
7426
7427    return ".".join(
7428        (
7429            part.sql(dialect=dialect, identify=True, copy=False)
7430            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7431            else part.name
7432        )
7433        for part in table.parts
7434    )
7435
7436
7437def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7438    """Returns a case normalized table name without quotes.
7439
7440    Args:
7441        table: the table to normalize
7442        dialect: the dialect to use for normalization rules
7443        copy: whether to copy the expression.
7444
7445    Examples:
7446        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7447        'A-B.c'
7448    """
7449    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7450
7451    return ".".join(
7452        p.name
7453        for p in normalize_identifiers(
7454            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7455        ).parts
7456    )
7457
7458
7459def replace_tables(
7460    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7461) -> E:
7462    """Replace all tables in expression according to the mapping.
7463
7464    Args:
7465        expression: expression node to be transformed and replaced.
7466        mapping: mapping of table names.
7467        dialect: the dialect of the mapping table
7468        copy: whether to copy the expression.
7469
7470    Examples:
7471        >>> from sqlglot import exp, parse_one
7472        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7473        'SELECT * FROM c /* a.b */'
7474
7475    Returns:
7476        The mapped expression.
7477    """
7478
7479    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7480
7481    def _replace_tables(node: Expression) -> Expression:
7482        if isinstance(node, Table):
7483            original = normalize_table_name(node, dialect=dialect)
7484            new_name = mapping.get(original)
7485
7486            if new_name:
7487                table = to_table(
7488                    new_name,
7489                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7490                    dialect=dialect,
7491                )
7492                table.add_comments([original])
7493                return table
7494        return node
7495
7496    return expression.transform(_replace_tables, copy=copy)  # type: ignore
7497
7498
7499def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7500    """Replace placeholders in an expression.
7501
7502    Args:
7503        expression: expression node to be transformed and replaced.
7504        args: positional names that will substitute unnamed placeholders in the given order.
7505        kwargs: keyword arguments that will substitute named placeholders.
7506
7507    Examples:
7508        >>> from sqlglot import exp, parse_one
7509        >>> replace_placeholders(
7510        ...     parse_one("select * from :tbl where ? = ?"),
7511        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7512        ... ).sql()
7513        "SELECT * FROM foo WHERE str_col = 'b'"
7514
7515    Returns:
7516        The mapped expression.
7517    """
7518
7519    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7520        if isinstance(node, Placeholder):
7521            if node.this:
7522                new_name = kwargs.get(node.this)
7523                if new_name is not None:
7524                    return convert(new_name)
7525            else:
7526                try:
7527                    return convert(next(args))
7528                except StopIteration:
7529                    pass
7530        return node
7531
7532    return expression.transform(_replace_placeholders, iter(args), **kwargs)
7533
7534
7535def expand(
7536    expression: Expression,
7537    sources: t.Dict[str, Query],
7538    dialect: DialectType = None,
7539    copy: bool = True,
7540) -> Expression:
7541    """Transforms an expression by expanding all referenced sources into subqueries.
7542
7543    Examples:
7544        >>> from sqlglot import parse_one
7545        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7546        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7547
7548        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7549        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7550
7551    Args:
7552        expression: The expression to expand.
7553        sources: A dictionary of name to Queries.
7554        dialect: The dialect of the sources dict.
7555        copy: Whether to copy the expression during transformation. Defaults to True.
7556
7557    Returns:
7558        The transformed expression.
7559    """
7560    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7561
7562    def _expand(node: Expression):
7563        if isinstance(node, Table):
7564            name = normalize_table_name(node, dialect=dialect)
7565            source = sources.get(name)
7566            if source:
7567                subquery = source.subquery(node.alias or name)
7568                subquery.comments = [f"source: {name}"]
7569                return subquery.transform(_expand, copy=False)
7570        return node
7571
7572    return expression.transform(_expand, copy=copy)
7573
7574
7575def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7576    """
7577    Returns a Func expression.
7578
7579    Examples:
7580        >>> func("abs", 5).sql()
7581        'ABS(5)'
7582
7583        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7584        'CAST(5 AS DOUBLE)'
7585
7586    Args:
7587        name: the name of the function to build.
7588        args: the args used to instantiate the function of interest.
7589        copy: whether to copy the argument expressions.
7590        dialect: the source dialect.
7591        kwargs: the kwargs used to instantiate the function of interest.
7592
7593    Note:
7594        The arguments `args` and `kwargs` are mutually exclusive.
7595
7596    Returns:
7597        An instance of the function of interest, or an anonymous function, if `name` doesn't
7598        correspond to an existing `sqlglot.expressions.Func` class.
7599    """
7600    if args and kwargs:
7601        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7602
7603    from sqlglot.dialects.dialect import Dialect
7604
7605    dialect = Dialect.get_or_raise(dialect)
7606
7607    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7608    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7609
7610    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7611    if constructor:
7612        if converted:
7613            if "dialect" in constructor.__code__.co_varnames:
7614                function = constructor(converted, dialect=dialect)
7615            else:
7616                function = constructor(converted)
7617        elif constructor.__name__ == "from_arg_list":
7618            function = constructor.__self__(**kwargs)  # type: ignore
7619        else:
7620            constructor = FUNCTION_BY_NAME.get(name.upper())
7621            if constructor:
7622                function = constructor(**kwargs)
7623            else:
7624                raise ValueError(
7625                    f"Unable to convert '{name}' into a Func. Either manually construct "
7626                    "the Func expression of interest or parse the function call."
7627                )
7628    else:
7629        kwargs = kwargs or {"expressions": converted}
7630        function = Anonymous(this=name, **kwargs)
7631
7632    for error_message in function.error_messages(converted):
7633        raise ValueError(error_message)
7634
7635    return function
7636
7637
7638def case(
7639    expression: t.Optional[ExpOrStr] = None,
7640    **opts,
7641) -> Case:
7642    """
7643    Initialize a CASE statement.
7644
7645    Example:
7646        case().when("a = 1", "foo").else_("bar")
7647
7648    Args:
7649        expression: Optionally, the input expression (not all dialects support this)
7650        **opts: Extra keyword arguments for parsing `expression`
7651    """
7652    if expression is not None:
7653        this = maybe_parse(expression, **opts)
7654    else:
7655        this = None
7656    return Case(this=this, ifs=[])
7657
7658
7659def array(
7660    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7661) -> Array:
7662    """
7663    Returns an array.
7664
7665    Examples:
7666        >>> array(1, 'x').sql()
7667        'ARRAY(1, x)'
7668
7669    Args:
7670        expressions: the expressions to add to the array.
7671        copy: whether to copy the argument expressions.
7672        dialect: the source dialect.
7673        kwargs: the kwargs used to instantiate the function of interest.
7674
7675    Returns:
7676        An array expression.
7677    """
7678    return Array(
7679        expressions=[
7680            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7681            for expression in expressions
7682        ]
7683    )
7684
7685
7686def tuple_(
7687    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7688) -> Tuple:
7689    """
7690    Returns an tuple.
7691
7692    Examples:
7693        >>> tuple_(1, 'x').sql()
7694        '(1, x)'
7695
7696    Args:
7697        expressions: the expressions to add to the tuple.
7698        copy: whether to copy the argument expressions.
7699        dialect: the source dialect.
7700        kwargs: the kwargs used to instantiate the function of interest.
7701
7702    Returns:
7703        A tuple expression.
7704    """
7705    return Tuple(
7706        expressions=[
7707            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7708            for expression in expressions
7709        ]
7710    )
7711
7712
7713def true() -> Boolean:
7714    """
7715    Returns a true Boolean expression.
7716    """
7717    return Boolean(this=True)
7718
7719
7720def false() -> Boolean:
7721    """
7722    Returns a false Boolean expression.
7723    """
7724    return Boolean(this=False)
7725
7726
7727def null() -> Null:
7728    """
7729    Returns a Null expression.
7730    """
7731    return Null()
7732
7733
7734NONNULL_CONSTANTS = (
7735    Literal,
7736    Boolean,
7737)
7738
7739CONSTANTS = (
7740    Literal,
7741    Boolean,
7742    Null,
7743)
SQLGLOT_META = 'sqlglot.meta'
TABLE_PARTS = ('this', 'db', 'catalog')
COLUMN_PARTS = ('this', 'table', 'db', 'catalog')
class Expression:
 66class Expression(metaclass=_Expression):
 67    """
 68    The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary
 69    context, such as its child expressions, their names (arg keys), and whether a given child expression
 70    is optional or not.
 71
 72    Attributes:
 73        key: a unique key for each class in the Expression hierarchy. This is useful for hashing
 74            and representing expressions as strings.
 75        arg_types: determines the arguments (child nodes) supported by an expression. It maps
 76            arg keys to booleans that indicate whether the corresponding args are optional.
 77        parent: a reference to the parent expression (or None, in case of root expressions).
 78        arg_key: the arg key an expression is associated with, i.e. the name its parent expression
 79            uses to refer to it.
 80        index: the index of an expression if it is inside of a list argument in its parent.
 81        comments: a list of comments that are associated with a given expression. This is used in
 82            order to preserve comments when transpiling SQL code.
 83        type: the `sqlglot.expressions.DataType` type of an expression. This is inferred by the
 84            optimizer, in order to enable some transformations that require type information.
 85        meta: a dictionary that can be used to store useful metadata for a given expression.
 86
 87    Example:
 88        >>> class Foo(Expression):
 89        ...     arg_types = {"this": True, "expression": False}
 90
 91        The above definition informs us that Foo is an Expression that requires an argument called
 92        "this" and may also optionally receive an argument called "expression".
 93
 94    Args:
 95        args: a mapping used for retrieving the arguments of an expression, given their arg keys.
 96    """
 97
 98    key = "expression"
 99    arg_types = {"this": True}
100    __slots__ = ("args", "parent", "arg_key", "index", "comments", "_type", "_meta", "_hash")
101
102    def __init__(self, **args: t.Any):
103        self.args: t.Dict[str, t.Any] = args
104        self.parent: t.Optional[Expression] = None
105        self.arg_key: t.Optional[str] = None
106        self.index: t.Optional[int] = None
107        self.comments: t.Optional[t.List[str]] = None
108        self._type: t.Optional[DataType] = None
109        self._meta: t.Optional[t.Dict[str, t.Any]] = None
110        self._hash: t.Optional[int] = None
111
112        for arg_key, value in self.args.items():
113            self._set_parent(arg_key, value)
114
115    def __eq__(self, other) -> bool:
116        return type(self) is type(other) and hash(self) == hash(other)
117
118    @property
119    def hashable_args(self) -> t.Any:
120        return frozenset(
121            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
122            for k, v in self.args.items()
123            if not (v is None or v is False or (type(v) is list and not v))
124        )
125
126    def __hash__(self) -> int:
127        if self._hash is not None:
128            return self._hash
129
130        return hash((self.__class__, self.hashable_args))
131
132    @property
133    def this(self) -> t.Any:
134        """
135        Retrieves the argument with key "this".
136        """
137        return self.args.get("this")
138
139    @property
140    def expression(self) -> t.Any:
141        """
142        Retrieves the argument with key "expression".
143        """
144        return self.args.get("expression")
145
146    @property
147    def expressions(self) -> t.List[t.Any]:
148        """
149        Retrieves the argument with key "expressions".
150        """
151        return self.args.get("expressions") or []
152
153    def text(self, key) -> str:
154        """
155        Returns a textual representation of the argument corresponding to "key". This can only be used
156        for args that are strings or leaf Expression instances, such as identifiers and literals.
157        """
158        field = self.args.get(key)
159        if isinstance(field, str):
160            return field
161        if isinstance(field, (Identifier, Literal, Var)):
162            return field.this
163        if isinstance(field, (Star, Null)):
164            return field.name
165        return ""
166
167    @property
168    def is_string(self) -> bool:
169        """
170        Checks whether a Literal expression is a string.
171        """
172        return isinstance(self, Literal) and self.args["is_string"]
173
174    @property
175    def is_number(self) -> bool:
176        """
177        Checks whether a Literal expression is a number.
178        """
179        return (isinstance(self, Literal) and not self.args["is_string"]) or (
180            isinstance(self, Neg) and self.this.is_number
181        )
182
183    def to_py(self) -> t.Any:
184        """
185        Returns a Python object equivalent of the SQL node.
186        """
187        raise ValueError(f"{self} cannot be converted to a Python object.")
188
189    @property
190    def is_int(self) -> bool:
191        """
192        Checks whether an expression is an integer.
193        """
194        return self.is_number and isinstance(self.to_py(), int)
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)
102    def __init__(self, **args: t.Any):
103        self.args: t.Dict[str, t.Any] = args
104        self.parent: t.Optional[Expression] = None
105        self.arg_key: t.Optional[str] = None
106        self.index: t.Optional[int] = None
107        self.comments: t.Optional[t.List[str]] = None
108        self._type: t.Optional[DataType] = None
109        self._meta: t.Optional[t.Dict[str, t.Any]] = None
110        self._hash: t.Optional[int] = None
111
112        for arg_key, value in self.args.items():
113            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
118    @property
119    def hashable_args(self) -> t.Any:
120        return frozenset(
121            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
122            for k, v in self.args.items()
123            if not (v is None or v is False or (type(v) is list and not v))
124        )
this: Any
132    @property
133    def this(self) -> t.Any:
134        """
135        Retrieves the argument with key "this".
136        """
137        return self.args.get("this")

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

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

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

def to_py(self) -> Any:
183    def to_py(self) -> t.Any:
184        """
185        Returns a Python object equivalent of the SQL node.
186        """
187        raise ValueError(f"{self} cannot be converted to a Python object.")

Returns a Python object equivalent of the SQL node.

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

Checks whether an 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        "on": False,
2132    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False, 'on': False}
key = 'indexparameters'
class Insert(DDL, DML):
2135class Insert(DDL, DML):
2136    arg_types = {
2137        "hint": False,
2138        "with": False,
2139        "is_function": False,
2140        "this": False,
2141        "expression": False,
2142        "conflict": False,
2143        "returning": False,
2144        "overwrite": False,
2145        "exists": False,
2146        "alternative": False,
2147        "where": False,
2148        "ignore": False,
2149        "by_name": False,
2150        "stored": False,
2151    }
2152
2153    def with_(
2154        self,
2155        alias: ExpOrStr,
2156        as_: ExpOrStr,
2157        recursive: t.Optional[bool] = None,
2158        append: bool = True,
2159        dialect: DialectType = None,
2160        copy: bool = True,
2161        **opts,
2162    ) -> Insert:
2163        """
2164        Append to or set the common table expressions.
2165
2166        Example:
2167            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2168            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2169
2170        Args:
2171            alias: the SQL code string to parse as the table name.
2172                If an `Expression` instance is passed, this is used as-is.
2173            as_: the SQL code string to parse as the table expression.
2174                If an `Expression` instance is passed, it will be used as-is.
2175            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2176            append: if `True`, add to any existing expressions.
2177                Otherwise, this resets the expressions.
2178            dialect: the dialect used to parse the input expression.
2179            copy: if `False`, modify this expression instance in-place.
2180            opts: other options to use to parse the input expressions.
2181
2182        Returns:
2183            The modified expression.
2184        """
2185        return _apply_cte_builder(
2186            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2187        )
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:
2153    def with_(
2154        self,
2155        alias: ExpOrStr,
2156        as_: ExpOrStr,
2157        recursive: t.Optional[bool] = None,
2158        append: bool = True,
2159        dialect: DialectType = None,
2160        copy: bool = True,
2161        **opts,
2162    ) -> Insert:
2163        """
2164        Append to or set the common table expressions.
2165
2166        Example:
2167            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2168            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2169
2170        Args:
2171            alias: the SQL code string to parse as the table name.
2172                If an `Expression` instance is passed, this is used as-is.
2173            as_: the SQL code string to parse as the table expression.
2174                If an `Expression` instance is passed, it will be used as-is.
2175            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2176            append: if `True`, add to any existing expressions.
2177                Otherwise, this resets the expressions.
2178            dialect: the dialect used to parse the input expression.
2179            copy: if `False`, modify this expression instance in-place.
2180            opts: other options to use to parse the input expressions.
2181
2182        Returns:
2183            The modified expression.
2184        """
2185        return _apply_cte_builder(
2186            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2187        )

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):
2190class OnConflict(Expression):
2191    arg_types = {
2192        "duplicate": False,
2193        "expressions": False,
2194        "action": False,
2195        "conflict_keys": False,
2196        "constraint": False,
2197    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2200class Returning(Expression):
2201    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2205class Introducer(Expression):
2206    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2210class National(Expression):
2211    pass
key = 'national'
class LoadData(Expression):
2214class LoadData(Expression):
2215    arg_types = {
2216        "this": True,
2217        "local": False,
2218        "overwrite": False,
2219        "inpath": True,
2220        "partition": False,
2221        "input_format": False,
2222        "serde": False,
2223    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2226class Partition(Expression):
2227    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2230class PartitionRange(Expression):
2231    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2235class PartitionId(Expression):
2236    pass
key = 'partitionid'
class Fetch(Expression):
2239class Fetch(Expression):
2240    arg_types = {
2241        "direction": False,
2242        "count": False,
2243        "percent": False,
2244        "with_ties": False,
2245    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2248class Group(Expression):
2249    arg_types = {
2250        "expressions": False,
2251        "grouping_sets": False,
2252        "cube": False,
2253        "rollup": False,
2254        "totals": False,
2255        "all": False,
2256    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2259class Lambda(Expression):
2260    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2263class Limit(Expression):
2264    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):
2267class Literal(Condition):
2268    arg_types = {"this": True, "is_string": True}
2269
2270    @property
2271    def hashable_args(self) -> t.Any:
2272        return (self.this, self.args.get("is_string"))
2273
2274    @classmethod
2275    def number(cls, number) -> Literal:
2276        return cls(this=str(number), is_string=False)
2277
2278    @classmethod
2279    def string(cls, string) -> Literal:
2280        return cls(this=str(string), is_string=True)
2281
2282    @property
2283    def output_name(self) -> str:
2284        return self.name
2285
2286    def to_py(self) -> int | str | Decimal:
2287        if self.is_number:
2288            try:
2289                return int(self.this)
2290            except ValueError:
2291                return Decimal(self.this)
2292        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2270    @property
2271    def hashable_args(self) -> t.Any:
2272        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2274    @classmethod
2275    def number(cls, number) -> Literal:
2276        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2278    @classmethod
2279    def string(cls, string) -> Literal:
2280        return cls(this=str(string), is_string=True)
output_name: str
2282    @property
2283    def output_name(self) -> str:
2284        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 to_py(self) -> int | str | decimal.Decimal:
2286    def to_py(self) -> int | str | Decimal:
2287        if self.is_number:
2288            try:
2289                return int(self.this)
2290            except ValueError:
2291                return Decimal(self.this)
2292        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2295class Join(Expression):
2296    arg_types = {
2297        "this": True,
2298        "on": False,
2299        "side": False,
2300        "kind": False,
2301        "using": False,
2302        "method": False,
2303        "global": False,
2304        "hint": False,
2305        "match_condition": False,  # Snowflake
2306    }
2307
2308    @property
2309    def method(self) -> str:
2310        return self.text("method").upper()
2311
2312    @property
2313    def kind(self) -> str:
2314        return self.text("kind").upper()
2315
2316    @property
2317    def side(self) -> str:
2318        return self.text("side").upper()
2319
2320    @property
2321    def hint(self) -> str:
2322        return self.text("hint").upper()
2323
2324    @property
2325    def alias_or_name(self) -> str:
2326        return self.this.alias_or_name
2327
2328    def on(
2329        self,
2330        *expressions: t.Optional[ExpOrStr],
2331        append: bool = True,
2332        dialect: DialectType = None,
2333        copy: bool = True,
2334        **opts,
2335    ) -> Join:
2336        """
2337        Append to or set the ON expressions.
2338
2339        Example:
2340            >>> import sqlglot
2341            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2342            'JOIN x ON y = 1'
2343
2344        Args:
2345            *expressions: the SQL code strings to parse.
2346                If an `Expression` instance is passed, it will be used as-is.
2347                Multiple expressions are combined with an AND operator.
2348            append: if `True`, AND the new expressions to any existing expression.
2349                Otherwise, this resets the expression.
2350            dialect: the dialect used to parse the input expressions.
2351            copy: if `False`, modify this expression instance in-place.
2352            opts: other options to use to parse the input expressions.
2353
2354        Returns:
2355            The modified Join expression.
2356        """
2357        join = _apply_conjunction_builder(
2358            *expressions,
2359            instance=self,
2360            arg="on",
2361            append=append,
2362            dialect=dialect,
2363            copy=copy,
2364            **opts,
2365        )
2366
2367        if join.kind == "CROSS":
2368            join.set("kind", None)
2369
2370        return join
2371
2372    def using(
2373        self,
2374        *expressions: t.Optional[ExpOrStr],
2375        append: bool = True,
2376        dialect: DialectType = None,
2377        copy: bool = True,
2378        **opts,
2379    ) -> Join:
2380        """
2381        Append to or set the USING expressions.
2382
2383        Example:
2384            >>> import sqlglot
2385            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2386            'JOIN x USING (foo, bla)'
2387
2388        Args:
2389            *expressions: the SQL code strings to parse.
2390                If an `Expression` instance is passed, it will be used as-is.
2391            append: if `True`, concatenate the new expressions to the existing "using" list.
2392                Otherwise, this resets the expression.
2393            dialect: the dialect used to parse the input expressions.
2394            copy: if `False`, modify this expression instance in-place.
2395            opts: other options to use to parse the input expressions.
2396
2397        Returns:
2398            The modified Join expression.
2399        """
2400        join = _apply_list_builder(
2401            *expressions,
2402            instance=self,
2403            arg="using",
2404            append=append,
2405            dialect=dialect,
2406            copy=copy,
2407            **opts,
2408        )
2409
2410        if join.kind == "CROSS":
2411            join.set("kind", None)
2412
2413        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
2308    @property
2309    def method(self) -> str:
2310        return self.text("method").upper()
kind: str
2312    @property
2313    def kind(self) -> str:
2314        return self.text("kind").upper()
side: str
2316    @property
2317    def side(self) -> str:
2318        return self.text("side").upper()
hint: str
2320    @property
2321    def hint(self) -> str:
2322        return self.text("hint").upper()
alias_or_name: str
2324    @property
2325    def alias_or_name(self) -> str:
2326        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:
2328    def on(
2329        self,
2330        *expressions: t.Optional[ExpOrStr],
2331        append: bool = True,
2332        dialect: DialectType = None,
2333        copy: bool = True,
2334        **opts,
2335    ) -> Join:
2336        """
2337        Append to or set the ON expressions.
2338
2339        Example:
2340            >>> import sqlglot
2341            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2342            'JOIN x ON y = 1'
2343
2344        Args:
2345            *expressions: the SQL code strings to parse.
2346                If an `Expression` instance is passed, it will be used as-is.
2347                Multiple expressions are combined with an AND operator.
2348            append: if `True`, AND the new expressions to any existing expression.
2349                Otherwise, this resets the expression.
2350            dialect: the dialect used to parse the input expressions.
2351            copy: if `False`, modify this expression instance in-place.
2352            opts: other options to use to parse the input expressions.
2353
2354        Returns:
2355            The modified Join expression.
2356        """
2357        join = _apply_conjunction_builder(
2358            *expressions,
2359            instance=self,
2360            arg="on",
2361            append=append,
2362            dialect=dialect,
2363            copy=copy,
2364            **opts,
2365        )
2366
2367        if join.kind == "CROSS":
2368            join.set("kind", None)
2369
2370        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:
2372    def using(
2373        self,
2374        *expressions: t.Optional[ExpOrStr],
2375        append: bool = True,
2376        dialect: DialectType = None,
2377        copy: bool = True,
2378        **opts,
2379    ) -> Join:
2380        """
2381        Append to or set the USING expressions.
2382
2383        Example:
2384            >>> import sqlglot
2385            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2386            'JOIN x USING (foo, bla)'
2387
2388        Args:
2389            *expressions: the SQL code strings to parse.
2390                If an `Expression` instance is passed, it will be used as-is.
2391            append: if `True`, concatenate the new expressions to the existing "using" list.
2392                Otherwise, this resets the expression.
2393            dialect: the dialect used to parse the input expressions.
2394            copy: if `False`, modify this expression instance in-place.
2395            opts: other options to use to parse the input expressions.
2396
2397        Returns:
2398            The modified Join expression.
2399        """
2400        join = _apply_list_builder(
2401            *expressions,
2402            instance=self,
2403            arg="using",
2404            append=append,
2405            dialect=dialect,
2406            copy=copy,
2407            **opts,
2408        )
2409
2410        if join.kind == "CROSS":
2411            join.set("kind", None)
2412
2413        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):
2416class Lateral(UDTF):
2417    arg_types = {
2418        "this": True,
2419        "view": False,
2420        "outer": False,
2421        "alias": False,
2422        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2423    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2426class MatchRecognizeMeasure(Expression):
2427    arg_types = {
2428        "this": True,
2429        "window_frame": False,
2430    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2433class MatchRecognize(Expression):
2434    arg_types = {
2435        "partition_by": False,
2436        "order": False,
2437        "measures": False,
2438        "rows": False,
2439        "after": False,
2440        "pattern": False,
2441        "define": False,
2442        "alias": False,
2443    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2448class Final(Expression):
2449    pass
key = 'final'
class Offset(Expression):
2452class Offset(Expression):
2453    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2456class Order(Expression):
2457    arg_types = {
2458        "this": False,
2459        "expressions": True,
2460        "interpolate": False,
2461        "siblings": False,
2462    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2466class WithFill(Expression):
2467    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2472class Cluster(Order):
2473    pass
key = 'cluster'
class Distribute(Order):
2476class Distribute(Order):
2477    pass
key = 'distribute'
class Sort(Order):
2480class Sort(Order):
2481    pass
key = 'sort'
class Ordered(Expression):
2484class Ordered(Expression):
2485    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):
2488class Property(Expression):
2489    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2492class AllowedValuesProperty(Expression):
2493    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2496class AlgorithmProperty(Property):
2497    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2500class AutoIncrementProperty(Property):
2501    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2505class AutoRefreshProperty(Property):
2506    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2509class BackupProperty(Property):
2510    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2513class BlockCompressionProperty(Property):
2514    arg_types = {
2515        "autotemp": False,
2516        "always": False,
2517        "default": False,
2518        "manual": False,
2519        "never": False,
2520    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2523class CharacterSetProperty(Property):
2524    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2527class ChecksumProperty(Property):
2528    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2531class CollateProperty(Property):
2532    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2535class CopyGrantsProperty(Property):
2536    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2539class DataBlocksizeProperty(Property):
2540    arg_types = {
2541        "size": False,
2542        "units": False,
2543        "minimum": False,
2544        "maximum": False,
2545        "default": False,
2546    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2549class DataDeletionProperty(Property):
2550    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):
2553class DefinerProperty(Property):
2554    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2557class DistKeyProperty(Property):
2558    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2561class DistStyleProperty(Property):
2562    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2565class EngineProperty(Property):
2566    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2569class HeapProperty(Property):
2570    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2573class ToTableProperty(Property):
2574    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2577class ExecuteAsProperty(Property):
2578    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2581class ExternalProperty(Property):
2582    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2585class FallbackProperty(Property):
2586    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2589class FileFormatProperty(Property):
2590    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2593class FreespaceProperty(Property):
2594    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2597class GlobalProperty(Property):
2598    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2601class IcebergProperty(Property):
2602    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2605class InheritsProperty(Property):
2606    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2609class InputModelProperty(Property):
2610    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2613class OutputModelProperty(Property):
2614    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2617class IsolatedLoadingProperty(Property):
2618    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2621class JournalProperty(Property):
2622    arg_types = {
2623        "no": False,
2624        "dual": False,
2625        "before": False,
2626        "local": False,
2627        "after": False,
2628    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2631class LanguageProperty(Property):
2632    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2636class ClusteredByProperty(Property):
2637    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2640class DictProperty(Property):
2641    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2644class DictSubProperty(Property):
2645    pass
key = 'dictsubproperty'
class DictRange(Property):
2648class DictRange(Property):
2649    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2652class DynamicProperty(Property):
2653    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2658class OnCluster(Property):
2659    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2662class LikeProperty(Property):
2663    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2666class LocationProperty(Property):
2667    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2670class LockProperty(Property):
2671    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2674class LockingProperty(Property):
2675    arg_types = {
2676        "this": False,
2677        "kind": True,
2678        "for_or_in": False,
2679        "lock_type": True,
2680        "override": False,
2681    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2684class LogProperty(Property):
2685    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2688class MaterializedProperty(Property):
2689    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2692class MergeBlockRatioProperty(Property):
2693    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):
2696class NoPrimaryIndexProperty(Property):
2697    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2700class OnProperty(Property):
2701    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2704class OnCommitProperty(Property):
2705    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2708class PartitionedByProperty(Property):
2709    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2713class PartitionBoundSpec(Expression):
2714    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2715    arg_types = {
2716        "this": False,
2717        "expression": False,
2718        "from_expressions": False,
2719        "to_expressions": False,
2720    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2723class PartitionedOfProperty(Property):
2724    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2725    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2728class RemoteWithConnectionModelProperty(Property):
2729    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2732class ReturnsProperty(Property):
2733    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):
2736class StrictProperty(Property):
2737    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2740class RowFormatProperty(Property):
2741    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2744class RowFormatDelimitedProperty(Property):
2745    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2746    arg_types = {
2747        "fields": False,
2748        "escaped": False,
2749        "collection_items": False,
2750        "map_keys": False,
2751        "lines": False,
2752        "null": False,
2753        "serde": False,
2754    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2757class RowFormatSerdeProperty(Property):
2758    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2762class QueryTransform(Expression):
2763    arg_types = {
2764        "expressions": True,
2765        "command_script": True,
2766        "schema": False,
2767        "row_format_before": False,
2768        "record_writer": False,
2769        "row_format_after": False,
2770        "record_reader": False,
2771    }
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):
2774class SampleProperty(Property):
2775    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2778class SchemaCommentProperty(Property):
2779    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2782class SerdeProperties(Property):
2783    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2786class SetProperty(Property):
2787    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2790class SharingProperty(Property):
2791    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2794class SetConfigProperty(Property):
2795    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2798class SettingsProperty(Property):
2799    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2802class SortKeyProperty(Property):
2803    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2806class SqlReadWriteProperty(Property):
2807    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2810class SqlSecurityProperty(Property):
2811    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2814class StabilityProperty(Property):
2815    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2818class TemporaryProperty(Property):
2819    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2822class SecureProperty(Property):
2823    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2826class TransformModelProperty(Property):
2827    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2830class TransientProperty(Property):
2831    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2834class UnloggedProperty(Property):
2835    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2839class ViewAttributeProperty(Property):
2840    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2843class VolatileProperty(Property):
2844    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2847class WithDataProperty(Property):
2848    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2851class WithJournalTableProperty(Property):
2852    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSystemVersioningProperty(Property):
2855class WithSystemVersioningProperty(Property):
2856    arg_types = {
2857        "on": False,
2858        "this": False,
2859        "data_consistency": False,
2860        "retention_period": False,
2861        "with": True,
2862    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2865class Properties(Expression):
2866    arg_types = {"expressions": True}
2867
2868    NAME_TO_PROPERTY = {
2869        "ALGORITHM": AlgorithmProperty,
2870        "AUTO_INCREMENT": AutoIncrementProperty,
2871        "CHARACTER SET": CharacterSetProperty,
2872        "CLUSTERED_BY": ClusteredByProperty,
2873        "COLLATE": CollateProperty,
2874        "COMMENT": SchemaCommentProperty,
2875        "DEFINER": DefinerProperty,
2876        "DISTKEY": DistKeyProperty,
2877        "DISTSTYLE": DistStyleProperty,
2878        "ENGINE": EngineProperty,
2879        "EXECUTE AS": ExecuteAsProperty,
2880        "FORMAT": FileFormatProperty,
2881        "LANGUAGE": LanguageProperty,
2882        "LOCATION": LocationProperty,
2883        "LOCK": LockProperty,
2884        "PARTITIONED_BY": PartitionedByProperty,
2885        "RETURNS": ReturnsProperty,
2886        "ROW_FORMAT": RowFormatProperty,
2887        "SORTKEY": SortKeyProperty,
2888    }
2889
2890    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2891
2892    # CREATE property locations
2893    # Form: schema specified
2894    #   create [POST_CREATE]
2895    #     table a [POST_NAME]
2896    #     (b int) [POST_SCHEMA]
2897    #     with ([POST_WITH])
2898    #     index (b) [POST_INDEX]
2899    #
2900    # Form: alias selection
2901    #   create [POST_CREATE]
2902    #     table a [POST_NAME]
2903    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2904    #     index (c) [POST_INDEX]
2905    class Location(AutoName):
2906        POST_CREATE = auto()
2907        POST_NAME = auto()
2908        POST_SCHEMA = auto()
2909        POST_WITH = auto()
2910        POST_ALIAS = auto()
2911        POST_EXPRESSION = auto()
2912        POST_INDEX = auto()
2913        UNSUPPORTED = auto()
2914
2915    @classmethod
2916    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2917        expressions = []
2918        for key, value in properties_dict.items():
2919            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2920            if property_cls:
2921                expressions.append(property_cls(this=convert(value)))
2922            else:
2923                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2924
2925        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:
2915    @classmethod
2916    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2917        expressions = []
2918        for key, value in properties_dict.items():
2919            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2920            if property_cls:
2921                expressions.append(property_cls(this=convert(value)))
2922            else:
2923                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2924
2925        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2905    class Location(AutoName):
2906        POST_CREATE = auto()
2907        POST_NAME = auto()
2908        POST_SCHEMA = auto()
2909        POST_WITH = auto()
2910        POST_ALIAS = auto()
2911        POST_EXPRESSION = auto()
2912        POST_INDEX = auto()
2913        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):
2928class Qualify(Expression):
2929    pass
key = 'qualify'
class InputOutputFormat(Expression):
2932class InputOutputFormat(Expression):
2933    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2937class Return(Expression):
2938    pass
key = 'return'
class Reference(Expression):
2941class Reference(Expression):
2942    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2945class Tuple(Expression):
2946    arg_types = {"expressions": False}
2947
2948    def isin(
2949        self,
2950        *expressions: t.Any,
2951        query: t.Optional[ExpOrStr] = None,
2952        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2953        copy: bool = True,
2954        **opts,
2955    ) -> In:
2956        return In(
2957            this=maybe_copy(self, copy),
2958            expressions=[convert(e, copy=copy) for e in expressions],
2959            query=maybe_parse(query, copy=copy, **opts) if query else None,
2960            unnest=(
2961                Unnest(
2962                    expressions=[
2963                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2964                        for e in ensure_list(unnest)
2965                    ]
2966                )
2967                if unnest
2968                else None
2969            ),
2970        )
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:
2948    def isin(
2949        self,
2950        *expressions: t.Any,
2951        query: t.Optional[ExpOrStr] = None,
2952        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2953        copy: bool = True,
2954        **opts,
2955    ) -> In:
2956        return In(
2957            this=maybe_copy(self, copy),
2958            expressions=[convert(e, copy=copy) for e in expressions],
2959            query=maybe_parse(query, copy=copy, **opts) if query else None,
2960            unnest=(
2961                Unnest(
2962                    expressions=[
2963                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2964                        for e in ensure_list(unnest)
2965                    ]
2966                )
2967                if unnest
2968                else None
2969            ),
2970        )
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):
3001class QueryOption(Expression):
3002    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3006class WithTableHint(Expression):
3007    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3011class IndexTableHint(Expression):
3012    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3016class HistoricalData(Expression):
3017    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3020class Table(Expression):
3021    arg_types = {
3022        "this": False,
3023        "alias": False,
3024        "db": False,
3025        "catalog": False,
3026        "laterals": False,
3027        "joins": False,
3028        "pivots": False,
3029        "hints": False,
3030        "system_time": False,
3031        "version": False,
3032        "format": False,
3033        "pattern": False,
3034        "ordinality": False,
3035        "when": False,
3036        "only": False,
3037        "partition": False,
3038    }
3039
3040    @property
3041    def name(self) -> str:
3042        if isinstance(self.this, Func):
3043            return ""
3044        return self.this.name
3045
3046    @property
3047    def db(self) -> str:
3048        return self.text("db")
3049
3050    @property
3051    def catalog(self) -> str:
3052        return self.text("catalog")
3053
3054    @property
3055    def selects(self) -> t.List[Expression]:
3056        return []
3057
3058    @property
3059    def named_selects(self) -> t.List[str]:
3060        return []
3061
3062    @property
3063    def parts(self) -> t.List[Expression]:
3064        """Return the parts of a table in order catalog, db, table."""
3065        parts: t.List[Expression] = []
3066
3067        for arg in ("catalog", "db", "this"):
3068            part = self.args.get(arg)
3069
3070            if isinstance(part, Dot):
3071                parts.extend(part.flatten())
3072            elif isinstance(part, Expression):
3073                parts.append(part)
3074
3075        return parts
3076
3077    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3078        parts = self.parts
3079        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3080        alias = self.args.get("alias")
3081        if alias:
3082            col = alias_(col, alias.this, copy=copy)
3083        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
3040    @property
3041    def name(self) -> str:
3042        if isinstance(self.this, Func):
3043            return ""
3044        return self.this.name
db: str
3046    @property
3047    def db(self) -> str:
3048        return self.text("db")
catalog: str
3050    @property
3051    def catalog(self) -> str:
3052        return self.text("catalog")
selects: List[Expression]
3054    @property
3055    def selects(self) -> t.List[Expression]:
3056        return []
named_selects: List[str]
3058    @property
3059    def named_selects(self) -> t.List[str]:
3060        return []
parts: List[Expression]
3062    @property
3063    def parts(self) -> t.List[Expression]:
3064        """Return the parts of a table in order catalog, db, table."""
3065        parts: t.List[Expression] = []
3066
3067        for arg in ("catalog", "db", "this"):
3068            part = self.args.get(arg)
3069
3070            if isinstance(part, Dot):
3071                parts.extend(part.flatten())
3072            elif isinstance(part, Expression):
3073                parts.append(part)
3074
3075        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3077    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3078        parts = self.parts
3079        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3080        alias = self.args.get("alias")
3081        if alias:
3082            col = alias_(col, alias.this, copy=copy)
3083        return col
key = 'table'
class SetOperation(Query):
3086class SetOperation(Query):
3087    arg_types = {
3088        "with": False,
3089        "this": True,
3090        "expression": True,
3091        "distinct": False,
3092        "by_name": False,
3093        **QUERY_MODIFIERS,
3094    }
3095
3096    def select(
3097        self: S,
3098        *expressions: t.Optional[ExpOrStr],
3099        append: bool = True,
3100        dialect: DialectType = None,
3101        copy: bool = True,
3102        **opts,
3103    ) -> S:
3104        this = maybe_copy(self, copy)
3105        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3106        this.expression.unnest().select(
3107            *expressions, append=append, dialect=dialect, copy=False, **opts
3108        )
3109        return this
3110
3111    @property
3112    def named_selects(self) -> t.List[str]:
3113        return self.this.unnest().named_selects
3114
3115    @property
3116    def is_star(self) -> bool:
3117        return self.this.is_star or self.expression.is_star
3118
3119    @property
3120    def selects(self) -> t.List[Expression]:
3121        return self.this.unnest().selects
3122
3123    @property
3124    def left(self) -> Expression:
3125        return self.this
3126
3127    @property
3128    def right(self) -> Expression:
3129        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: ~S, *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) -> ~S:
3096    def select(
3097        self: S,
3098        *expressions: t.Optional[ExpOrStr],
3099        append: bool = True,
3100        dialect: DialectType = None,
3101        copy: bool = True,
3102        **opts,
3103    ) -> S:
3104        this = maybe_copy(self, copy)
3105        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3106        this.expression.unnest().select(
3107            *expressions, append=append, dialect=dialect, copy=False, **opts
3108        )
3109        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]
3111    @property
3112    def named_selects(self) -> t.List[str]:
3113        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3115    @property
3116    def is_star(self) -> bool:
3117        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3119    @property
3120    def selects(self) -> t.List[Expression]:
3121        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3747    @property
3748    def selects(self) -> t.List[Expression]:
3749        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
3770    def unwrap(self) -> Subquery:
3771        expression = self
3772        while expression.same_parent and expression.is_wrapper:
3773            expression = t.cast(Subquery, expression.parent)
3774        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:
3776    def select(
3777        self,
3778        *expressions: t.Optional[ExpOrStr],
3779        append: bool = True,
3780        dialect: DialectType = None,
3781        copy: bool = True,
3782        **opts,
3783    ) -> Subquery:
3784        this = maybe_copy(self, copy)
3785        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3786        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
3788    @property
3789    def is_wrapper(self) -> bool:
3790        """
3791        Whether this Subquery acts as a simple wrapper around another expression.
3792
3793        SELECT * FROM (((SELECT * FROM t)))
3794                      ^
3795                      This corresponds to a "wrapper" Subquery node
3796        """
3797        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
3799    @property
3800    def is_star(self) -> bool:
3801        return self.this.is_star

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3835class Pivot(Expression):
3836    arg_types = {
3837        "this": False,
3838        "alias": False,
3839        "expressions": False,
3840        "field": False,
3841        "unpivot": False,
3842        "using": False,
3843        "group": False,
3844        "columns": False,
3845        "include_nulls": False,
3846    }
3847
3848    @property
3849    def unpivot(self) -> bool:
3850        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
3848    @property
3849    def unpivot(self) -> bool:
3850        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3853class Window(Condition):
3854    arg_types = {
3855        "this": True,
3856        "partition_by": False,
3857        "order": False,
3858        "spec": False,
3859        "alias": False,
3860        "over": False,
3861        "first": False,
3862    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3865class WindowSpec(Expression):
3866    arg_types = {
3867        "kind": False,
3868        "start": False,
3869        "start_side": False,
3870        "end": False,
3871        "end_side": False,
3872    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3875class PreWhere(Expression):
3876    pass
key = 'prewhere'
class Where(Expression):
3879class Where(Expression):
3880    pass
key = 'where'
class Star(Expression):
3883class Star(Expression):
3884    arg_types = {"except": False, "replace": False, "rename": False}
3885
3886    @property
3887    def name(self) -> str:
3888        return "*"
3889
3890    @property
3891    def output_name(self) -> str:
3892        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3886    @property
3887    def name(self) -> str:
3888        return "*"
output_name: str
3890    @property
3891    def output_name(self) -> str:
3892        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):
3895class Parameter(Condition):
3896    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3899class SessionParameter(Condition):
3900    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3903class Placeholder(Condition):
3904    arg_types = {"this": False, "kind": False}
3905
3906    @property
3907    def name(self) -> str:
3908        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3906    @property
3907    def name(self) -> str:
3908        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3911class Null(Condition):
3912    arg_types: t.Dict[str, t.Any] = {}
3913
3914    @property
3915    def name(self) -> str:
3916        return "NULL"
3917
3918    def to_py(self) -> Lit[None]:
3919        return None
arg_types: Dict[str, Any] = {}
name: str
3914    @property
3915    def name(self) -> str:
3916        return "NULL"
def to_py(self) -> Literal[None]:
3918    def to_py(self) -> Lit[None]:
3919        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
3922class Boolean(Condition):
3923    def to_py(self) -> bool:
3924        return self.this
def to_py(self) -> bool:
3923    def to_py(self) -> bool:
3924        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
3927class DataTypeParam(Expression):
3928    arg_types = {"this": True, "expression": False}
3929
3930    @property
3931    def name(self) -> str:
3932        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3930    @property
3931    def name(self) -> str:
3932        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3935class DataType(Expression):
3936    arg_types = {
3937        "this": True,
3938        "expressions": False,
3939        "nested": False,
3940        "values": False,
3941        "prefix": False,
3942        "kind": False,
3943    }
3944
3945    class Type(AutoName):
3946        ARRAY = auto()
3947        AGGREGATEFUNCTION = auto()
3948        SIMPLEAGGREGATEFUNCTION = auto()
3949        BIGDECIMAL = auto()
3950        BIGINT = auto()
3951        BIGSERIAL = auto()
3952        BINARY = auto()
3953        BIT = auto()
3954        BOOLEAN = auto()
3955        BPCHAR = auto()
3956        CHAR = auto()
3957        DATE = auto()
3958        DATE32 = auto()
3959        DATEMULTIRANGE = auto()
3960        DATERANGE = auto()
3961        DATETIME = auto()
3962        DATETIME64 = auto()
3963        DECIMAL = auto()
3964        DOUBLE = auto()
3965        ENUM = auto()
3966        ENUM8 = auto()
3967        ENUM16 = auto()
3968        FIXEDSTRING = auto()
3969        FLOAT = auto()
3970        GEOGRAPHY = auto()
3971        GEOMETRY = auto()
3972        HLLSKETCH = auto()
3973        HSTORE = auto()
3974        IMAGE = auto()
3975        INET = auto()
3976        INT = auto()
3977        INT128 = auto()
3978        INT256 = auto()
3979        INT4MULTIRANGE = auto()
3980        INT4RANGE = auto()
3981        INT8MULTIRANGE = auto()
3982        INT8RANGE = auto()
3983        INTERVAL = auto()
3984        IPADDRESS = auto()
3985        IPPREFIX = auto()
3986        IPV4 = auto()
3987        IPV6 = auto()
3988        JSON = auto()
3989        JSONB = auto()
3990        LIST = auto()
3991        LONGBLOB = auto()
3992        LONGTEXT = auto()
3993        LOWCARDINALITY = auto()
3994        MAP = auto()
3995        MEDIUMBLOB = auto()
3996        MEDIUMINT = auto()
3997        MEDIUMTEXT = auto()
3998        MONEY = auto()
3999        NAME = auto()
4000        NCHAR = auto()
4001        NESTED = auto()
4002        NULL = auto()
4003        NULLABLE = auto()
4004        NUMMULTIRANGE = auto()
4005        NUMRANGE = auto()
4006        NVARCHAR = auto()
4007        OBJECT = auto()
4008        ROWVERSION = auto()
4009        SERIAL = auto()
4010        SET = auto()
4011        SMALLINT = auto()
4012        SMALLMONEY = auto()
4013        SMALLSERIAL = auto()
4014        STRUCT = auto()
4015        SUPER = auto()
4016        TEXT = auto()
4017        TINYBLOB = auto()
4018        TINYTEXT = auto()
4019        TIME = auto()
4020        TIMETZ = auto()
4021        TIMESTAMP = auto()
4022        TIMESTAMPNTZ = auto()
4023        TIMESTAMPLTZ = auto()
4024        TIMESTAMPTZ = auto()
4025        TIMESTAMP_S = auto()
4026        TIMESTAMP_MS = auto()
4027        TIMESTAMP_NS = auto()
4028        TINYINT = auto()
4029        TSMULTIRANGE = auto()
4030        TSRANGE = auto()
4031        TSTZMULTIRANGE = auto()
4032        TSTZRANGE = auto()
4033        UBIGINT = auto()
4034        UINT = auto()
4035        UINT128 = auto()
4036        UINT256 = auto()
4037        UMEDIUMINT = auto()
4038        UDECIMAL = auto()
4039        UNIQUEIDENTIFIER = auto()
4040        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4041        USERDEFINED = "USER-DEFINED"
4042        USMALLINT = auto()
4043        UTINYINT = auto()
4044        UUID = auto()
4045        VARBINARY = auto()
4046        VARCHAR = auto()
4047        VARIANT = auto()
4048        XML = auto()
4049        YEAR = auto()
4050        TDIGEST = auto()
4051
4052    STRUCT_TYPES = {
4053        Type.NESTED,
4054        Type.OBJECT,
4055        Type.STRUCT,
4056    }
4057
4058    NESTED_TYPES = {
4059        *STRUCT_TYPES,
4060        Type.ARRAY,
4061        Type.MAP,
4062    }
4063
4064    TEXT_TYPES = {
4065        Type.CHAR,
4066        Type.NCHAR,
4067        Type.NVARCHAR,
4068        Type.TEXT,
4069        Type.VARCHAR,
4070        Type.NAME,
4071    }
4072
4073    SIGNED_INTEGER_TYPES = {
4074        Type.BIGINT,
4075        Type.INT,
4076        Type.INT128,
4077        Type.INT256,
4078        Type.MEDIUMINT,
4079        Type.SMALLINT,
4080        Type.TINYINT,
4081    }
4082
4083    UNSIGNED_INTEGER_TYPES = {
4084        Type.UBIGINT,
4085        Type.UINT,
4086        Type.UINT128,
4087        Type.UINT256,
4088        Type.UMEDIUMINT,
4089        Type.USMALLINT,
4090        Type.UTINYINT,
4091    }
4092
4093    INTEGER_TYPES = {
4094        *SIGNED_INTEGER_TYPES,
4095        *UNSIGNED_INTEGER_TYPES,
4096        Type.BIT,
4097    }
4098
4099    FLOAT_TYPES = {
4100        Type.DOUBLE,
4101        Type.FLOAT,
4102    }
4103
4104    REAL_TYPES = {
4105        *FLOAT_TYPES,
4106        Type.BIGDECIMAL,
4107        Type.DECIMAL,
4108        Type.MONEY,
4109        Type.SMALLMONEY,
4110        Type.UDECIMAL,
4111    }
4112
4113    NUMERIC_TYPES = {
4114        *INTEGER_TYPES,
4115        *REAL_TYPES,
4116    }
4117
4118    TEMPORAL_TYPES = {
4119        Type.DATE,
4120        Type.DATE32,
4121        Type.DATETIME,
4122        Type.DATETIME64,
4123        Type.TIME,
4124        Type.TIMESTAMP,
4125        Type.TIMESTAMPNTZ,
4126        Type.TIMESTAMPLTZ,
4127        Type.TIMESTAMPTZ,
4128        Type.TIMESTAMP_MS,
4129        Type.TIMESTAMP_NS,
4130        Type.TIMESTAMP_S,
4131        Type.TIMETZ,
4132    }
4133
4134    @classmethod
4135    def build(
4136        cls,
4137        dtype: DATA_TYPE,
4138        dialect: DialectType = None,
4139        udt: bool = False,
4140        copy: bool = True,
4141        **kwargs,
4142    ) -> DataType:
4143        """
4144        Constructs a DataType object.
4145
4146        Args:
4147            dtype: the data type of interest.
4148            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4149            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4150                DataType, thus creating a user-defined type.
4151            copy: whether to copy the data type.
4152            kwargs: additional arguments to pass in the constructor of DataType.
4153
4154        Returns:
4155            The constructed DataType object.
4156        """
4157        from sqlglot import parse_one
4158
4159        if isinstance(dtype, str):
4160            if dtype.upper() == "UNKNOWN":
4161                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4162
4163            try:
4164                data_type_exp = parse_one(
4165                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4166                )
4167            except ParseError:
4168                if udt:
4169                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4170                raise
4171        elif isinstance(dtype, DataType.Type):
4172            data_type_exp = DataType(this=dtype)
4173        elif isinstance(dtype, DataType):
4174            return maybe_copy(dtype, copy)
4175        else:
4176            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4177
4178        return DataType(**{**data_type_exp.args, **kwargs})
4179
4180    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4181        """
4182        Checks whether this DataType matches one of the provided data types. Nested types or precision
4183        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4184
4185        Args:
4186            dtypes: the data types to compare this DataType to.
4187
4188        Returns:
4189            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4190        """
4191        for dtype in dtypes:
4192            other = DataType.build(dtype, copy=False, udt=True)
4193
4194            if (
4195                other.expressions
4196                or self.this == DataType.Type.USERDEFINED
4197                or other.this == DataType.Type.USERDEFINED
4198            ):
4199                matches = self == other
4200            else:
4201                matches = self.this == other.this
4202
4203            if matches:
4204                return True
4205        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>}
NESTED_TYPES = {<Type.NESTED: 'NESTED'>, <Type.ARRAY: 'ARRAY'>, <Type.MAP: 'MAP'>, <Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>}
TEXT_TYPES = {<Type.VARCHAR: 'VARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NAME: 'NAME'>}
SIGNED_INTEGER_TYPES = {<Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UBIGINT: 'UBIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.USMALLINT: 'USMALLINT'>}
INTEGER_TYPES = {<Type.UBIGINT: 'UBIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.UINT256: 'UINT256'>, <Type.TINYINT: 'TINYINT'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.MONEY: 'MONEY'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT: 'UINT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.USMALLINT: 'USMALLINT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.MONEY: 'MONEY'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT256: 'UINT256'>, <Type.BIT: 'BIT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>}
TEMPORAL_TYPES = {<Type.DATE32: 'DATE32'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATE: 'DATE'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>}
@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:
4134    @classmethod
4135    def build(
4136        cls,
4137        dtype: DATA_TYPE,
4138        dialect: DialectType = None,
4139        udt: bool = False,
4140        copy: bool = True,
4141        **kwargs,
4142    ) -> DataType:
4143        """
4144        Constructs a DataType object.
4145
4146        Args:
4147            dtype: the data type of interest.
4148            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4149            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4150                DataType, thus creating a user-defined type.
4151            copy: whether to copy the data type.
4152            kwargs: additional arguments to pass in the constructor of DataType.
4153
4154        Returns:
4155            The constructed DataType object.
4156        """
4157        from sqlglot import parse_one
4158
4159        if isinstance(dtype, str):
4160            if dtype.upper() == "UNKNOWN":
4161                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4162
4163            try:
4164                data_type_exp = parse_one(
4165                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4166                )
4167            except ParseError:
4168                if udt:
4169                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4170                raise
4171        elif isinstance(dtype, DataType.Type):
4172            data_type_exp = DataType(this=dtype)
4173        elif isinstance(dtype, DataType):
4174            return maybe_copy(dtype, copy)
4175        else:
4176            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4177
4178        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:
4180    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4181        """
4182        Checks whether this DataType matches one of the provided data types. Nested types or precision
4183        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4184
4185        Args:
4186            dtypes: the data types to compare this DataType to.
4187
4188        Returns:
4189            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4190        """
4191        for dtype in dtypes:
4192            other = DataType.build(dtype, copy=False, udt=True)
4193
4194            if (
4195                other.expressions
4196                or self.this == DataType.Type.USERDEFINED
4197                or other.this == DataType.Type.USERDEFINED
4198            ):
4199                matches = self == other
4200            else:
4201                matches = self.this == other.this
4202
4203            if matches:
4204                return True
4205        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):
3945    class Type(AutoName):
3946        ARRAY = auto()
3947        AGGREGATEFUNCTION = auto()
3948        SIMPLEAGGREGATEFUNCTION = auto()
3949        BIGDECIMAL = auto()
3950        BIGINT = auto()
3951        BIGSERIAL = auto()
3952        BINARY = auto()
3953        BIT = auto()
3954        BOOLEAN = auto()
3955        BPCHAR = auto()
3956        CHAR = auto()
3957        DATE = auto()
3958        DATE32 = auto()
3959        DATEMULTIRANGE = auto()
3960        DATERANGE = auto()
3961        DATETIME = auto()
3962        DATETIME64 = auto()
3963        DECIMAL = auto()
3964        DOUBLE = auto()
3965        ENUM = auto()
3966        ENUM8 = auto()
3967        ENUM16 = auto()
3968        FIXEDSTRING = auto()
3969        FLOAT = auto()
3970        GEOGRAPHY = auto()
3971        GEOMETRY = auto()
3972        HLLSKETCH = auto()
3973        HSTORE = auto()
3974        IMAGE = auto()
3975        INET = auto()
3976        INT = auto()
3977        INT128 = auto()
3978        INT256 = auto()
3979        INT4MULTIRANGE = auto()
3980        INT4RANGE = auto()
3981        INT8MULTIRANGE = auto()
3982        INT8RANGE = auto()
3983        INTERVAL = auto()
3984        IPADDRESS = auto()
3985        IPPREFIX = auto()
3986        IPV4 = auto()
3987        IPV6 = auto()
3988        JSON = auto()
3989        JSONB = auto()
3990        LIST = auto()
3991        LONGBLOB = auto()
3992        LONGTEXT = auto()
3993        LOWCARDINALITY = auto()
3994        MAP = auto()
3995        MEDIUMBLOB = auto()
3996        MEDIUMINT = auto()
3997        MEDIUMTEXT = auto()
3998        MONEY = auto()
3999        NAME = auto()
4000        NCHAR = auto()
4001        NESTED = auto()
4002        NULL = auto()
4003        NULLABLE = auto()
4004        NUMMULTIRANGE = auto()
4005        NUMRANGE = auto()
4006        NVARCHAR = auto()
4007        OBJECT = auto()
4008        ROWVERSION = auto()
4009        SERIAL = auto()
4010        SET = auto()
4011        SMALLINT = auto()
4012        SMALLMONEY = auto()
4013        SMALLSERIAL = auto()
4014        STRUCT = auto()
4015        SUPER = auto()
4016        TEXT = auto()
4017        TINYBLOB = auto()
4018        TINYTEXT = auto()
4019        TIME = auto()
4020        TIMETZ = auto()
4021        TIMESTAMP = auto()
4022        TIMESTAMPNTZ = auto()
4023        TIMESTAMPLTZ = auto()
4024        TIMESTAMPTZ = auto()
4025        TIMESTAMP_S = auto()
4026        TIMESTAMP_MS = auto()
4027        TIMESTAMP_NS = auto()
4028        TINYINT = auto()
4029        TSMULTIRANGE = auto()
4030        TSRANGE = auto()
4031        TSTZMULTIRANGE = auto()
4032        TSTZRANGE = auto()
4033        UBIGINT = auto()
4034        UINT = auto()
4035        UINT128 = auto()
4036        UINT256 = auto()
4037        UMEDIUMINT = auto()
4038        UDECIMAL = auto()
4039        UNIQUEIDENTIFIER = auto()
4040        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4041        USERDEFINED = "USER-DEFINED"
4042        USMALLINT = auto()
4043        UTINYINT = auto()
4044        UUID = auto()
4045        VARBINARY = auto()
4046        VARCHAR = auto()
4047        VARIANT = auto()
4048        XML = auto()
4049        YEAR = auto()
4050        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'>
LIST = <Type.LIST: 'LIST'>
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):
4212class PseudoType(DataType):
4213    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4217class ObjectIdentifier(DataType):
4218    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4222class SubqueryPredicate(Predicate):
4223    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4226class All(SubqueryPredicate):
4227    pass
key = 'all'
class Any(SubqueryPredicate):
4230class Any(SubqueryPredicate):
4231    pass
key = 'any'
class Exists(SubqueryPredicate):
4234class Exists(SubqueryPredicate):
4235    pass
key = 'exists'
class Command(Expression):
4240class Command(Expression):
4241    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4244class Transaction(Expression):
4245    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4248class Commit(Expression):
4249    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4252class Rollback(Expression):
4253    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4256class AlterTable(Expression):
4257    arg_types = {
4258        "this": True,
4259        "actions": True,
4260        "exists": False,
4261        "only": False,
4262        "options": False,
4263        "cluster": False,
4264    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False}
key = 'altertable'
class AddConstraint(Expression):
4267class AddConstraint(Expression):
4268    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4271class DropPartition(Expression):
4272    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4276class ReplacePartition(Expression):
4277    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4281class Binary(Condition):
4282    arg_types = {"this": True, "expression": True}
4283
4284    @property
4285    def left(self) -> Expression:
4286        return self.this
4287
4288    @property
4289    def right(self) -> Expression:
4290        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4284    @property
4285    def left(self) -> Expression:
4286        return self.this
right: Expression
4288    @property
4289    def right(self) -> Expression:
4290        return self.expression
key = 'binary'
class Add(Binary):
4293class Add(Binary):
4294    pass
key = 'add'
class Connector(Binary):
4297class Connector(Binary):
4298    pass
key = 'connector'
class And(Connector):
4301class And(Connector):
4302    pass
key = 'and'
class Or(Connector):
4305class Or(Connector):
4306    pass
key = 'or'
class BitwiseAnd(Binary):
4309class BitwiseAnd(Binary):
4310    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4313class BitwiseLeftShift(Binary):
4314    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4317class BitwiseOr(Binary):
4318    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4321class BitwiseRightShift(Binary):
4322    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4325class BitwiseXor(Binary):
4326    pass
key = 'bitwisexor'
class Div(Binary):
4329class Div(Binary):
4330    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):
4333class Overlaps(Binary):
4334    pass
key = 'overlaps'
class Dot(Binary):
4337class Dot(Binary):
4338    @property
4339    def is_star(self) -> bool:
4340        return self.expression.is_star
4341
4342    @property
4343    def name(self) -> str:
4344        return self.expression.name
4345
4346    @property
4347    def output_name(self) -> str:
4348        return self.name
4349
4350    @classmethod
4351    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4352        """Build a Dot object with a sequence of expressions."""
4353        if len(expressions) < 2:
4354            raise ValueError("Dot requires >= 2 expressions.")
4355
4356        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4357
4358    @property
4359    def parts(self) -> t.List[Expression]:
4360        """Return the parts of a table / column in order catalog, db, table."""
4361        this, *parts = self.flatten()
4362
4363        parts.reverse()
4364
4365        for arg in COLUMN_PARTS:
4366            part = this.args.get(arg)
4367
4368            if isinstance(part, Expression):
4369                parts.append(part)
4370
4371        parts.reverse()
4372        return parts
is_star: bool
4338    @property
4339    def is_star(self) -> bool:
4340        return self.expression.is_star

Checks whether an expression is a star.

name: str
4342    @property
4343    def name(self) -> str:
4344        return self.expression.name
output_name: str
4346    @property
4347    def output_name(self) -> str:
4348        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:
4350    @classmethod
4351    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4352        """Build a Dot object with a sequence of expressions."""
4353        if len(expressions) < 2:
4354            raise ValueError("Dot requires >= 2 expressions.")
4355
4356        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]
4358    @property
4359    def parts(self) -> t.List[Expression]:
4360        """Return the parts of a table / column in order catalog, db, table."""
4361        this, *parts = self.flatten()
4362
4363        parts.reverse()
4364
4365        for arg in COLUMN_PARTS:
4366            part = this.args.get(arg)
4367
4368            if isinstance(part, Expression):
4369                parts.append(part)
4370
4371        parts.reverse()
4372        return parts

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

key = 'dot'
class DPipe(Binary):
4375class DPipe(Binary):
4376    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4379class EQ(Binary, Predicate):
4380    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4383class NullSafeEQ(Binary, Predicate):
4384    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4387class NullSafeNEQ(Binary, Predicate):
4388    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4392class PropertyEQ(Binary):
4393    pass
key = 'propertyeq'
class Distance(Binary):
4396class Distance(Binary):
4397    pass
key = 'distance'
class Escape(Binary):
4400class Escape(Binary):
4401    pass
key = 'escape'
class Glob(Binary, Predicate):
4404class Glob(Binary, Predicate):
4405    pass
key = 'glob'
class GT(Binary, Predicate):
4408class GT(Binary, Predicate):
4409    pass
key = 'gt'
class GTE(Binary, Predicate):
4412class GTE(Binary, Predicate):
4413    pass
key = 'gte'
class ILike(Binary, Predicate):
4416class ILike(Binary, Predicate):
4417    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4420class ILikeAny(Binary, Predicate):
4421    pass
key = 'ilikeany'
class IntDiv(Binary):
4424class IntDiv(Binary):
4425    pass
key = 'intdiv'
class Is(Binary, Predicate):
4428class Is(Binary, Predicate):
4429    pass
key = 'is'
class Kwarg(Binary):
4432class Kwarg(Binary):
4433    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4436class Like(Binary, Predicate):
4437    pass
key = 'like'
class LikeAny(Binary, Predicate):
4440class LikeAny(Binary, Predicate):
4441    pass
key = 'likeany'
class LT(Binary, Predicate):
4444class LT(Binary, Predicate):
4445    pass
key = 'lt'
class LTE(Binary, Predicate):
4448class LTE(Binary, Predicate):
4449    pass
key = 'lte'
class Mod(Binary):
4452class Mod(Binary):
4453    pass
key = 'mod'
class Mul(Binary):
4456class Mul(Binary):
4457    pass
key = 'mul'
class NEQ(Binary, Predicate):
4460class NEQ(Binary, Predicate):
4461    pass
key = 'neq'
class Operator(Binary):
4465class Operator(Binary):
4466    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4469class SimilarTo(Binary, Predicate):
4470    pass
key = 'similarto'
class Slice(Binary):
4473class Slice(Binary):
4474    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4477class Sub(Binary):
4478    pass
key = 'sub'
class Unary(Condition):
4483class Unary(Condition):
4484    pass
key = 'unary'
class BitwiseNot(Unary):
4487class BitwiseNot(Unary):
4488    pass
key = 'bitwisenot'
class Not(Unary):
4491class Not(Unary):
4492    pass
key = 'not'
class Paren(Unary):
4495class Paren(Unary):
4496    @property
4497    def output_name(self) -> str:
4498        return self.this.name
output_name: str
4496    @property
4497    def output_name(self) -> str:
4498        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):
4501class Neg(Unary):
4502    def to_py(self) -> int | Decimal:
4503        if self.is_number:
4504            return self.this.to_py() * -1
4505        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4502    def to_py(self) -> int | Decimal:
4503        if self.is_number:
4504            return self.this.to_py() * -1
4505        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4508class Alias(Expression):
4509    arg_types = {"this": True, "alias": False}
4510
4511    @property
4512    def output_name(self) -> str:
4513        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4511    @property
4512    def output_name(self) -> str:
4513        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):
4518class PivotAlias(Alias):
4519    pass
key = 'pivotalias'
class Aliases(Expression):
4522class Aliases(Expression):
4523    arg_types = {"this": True, "expressions": True}
4524
4525    @property
4526    def aliases(self):
4527        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4525    @property
4526    def aliases(self):
4527        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4531class AtIndex(Expression):
4532    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4535class AtTimeZone(Expression):
4536    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4539class FromTimeZone(Expression):
4540    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4543class Between(Predicate):
4544    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4547class Bracket(Condition):
4548    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4549    arg_types = {
4550        "this": True,
4551        "expressions": True,
4552        "offset": False,
4553        "safe": False,
4554        "returns_list_for_maps": False,
4555    }
4556
4557    @property
4558    def output_name(self) -> str:
4559        if len(self.expressions) == 1:
4560            return self.expressions[0].output_name
4561
4562        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4557    @property
4558    def output_name(self) -> str:
4559        if len(self.expressions) == 1:
4560            return self.expressions[0].output_name
4561
4562        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):
4565class Distinct(Expression):
4566    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4569class In(Predicate):
4570    arg_types = {
4571        "this": True,
4572        "expressions": False,
4573        "query": False,
4574        "unnest": False,
4575        "field": False,
4576        "is_global": False,
4577    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4581class ForIn(Expression):
4582    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4585class TimeUnit(Expression):
4586    """Automatically converts unit arg into a var."""
4587
4588    arg_types = {"unit": False}
4589
4590    UNABBREVIATED_UNIT_NAME = {
4591        "D": "DAY",
4592        "H": "HOUR",
4593        "M": "MINUTE",
4594        "MS": "MILLISECOND",
4595        "NS": "NANOSECOND",
4596        "Q": "QUARTER",
4597        "S": "SECOND",
4598        "US": "MICROSECOND",
4599        "W": "WEEK",
4600        "Y": "YEAR",
4601    }
4602
4603    VAR_LIKE = (Column, Literal, Var)
4604
4605    def __init__(self, **args):
4606        unit = args.get("unit")
4607        if isinstance(unit, self.VAR_LIKE):
4608            args["unit"] = Var(
4609                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4610            )
4611        elif isinstance(unit, Week):
4612            unit.set("this", Var(this=unit.this.name.upper()))
4613
4614        super().__init__(**args)
4615
4616    @property
4617    def unit(self) -> t.Optional[Var | IntervalSpan]:
4618        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4605    def __init__(self, **args):
4606        unit = args.get("unit")
4607        if isinstance(unit, self.VAR_LIKE):
4608            args["unit"] = Var(
4609                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4610            )
4611        elif isinstance(unit, Week):
4612            unit.set("this", Var(this=unit.this.name.upper()))
4613
4614        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]
4616    @property
4617    def unit(self) -> t.Optional[Var | IntervalSpan]:
4618        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4621class IntervalOp(TimeUnit):
4622    arg_types = {"unit": True, "expression": True}
4623
4624    def interval(self):
4625        return Interval(
4626            this=self.expression.copy(),
4627            unit=self.unit.copy(),
4628        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4624    def interval(self):
4625        return Interval(
4626            this=self.expression.copy(),
4627            unit=self.unit.copy(),
4628        )
key = 'intervalop'
class IntervalSpan(DataType):
4634class IntervalSpan(DataType):
4635    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4638class Interval(TimeUnit):
4639    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4642class IgnoreNulls(Expression):
4643    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4646class RespectNulls(Expression):
4647    pass
key = 'respectnulls'
class HavingMax(Expression):
4651class HavingMax(Expression):
4652    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4656class Func(Condition):
4657    """
4658    The base class for all function expressions.
4659
4660    Attributes:
4661        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4662            treated as a variable length argument and the argument's value will be stored as a list.
4663        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4664            function expression. These values are used to map this node to a name during parsing as
4665            well as to provide the function's name during SQL string generation. By default the SQL
4666            name is set to the expression's class name transformed to snake case.
4667    """
4668
4669    is_var_len_args = False
4670
4671    @classmethod
4672    def from_arg_list(cls, args):
4673        if cls.is_var_len_args:
4674            all_arg_keys = list(cls.arg_types)
4675            # If this function supports variable length argument treat the last argument as such.
4676            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4677            num_non_var = len(non_var_len_arg_keys)
4678
4679            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4680            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4681        else:
4682            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4683
4684        return cls(**args_dict)
4685
4686    @classmethod
4687    def sql_names(cls):
4688        if cls is Func:
4689            raise NotImplementedError(
4690                "SQL name is only supported by concrete function implementations"
4691            )
4692        if "_sql_names" not in cls.__dict__:
4693            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4694        return cls._sql_names
4695
4696    @classmethod
4697    def sql_name(cls):
4698        return cls.sql_names()[0]
4699
4700    @classmethod
4701    def default_parser_mappings(cls):
4702        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):
4671    @classmethod
4672    def from_arg_list(cls, args):
4673        if cls.is_var_len_args:
4674            all_arg_keys = list(cls.arg_types)
4675            # If this function supports variable length argument treat the last argument as such.
4676            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4677            num_non_var = len(non_var_len_arg_keys)
4678
4679            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4680            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4681        else:
4682            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4683
4684        return cls(**args_dict)
@classmethod
def sql_names(cls):
4686    @classmethod
4687    def sql_names(cls):
4688        if cls is Func:
4689            raise NotImplementedError(
4690                "SQL name is only supported by concrete function implementations"
4691            )
4692        if "_sql_names" not in cls.__dict__:
4693            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4694        return cls._sql_names
@classmethod
def sql_name(cls):
4696    @classmethod
4697    def sql_name(cls):
4698        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4700    @classmethod
4701    def default_parser_mappings(cls):
4702        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4705class AggFunc(Func):
4706    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4709class ParameterizedAgg(AggFunc):
4710    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4713class Abs(Func):
4714    pass
key = 'abs'
class ArgMax(AggFunc):
4717class ArgMax(AggFunc):
4718    arg_types = {"this": True, "expression": True, "count": False}
4719    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4722class ArgMin(AggFunc):
4723    arg_types = {"this": True, "expression": True, "count": False}
4724    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4727class ApproxTopK(AggFunc):
4728    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4731class Flatten(Func):
4732    pass
key = 'flatten'
class Transform(Func):
4736class Transform(Func):
4737    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4740class Anonymous(Func):
4741    arg_types = {"this": True, "expressions": False}
4742    is_var_len_args = True
4743
4744    @property
4745    def name(self) -> str:
4746        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
4744    @property
4745    def name(self) -> str:
4746        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4749class AnonymousAggFunc(AggFunc):
4750    arg_types = {"this": True, "expressions": False}
4751    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4755class CombinedAggFunc(AnonymousAggFunc):
4756    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4759class CombinedParameterizedAgg(ParameterizedAgg):
4760    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):
4765class Hll(AggFunc):
4766    arg_types = {"this": True, "expressions": False}
4767    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4770class ApproxDistinct(AggFunc):
4771    arg_types = {"this": True, "accuracy": False}
4772    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4775class Array(Func):
4776    arg_types = {"expressions": False}
4777    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4781class ToArray(Func):
4782    pass
key = 'toarray'
class List(Func):
4786class List(Func):
4787    arg_types = {"expressions": False}
4788    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class ToChar(Func):
4793class ToChar(Func):
4794    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4799class ToNumber(Func):
4800    arg_types = {
4801        "this": True,
4802        "format": False,
4803        "nlsparam": False,
4804        "precision": False,
4805        "scale": False,
4806    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4810class Convert(Func):
4811    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4814class GenerateSeries(Func):
4815    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):
4818class ArrayAgg(AggFunc):
4819    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4822class ArrayUniqueAgg(AggFunc):
4823    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4826class ArrayAll(Func):
4827    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4831class ArrayAny(Func):
4832    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4835class ArrayConcat(Func):
4836    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4837    arg_types = {"this": True, "expressions": False}
4838    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4841class ArrayConstructCompact(Func):
4842    arg_types = {"expressions": True}
4843    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4846class ArrayContains(Binary, Func):
4847    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4850class ArrayContainsAll(Binary, Func):
4851    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4854class ArrayFilter(Func):
4855    arg_types = {"this": True, "expression": True}
4856    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4859class ArrayToString(Func):
4860    arg_types = {"this": True, "expression": True, "null": False}
4861    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4864class StringToArray(Func):
4865    arg_types = {"this": True, "expression": True, "null": False}
4866    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4869class ArrayOverlaps(Binary, Func):
4870    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4873class ArraySize(Func):
4874    arg_types = {"this": True, "expression": False}
4875    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4878class ArraySort(Func):
4879    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4882class ArraySum(Func):
4883    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4886class ArrayUnionAgg(AggFunc):
4887    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4890class Avg(AggFunc):
4891    pass
key = 'avg'
class AnyValue(AggFunc):
4894class AnyValue(AggFunc):
4895    pass
key = 'anyvalue'
class Lag(AggFunc):
4898class Lag(AggFunc):
4899    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4902class Lead(AggFunc):
4903    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4908class First(AggFunc):
4909    pass
key = 'first'
class Last(AggFunc):
4912class Last(AggFunc):
4913    pass
key = 'last'
class FirstValue(AggFunc):
4916class FirstValue(AggFunc):
4917    pass
key = 'firstvalue'
class LastValue(AggFunc):
4920class LastValue(AggFunc):
4921    pass
key = 'lastvalue'
class NthValue(AggFunc):
4924class NthValue(AggFunc):
4925    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4928class Case(Func):
4929    arg_types = {"this": False, "ifs": True, "default": False}
4930
4931    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4932        instance = maybe_copy(self, copy)
4933        instance.append(
4934            "ifs",
4935            If(
4936                this=maybe_parse(condition, copy=copy, **opts),
4937                true=maybe_parse(then, copy=copy, **opts),
4938            ),
4939        )
4940        return instance
4941
4942    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4943        instance = maybe_copy(self, copy)
4944        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4945        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:
4931    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4932        instance = maybe_copy(self, copy)
4933        instance.append(
4934            "ifs",
4935            If(
4936                this=maybe_parse(condition, copy=copy, **opts),
4937                true=maybe_parse(then, copy=copy, **opts),
4938            ),
4939        )
4940        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4942    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4943        instance = maybe_copy(self, copy)
4944        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4945        return instance
key = 'case'
class Cast(Func):
4948class Cast(Func):
4949    arg_types = {
4950        "this": True,
4951        "to": True,
4952        "format": False,
4953        "safe": False,
4954        "action": False,
4955    }
4956
4957    @property
4958    def name(self) -> str:
4959        return self.this.name
4960
4961    @property
4962    def to(self) -> DataType:
4963        return self.args["to"]
4964
4965    @property
4966    def output_name(self) -> str:
4967        return self.name
4968
4969    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4970        """
4971        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4972        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4973        array<int> != array<float>.
4974
4975        Args:
4976            dtypes: the data types to compare this Cast's DataType to.
4977
4978        Returns:
4979            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4980        """
4981        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4957    @property
4958    def name(self) -> str:
4959        return self.this.name
to: DataType
4961    @property
4962    def to(self) -> DataType:
4963        return self.args["to"]
output_name: str
4965    @property
4966    def output_name(self) -> str:
4967        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:
4969    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4970        """
4971        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4972        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4973        array<int> != array<float>.
4974
4975        Args:
4976            dtypes: the data types to compare this Cast's DataType to.
4977
4978        Returns:
4979            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4980        """
4981        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):
4984class TryCast(Cast):
4985    pass
key = 'trycast'
class Try(Func):
4988class Try(Func):
4989    pass
key = 'try'
class CastToStrType(Func):
4992class CastToStrType(Func):
4993    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
4996class Collate(Binary, Func):
4997    pass
key = 'collate'
class Ceil(Func):
5000class Ceil(Func):
5001    arg_types = {"this": True, "decimals": False}
5002    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5005class Coalesce(Func):
5006    arg_types = {"this": True, "expressions": False}
5007    is_var_len_args = True
5008    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5011class Chr(Func):
5012    arg_types = {"this": True, "charset": False, "expressions": False}
5013    is_var_len_args = True
5014    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5017class Concat(Func):
5018    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5019    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5022class ConcatWs(Concat):
5023    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5027class ConnectByRoot(Func):
5028    pass
key = 'connectbyroot'
class Count(AggFunc):
5031class Count(AggFunc):
5032    arg_types = {"this": False, "expressions": False}
5033    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5036class CountIf(AggFunc):
5037    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5041class Cbrt(Func):
5042    pass
key = 'cbrt'
class CurrentDate(Func):
5045class CurrentDate(Func):
5046    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5049class CurrentDatetime(Func):
5050    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5053class CurrentTime(Func):
5054    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5057class CurrentTimestamp(Func):
5058    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5061class CurrentUser(Func):
5062    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5065class DateAdd(Func, IntervalOp):
5066    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5069class DateSub(Func, IntervalOp):
5070    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5073class DateDiff(Func, TimeUnit):
5074    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5075    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5078class DateTrunc(Func):
5079    arg_types = {"unit": True, "this": True, "zone": False}
5080
5081    def __init__(self, **args):
5082        unit = args.get("unit")
5083        if isinstance(unit, TimeUnit.VAR_LIKE):
5084            args["unit"] = Literal.string(
5085                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5086            )
5087        elif isinstance(unit, Week):
5088            unit.set("this", Literal.string(unit.this.name.upper()))
5089
5090        super().__init__(**args)
5091
5092    @property
5093    def unit(self) -> Expression:
5094        return self.args["unit"]
DateTrunc(**args)
5081    def __init__(self, **args):
5082        unit = args.get("unit")
5083        if isinstance(unit, TimeUnit.VAR_LIKE):
5084            args["unit"] = Literal.string(
5085                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5086            )
5087        elif isinstance(unit, Week):
5088            unit.set("this", Literal.string(unit.this.name.upper()))
5089
5090        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5092    @property
5093    def unit(self) -> Expression:
5094        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5099class Datetime(Func):
5100    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5103class DatetimeAdd(Func, IntervalOp):
5104    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5107class DatetimeSub(Func, IntervalOp):
5108    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5111class DatetimeDiff(Func, TimeUnit):
5112    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5115class DatetimeTrunc(Func, TimeUnit):
5116    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5119class DayOfWeek(Func):
5120    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5123class DayOfMonth(Func):
5124    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5127class DayOfYear(Func):
5128    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5131class ToDays(Func):
5132    pass
key = 'todays'
class WeekOfYear(Func):
5135class WeekOfYear(Func):
5136    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5139class MonthsBetween(Func):
5140    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5143class LastDay(Func, TimeUnit):
5144    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5145    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5148class Extract(Func):
5149    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5152class Timestamp(Func):
5153    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5156class TimestampAdd(Func, TimeUnit):
5157    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5160class TimestampSub(Func, TimeUnit):
5161    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5164class TimestampDiff(Func, TimeUnit):
5165    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5166    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5169class TimestampTrunc(Func, TimeUnit):
5170    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5173class TimeAdd(Func, TimeUnit):
5174    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5177class TimeSub(Func, TimeUnit):
5178    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5181class TimeDiff(Func, TimeUnit):
5182    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5185class TimeTrunc(Func, TimeUnit):
5186    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5189class DateFromParts(Func):
5190    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5191    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5194class TimeFromParts(Func):
5195    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5196    arg_types = {
5197        "hour": True,
5198        "min": True,
5199        "sec": True,
5200        "nano": False,
5201        "fractions": False,
5202        "precision": False,
5203    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5206class DateStrToDate(Func):
5207    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5210class DateToDateStr(Func):
5211    pass
key = 'datetodatestr'
class DateToDi(Func):
5214class DateToDi(Func):
5215    pass
key = 'datetodi'
class Date(Func):
5219class Date(Func):
5220    arg_types = {"this": False, "zone": False, "expressions": False}
5221    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5224class Day(Func):
5225    pass
key = 'day'
class Decode(Func):
5228class Decode(Func):
5229    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5232class DiToDate(Func):
5233    pass
key = 'ditodate'
class Encode(Func):
5236class Encode(Func):
5237    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5240class Exp(Func):
5241    pass
key = 'exp'
class Explode(Func):
5245class Explode(Func):
5246    arg_types = {"this": True, "expressions": False}
5247    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5250class ExplodeOuter(Explode):
5251    pass
key = 'explodeouter'
class Posexplode(Explode):
5254class Posexplode(Explode):
5255    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5258class PosexplodeOuter(Posexplode, ExplodeOuter):
5259    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5262class Unnest(Func, UDTF):
5263    arg_types = {
5264        "expressions": True,
5265        "alias": False,
5266        "offset": False,
5267    }
5268
5269    @property
5270    def selects(self) -> t.List[Expression]:
5271        columns = super().selects
5272        offset = self.args.get("offset")
5273        if offset:
5274            columns = columns + [to_identifier("offset") if offset is True else offset]
5275        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5269    @property
5270    def selects(self) -> t.List[Expression]:
5271        columns = super().selects
5272        offset = self.args.get("offset")
5273        if offset:
5274            columns = columns + [to_identifier("offset") if offset is True else offset]
5275        return columns
key = 'unnest'
class Floor(Func):
5278class Floor(Func):
5279    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5282class FromBase64(Func):
5283    pass
key = 'frombase64'
class ToBase64(Func):
5286class ToBase64(Func):
5287    pass
key = 'tobase64'
class GapFill(Func):
5290class GapFill(Func):
5291    arg_types = {
5292        "this": True,
5293        "ts_column": True,
5294        "bucket_width": True,
5295        "partitioning_columns": False,
5296        "value_columns": False,
5297        "origin": False,
5298        "ignore_nulls": False,
5299    }
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):
5302class GenerateDateArray(Func):
5303    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5306class Greatest(Func):
5307    arg_types = {"this": True, "expressions": False}
5308    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5311class GroupConcat(AggFunc):
5312    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5315class Hex(Func):
5316    pass
key = 'hex'
class LowerHex(Hex):
5319class LowerHex(Hex):
5320    pass
key = 'lowerhex'
class Xor(Connector, Func):
5323class Xor(Connector, Func):
5324    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5327class If(Func):
5328    arg_types = {"this": True, "true": True, "false": False}
5329    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5332class Nullif(Func):
5333    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5336class Initcap(Func):
5337    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5340class IsNan(Func):
5341    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5344class IsInf(Func):
5345    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5348class JSONPath(Expression):
5349    arg_types = {"expressions": True}
5350
5351    @property
5352    def output_name(self) -> str:
5353        last_segment = self.expressions[-1].this
5354        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5351    @property
5352    def output_name(self) -> str:
5353        last_segment = self.expressions[-1].this
5354        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):
5357class JSONPathPart(Expression):
5358    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5361class JSONPathFilter(JSONPathPart):
5362    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5365class JSONPathKey(JSONPathPart):
5366    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5369class JSONPathRecursive(JSONPathPart):
5370    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5373class JSONPathRoot(JSONPathPart):
5374    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5377class JSONPathScript(JSONPathPart):
5378    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5381class JSONPathSlice(JSONPathPart):
5382    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5385class JSONPathSelector(JSONPathPart):
5386    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5389class JSONPathSubscript(JSONPathPart):
5390    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5393class JSONPathUnion(JSONPathPart):
5394    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5397class JSONPathWildcard(JSONPathPart):
5398    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5401class FormatJson(Expression):
5402    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5405class JSONKeyValue(Expression):
5406    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5409class JSONObject(Func):
5410    arg_types = {
5411        "expressions": False,
5412        "null_handling": False,
5413        "unique_keys": False,
5414        "return_type": False,
5415        "encoding": False,
5416    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5419class JSONObjectAgg(AggFunc):
5420    arg_types = {
5421        "expressions": False,
5422        "null_handling": False,
5423        "unique_keys": False,
5424        "return_type": False,
5425        "encoding": False,
5426    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5430class JSONArray(Func):
5431    arg_types = {
5432        "expressions": True,
5433        "null_handling": False,
5434        "return_type": False,
5435        "strict": False,
5436    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5440class JSONArrayAgg(Func):
5441    arg_types = {
5442        "this": True,
5443        "order": False,
5444        "null_handling": False,
5445        "return_type": False,
5446        "strict": False,
5447    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5452class JSONColumnDef(Expression):
5453    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):
5456class JSONSchema(Expression):
5457    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5461class JSONTable(Func):
5462    arg_types = {
5463        "this": True,
5464        "schema": True,
5465        "path": False,
5466        "error_handling": False,
5467        "empty_handling": False,
5468    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class OpenJSONColumnDef(Expression):
5471class OpenJSONColumnDef(Expression):
5472    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):
5475class OpenJSON(Func):
5476    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5479class JSONBContains(Binary, Func):
5480    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5483class JSONExtract(Binary, Func):
5484    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5485    _sql_names = ["JSON_EXTRACT"]
5486    is_var_len_args = True
5487
5488    @property
5489    def output_name(self) -> str:
5490        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
5488    @property
5489    def output_name(self) -> str:
5490        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):
5493class JSONExtractScalar(Binary, Func):
5494    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5495    _sql_names = ["JSON_EXTRACT_SCALAR"]
5496    is_var_len_args = True
5497
5498    @property
5499    def output_name(self) -> str:
5500        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
5498    @property
5499    def output_name(self) -> str:
5500        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):
5503class JSONBExtract(Binary, Func):
5504    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5507class JSONBExtractScalar(Binary, Func):
5508    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5511class JSONFormat(Func):
5512    arg_types = {"this": False, "options": False}
5513    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5517class JSONArrayContains(Binary, Predicate, Func):
5518    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5521class ParseJSON(Func):
5522    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5523    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5524    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5525    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5528class Least(Func):
5529    arg_types = {"this": True, "expressions": False}
5530    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5533class Left(Func):
5534    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5541class Length(Func):
5542    arg_types = {"this": True, "binary": False}
5543    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5546class Levenshtein(Func):
5547    arg_types = {
5548        "this": True,
5549        "expression": False,
5550        "ins_cost": False,
5551        "del_cost": False,
5552        "sub_cost": False,
5553    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5556class Ln(Func):
5557    pass
key = 'ln'
class Log(Func):
5560class Log(Func):
5561    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5564class LogicalOr(AggFunc):
5565    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5568class LogicalAnd(AggFunc):
5569    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5572class Lower(Func):
5573    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5576class Map(Func):
5577    arg_types = {"keys": False, "values": False}
5578
5579    @property
5580    def keys(self) -> t.List[Expression]:
5581        keys = self.args.get("keys")
5582        return keys.expressions if keys else []
5583
5584    @property
5585    def values(self) -> t.List[Expression]:
5586        values = self.args.get("values")
5587        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5579    @property
5580    def keys(self) -> t.List[Expression]:
5581        keys = self.args.get("keys")
5582        return keys.expressions if keys else []
values: List[Expression]
5584    @property
5585    def values(self) -> t.List[Expression]:
5586        values = self.args.get("values")
5587        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5591class ToMap(Func):
5592    pass
key = 'tomap'
class MapFromEntries(Func):
5595class MapFromEntries(Func):
5596    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5600class ScopeResolution(Expression):
5601    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class StarMap(Func):
5604class StarMap(Func):
5605    pass
key = 'starmap'
class VarMap(Func):
5608class VarMap(Func):
5609    arg_types = {"keys": True, "values": True}
5610    is_var_len_args = True
5611
5612    @property
5613    def keys(self) -> t.List[Expression]:
5614        return self.args["keys"].expressions
5615
5616    @property
5617    def values(self) -> t.List[Expression]:
5618        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5612    @property
5613    def keys(self) -> t.List[Expression]:
5614        return self.args["keys"].expressions
values: List[Expression]
5616    @property
5617    def values(self) -> t.List[Expression]:
5618        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5622class MatchAgainst(Func):
5623    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5626class Max(AggFunc):
5627    arg_types = {"this": True, "expressions": False}
5628    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5631class MD5(Func):
5632    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5636class MD5Digest(Func):
5637    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5640class Min(AggFunc):
5641    arg_types = {"this": True, "expressions": False}
5642    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5645class Month(Func):
5646    pass
key = 'month'
class AddMonths(Func):
5649class AddMonths(Func):
5650    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5653class Nvl2(Func):
5654    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5658class Predict(Func):
5659    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5662class Pow(Binary, Func):
5663    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5666class PercentileCont(AggFunc):
5667    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5670class PercentileDisc(AggFunc):
5671    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5674class Quantile(AggFunc):
5675    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5678class ApproxQuantile(Quantile):
5679    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):
5682class Quarter(Func):
5683    pass
key = 'quarter'
class Rand(Func):
5686class Rand(Func):
5687    _sql_names = ["RAND", "RANDOM"]
5688    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rand'
class Randn(Func):
5691class Randn(Func):
5692    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5695class RangeN(Func):
5696    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5699class ReadCSV(Func):
5700    _sql_names = ["READ_CSV"]
5701    is_var_len_args = True
5702    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5705class Reduce(Func):
5706    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):
5709class RegexpExtract(Func):
5710    arg_types = {
5711        "this": True,
5712        "expression": True,
5713        "position": False,
5714        "occurrence": False,
5715        "parameters": False,
5716        "group": False,
5717    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5720class RegexpReplace(Func):
5721    arg_types = {
5722        "this": True,
5723        "expression": True,
5724        "replacement": False,
5725        "position": False,
5726        "occurrence": False,
5727        "modifiers": False,
5728    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5731class RegexpLike(Binary, Func):
5732    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5735class RegexpILike(Binary, Func):
5736    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5741class RegexpSplit(Func):
5742    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5745class Repeat(Func):
5746    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5751class Round(Func):
5752    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5755class RowNumber(Func):
5756    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5759class SafeDivide(Func):
5760    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5763class SHA(Func):
5764    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5767class SHA2(Func):
5768    _sql_names = ["SHA2"]
5769    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5772class Sign(Func):
5773    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5776class SortArray(Func):
5777    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5780class Split(Func):
5781    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5786class Substring(Func):
5787    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5790class StandardHash(Func):
5791    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5794class StartsWith(Func):
5795    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5796    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5799class StrPosition(Func):
5800    arg_types = {
5801        "this": True,
5802        "substr": True,
5803        "position": False,
5804        "instance": False,
5805    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5808class StrToDate(Func):
5809    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
5812class StrToTime(Func):
5813    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
arg_types = {'this': True, 'format': True, 'zone': False, 'safe': False}
key = 'strtotime'
class StrToUnix(Func):
5818class StrToUnix(Func):
5819    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5824class StrToMap(Func):
5825    arg_types = {
5826        "this": True,
5827        "pair_delim": False,
5828        "key_value_delim": False,
5829        "duplicate_resolution_callback": False,
5830    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5833class NumberToStr(Func):
5834    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5837class FromBase(Func):
5838    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5841class Struct(Func):
5842    arg_types = {"expressions": False}
5843    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5846class StructExtract(Func):
5847    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5852class Stuff(Func):
5853    _sql_names = ["STUFF", "INSERT"]
5854    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):
5857class Sum(AggFunc):
5858    pass
key = 'sum'
class Sqrt(Func):
5861class Sqrt(Func):
5862    pass
key = 'sqrt'
class Stddev(AggFunc):
5865class Stddev(AggFunc):
5866    pass
key = 'stddev'
class StddevPop(AggFunc):
5869class StddevPop(AggFunc):
5870    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5873class StddevSamp(AggFunc):
5874    pass
key = 'stddevsamp'
class Time(Func):
5878class Time(Func):
5879    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
5882class TimeToStr(Func):
5883    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):
5886class TimeToTimeStr(Func):
5887    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5890class TimeToUnix(Func):
5891    pass
key = 'timetounix'
class TimeStrToDate(Func):
5894class TimeStrToDate(Func):
5895    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5898class TimeStrToTime(Func):
5899    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5902class TimeStrToUnix(Func):
5903    pass
key = 'timestrtounix'
class Trim(Func):
5906class Trim(Func):
5907    arg_types = {
5908        "this": True,
5909        "expression": False,
5910        "position": False,
5911        "collation": False,
5912    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5915class TsOrDsAdd(Func, TimeUnit):
5916    # return_type is used to correctly cast the arguments of this expression when transpiling it
5917    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5918
5919    @property
5920    def return_type(self) -> DataType:
5921        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
5919    @property
5920    def return_type(self) -> DataType:
5921        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5924class TsOrDsDiff(Func, TimeUnit):
5925    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5928class TsOrDsToDateStr(Func):
5929    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5932class TsOrDsToDate(Func):
5933    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5936class TsOrDsToTime(Func):
5937    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5940class TsOrDsToTimestamp(Func):
5941    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5944class TsOrDiToDi(Func):
5945    pass
key = 'tsorditodi'
class Unhex(Func):
5948class Unhex(Func):
5949    pass
key = 'unhex'
class UnixDate(Func):
5953class UnixDate(Func):
5954    pass
key = 'unixdate'
class UnixToStr(Func):
5957class UnixToStr(Func):
5958    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5963class UnixToTime(Func):
5964    arg_types = {
5965        "this": True,
5966        "scale": False,
5967        "zone": False,
5968        "hours": False,
5969        "minutes": False,
5970        "format": False,
5971    }
5972
5973    SECONDS = Literal.number(0)
5974    DECIS = Literal.number(1)
5975    CENTIS = Literal.number(2)
5976    MILLIS = Literal.number(3)
5977    DECIMILLIS = Literal.number(4)
5978    CENTIMILLIS = Literal.number(5)
5979    MICROS = Literal.number(6)
5980    DECIMICROS = Literal.number(7)
5981    CENTIMICROS = Literal.number(8)
5982    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):
5985class UnixToTimeStr(Func):
5986    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
5989class TimestampFromParts(Func):
5990    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
5991    arg_types = {
5992        "year": True,
5993        "month": True,
5994        "day": True,
5995        "hour": True,
5996        "min": True,
5997        "sec": True,
5998        "nano": False,
5999        "zone": False,
6000        "milli": False,
6001    }
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):
6004class Upper(Func):
6005    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6008class Corr(Binary, AggFunc):
6009    pass
key = 'corr'
class Variance(AggFunc):
6012class Variance(AggFunc):
6013    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6016class VariancePop(AggFunc):
6017    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6020class CovarSamp(Binary, AggFunc):
6021    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6024class CovarPop(Binary, AggFunc):
6025    pass
key = 'covarpop'
class Week(Func):
6028class Week(Func):
6029    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6032class XMLTable(Func):
6033    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):
6036class Year(Func):
6037    pass
key = 'year'
class Use(Expression):
6040class Use(Expression):
6041    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6044class Merge(Expression):
6045    arg_types = {
6046        "this": True,
6047        "using": True,
6048        "on": True,
6049        "expressions": True,
6050        "with": False,
6051    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6054class When(Func):
6055    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):
6060class NextValueFor(Func):
6061    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6066class Semicolon(Expression):
6067    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 'Datetime'>, <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 'JSONBContains'>, <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 'List'>, <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 'Time'>, <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 'Unnest'>, <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': <class 'Datetime'>, '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_CONTAINS': <class 'JSONBContains'>, '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'>, 'LIST': <class 'List'>, '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': <class 'Time'>, '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'>, 'UNNEST': <class 'Unnest'>, '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:
6107def maybe_parse(
6108    sql_or_expression: ExpOrStr,
6109    *,
6110    into: t.Optional[IntoType] = None,
6111    dialect: DialectType = None,
6112    prefix: t.Optional[str] = None,
6113    copy: bool = False,
6114    **opts,
6115) -> Expression:
6116    """Gracefully handle a possible string or expression.
6117
6118    Example:
6119        >>> maybe_parse("1")
6120        Literal(this=1, is_string=False)
6121        >>> maybe_parse(to_identifier("x"))
6122        Identifier(this=x, quoted=False)
6123
6124    Args:
6125        sql_or_expression: the SQL code string or an expression
6126        into: the SQLGlot Expression to parse into
6127        dialect: the dialect used to parse the input expressions (in the case that an
6128            input expression is a SQL string).
6129        prefix: a string to prefix the sql with before it gets parsed
6130            (automatically includes a space)
6131        copy: whether to copy the expression.
6132        **opts: other options to use to parse the input expressions (again, in the case
6133            that an input expression is a SQL string).
6134
6135    Returns:
6136        Expression: the parsed or given expression.
6137    """
6138    if isinstance(sql_or_expression, Expression):
6139        if copy:
6140            return sql_or_expression.copy()
6141        return sql_or_expression
6142
6143    if sql_or_expression is None:
6144        raise ParseError("SQL cannot be None")
6145
6146    import sqlglot
6147
6148    sql = str(sql_or_expression)
6149    if prefix:
6150        sql = f"{prefix} {sql}"
6151
6152    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):
6163def maybe_copy(instance, copy=True):
6164    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:
6384def union(
6385    left: ExpOrStr,
6386    right: ExpOrStr,
6387    distinct: bool = True,
6388    dialect: DialectType = None,
6389    copy: bool = True,
6390    **opts,
6391) -> Union:
6392    """
6393    Initializes a syntax tree from one UNION expression.
6394
6395    Example:
6396        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6397        'SELECT * FROM foo UNION SELECT * FROM bla'
6398
6399    Args:
6400        left: the SQL code string corresponding to the left-hand side.
6401            If an `Expression` instance is passed, it will be used as-is.
6402        right: the SQL code string corresponding to the right-hand side.
6403            If an `Expression` instance is passed, it will be used as-is.
6404        distinct: set the DISTINCT flag if and only if this is true.
6405        dialect: the dialect used to parse the input expression.
6406        copy: whether to copy the expression.
6407        opts: other options to use to parse the input expressions.
6408
6409    Returns:
6410        The new Union instance.
6411    """
6412    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6413    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6414
6415    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:
6418def intersect(
6419    left: ExpOrStr,
6420    right: ExpOrStr,
6421    distinct: bool = True,
6422    dialect: DialectType = None,
6423    copy: bool = True,
6424    **opts,
6425) -> Intersect:
6426    """
6427    Initializes a syntax tree from one INTERSECT expression.
6428
6429    Example:
6430        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6431        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6432
6433    Args:
6434        left: the SQL code string corresponding to the left-hand side.
6435            If an `Expression` instance is passed, it will be used as-is.
6436        right: the SQL code string corresponding to the right-hand side.
6437            If an `Expression` instance is passed, it will be used as-is.
6438        distinct: set the DISTINCT flag if and only if this is true.
6439        dialect: the dialect used to parse the input expression.
6440        copy: whether to copy the expression.
6441        opts: other options to use to parse the input expressions.
6442
6443    Returns:
6444        The new Intersect instance.
6445    """
6446    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6447    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6448
6449    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:
6452def except_(
6453    left: ExpOrStr,
6454    right: ExpOrStr,
6455    distinct: bool = True,
6456    dialect: DialectType = None,
6457    copy: bool = True,
6458    **opts,
6459) -> Except:
6460    """
6461    Initializes a syntax tree from one EXCEPT expression.
6462
6463    Example:
6464        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6465        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6466
6467    Args:
6468        left: the SQL code string corresponding to the left-hand side.
6469            If an `Expression` instance is passed, it will be used as-is.
6470        right: the SQL code string corresponding to the right-hand side.
6471            If an `Expression` instance is passed, it will be used as-is.
6472        distinct: set the DISTINCT flag if and only if this is true.
6473        dialect: the dialect used to parse the input expression.
6474        copy: whether to copy the expression.
6475        opts: other options to use to parse the input expressions.
6476
6477    Returns:
6478        The new Except instance.
6479    """
6480    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6481    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6482
6483    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:
6486def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6487    """
6488    Initializes a syntax tree from one or multiple SELECT expressions.
6489
6490    Example:
6491        >>> select("col1", "col2").from_("tbl").sql()
6492        'SELECT col1, col2 FROM tbl'
6493
6494    Args:
6495        *expressions: the SQL code string to parse as the expressions of a
6496            SELECT statement. If an Expression instance is passed, this is used as-is.
6497        dialect: the dialect used to parse the input expressions (in the case that an
6498            input expression is a SQL string).
6499        **opts: other options to use to parse the input expressions (again, in the case
6500            that an input expression is a SQL string).
6501
6502    Returns:
6503        Select: the syntax tree for the SELECT statement.
6504    """
6505    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:
6508def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6509    """
6510    Initializes a syntax tree from a FROM expression.
6511
6512    Example:
6513        >>> from_("tbl").select("col1", "col2").sql()
6514        'SELECT col1, col2 FROM tbl'
6515
6516    Args:
6517        *expression: the SQL code string to parse as the FROM expressions of a
6518            SELECT statement. If an Expression instance is passed, this is used as-is.
6519        dialect: the dialect used to parse the input expression (in the case that the
6520            input expression is a SQL string).
6521        **opts: other options to use to parse the input expressions (again, in the case
6522            that the input expression is a SQL string).
6523
6524    Returns:
6525        Select: the syntax tree for the SELECT statement.
6526    """
6527    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:
6530def update(
6531    table: str | Table,
6532    properties: dict,
6533    where: t.Optional[ExpOrStr] = None,
6534    from_: t.Optional[ExpOrStr] = None,
6535    dialect: DialectType = None,
6536    **opts,
6537) -> Update:
6538    """
6539    Creates an update statement.
6540
6541    Example:
6542        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6543        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6544
6545    Args:
6546        *properties: dictionary of properties to set which are
6547            auto converted to sql objects eg None -> NULL
6548        where: sql conditional parsed into a WHERE statement
6549        from_: sql statement parsed into a FROM statement
6550        dialect: the dialect used to parse the input expressions.
6551        **opts: other options to use to parse the input expressions.
6552
6553    Returns:
6554        Update: the syntax tree for the UPDATE statement.
6555    """
6556    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6557    update_expr.set(
6558        "expressions",
6559        [
6560            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6561            for k, v in properties.items()
6562        ],
6563    )
6564    if from_:
6565        update_expr.set(
6566            "from",
6567            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6568        )
6569    if isinstance(where, Condition):
6570        where = Where(this=where)
6571    if where:
6572        update_expr.set(
6573            "where",
6574            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6575        )
6576    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:
6579def delete(
6580    table: ExpOrStr,
6581    where: t.Optional[ExpOrStr] = None,
6582    returning: t.Optional[ExpOrStr] = None,
6583    dialect: DialectType = None,
6584    **opts,
6585) -> Delete:
6586    """
6587    Builds a delete statement.
6588
6589    Example:
6590        >>> delete("my_table", where="id > 1").sql()
6591        'DELETE FROM my_table WHERE id > 1'
6592
6593    Args:
6594        where: sql conditional parsed into a WHERE statement
6595        returning: sql conditional parsed into a RETURNING statement
6596        dialect: the dialect used to parse the input expressions.
6597        **opts: other options to use to parse the input expressions.
6598
6599    Returns:
6600        Delete: the syntax tree for the DELETE statement.
6601    """
6602    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6603    if where:
6604        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6605    if returning:
6606        delete_expr = t.cast(
6607            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6608        )
6609    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:
6612def insert(
6613    expression: ExpOrStr,
6614    into: ExpOrStr,
6615    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6616    overwrite: t.Optional[bool] = None,
6617    returning: t.Optional[ExpOrStr] = None,
6618    dialect: DialectType = None,
6619    copy: bool = True,
6620    **opts,
6621) -> Insert:
6622    """
6623    Builds an INSERT statement.
6624
6625    Example:
6626        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6627        'INSERT INTO tbl VALUES (1, 2, 3)'
6628
6629    Args:
6630        expression: the sql string or expression of the INSERT statement
6631        into: the tbl to insert data to.
6632        columns: optionally the table's column names.
6633        overwrite: whether to INSERT OVERWRITE or not.
6634        returning: sql conditional parsed into a RETURNING statement
6635        dialect: the dialect used to parse the input expressions.
6636        copy: whether to copy the expression.
6637        **opts: other options to use to parse the input expressions.
6638
6639    Returns:
6640        Insert: the syntax tree for the INSERT statement.
6641    """
6642    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6643    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6644
6645    if columns:
6646        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6647
6648    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6649
6650    if returning:
6651        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6652
6653    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:
6656def condition(
6657    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6658) -> Condition:
6659    """
6660    Initialize a logical condition expression.
6661
6662    Example:
6663        >>> condition("x=1").sql()
6664        'x = 1'
6665
6666        This is helpful for composing larger logical syntax trees:
6667        >>> where = condition("x=1")
6668        >>> where = where.and_("y=1")
6669        >>> Select().from_("tbl").select("*").where(where).sql()
6670        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6671
6672    Args:
6673        *expression: the SQL code string to parse.
6674            If an Expression instance is passed, this is used as-is.
6675        dialect: the dialect used to parse the input expression (in the case that the
6676            input expression is a SQL string).
6677        copy: Whether to copy `expression` (only applies to expressions).
6678        **opts: other options to use to parse the input expressions (again, in the case
6679            that the input expression is a SQL string).
6680
6681    Returns:
6682        The new Condition instance
6683    """
6684    return maybe_parse(
6685        expression,
6686        into=Condition,
6687        dialect=dialect,
6688        copy=copy,
6689        **opts,
6690    )

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:
6693def and_(
6694    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6695) -> Condition:
6696    """
6697    Combine multiple conditions with an AND logical operator.
6698
6699    Example:
6700        >>> and_("x=1", and_("y=1", "z=1")).sql()
6701        'x = 1 AND (y = 1 AND z = 1)'
6702
6703    Args:
6704        *expressions: the SQL code strings to parse.
6705            If an Expression instance is passed, this is used as-is.
6706        dialect: the dialect used to parse the input expression.
6707        copy: whether to copy `expressions` (only applies to Expressions).
6708        **opts: other options to use to parse the input expressions.
6709
6710    Returns:
6711        The new condition
6712    """
6713    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:
6716def or_(
6717    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6718) -> Condition:
6719    """
6720    Combine multiple conditions with an OR logical operator.
6721
6722    Example:
6723        >>> or_("x=1", or_("y=1", "z=1")).sql()
6724        'x = 1 OR (y = 1 OR z = 1)'
6725
6726    Args:
6727        *expressions: the SQL code strings to parse.
6728            If an Expression instance is passed, this is used as-is.
6729        dialect: the dialect used to parse the input expression.
6730        copy: whether to copy `expressions` (only applies to Expressions).
6731        **opts: other options to use to parse the input expressions.
6732
6733    Returns:
6734        The new condition
6735    """
6736    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:
6739def xor(
6740    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6741) -> Condition:
6742    """
6743    Combine multiple conditions with an XOR logical operator.
6744
6745    Example:
6746        >>> xor("x=1", xor("y=1", "z=1")).sql()
6747        'x = 1 XOR (y = 1 XOR z = 1)'
6748
6749    Args:
6750        *expressions: the SQL code strings to parse.
6751            If an Expression instance is passed, this is used as-is.
6752        dialect: the dialect used to parse the input expression.
6753        copy: whether to copy `expressions` (only applies to Expressions).
6754        **opts: other options to use to parse the input expressions.
6755
6756    Returns:
6757        The new condition
6758    """
6759    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:
6762def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6763    """
6764    Wrap a condition with a NOT operator.
6765
6766    Example:
6767        >>> not_("this_suit='black'").sql()
6768        "NOT this_suit = 'black'"
6769
6770    Args:
6771        expression: the SQL code string to parse.
6772            If an Expression instance is passed, this is used as-is.
6773        dialect: the dialect used to parse the input expression.
6774        copy: whether to copy the expression or not.
6775        **opts: other options to use to parse the input expressions.
6776
6777    Returns:
6778        The new condition.
6779    """
6780    this = condition(
6781        expression,
6782        dialect=dialect,
6783        copy=copy,
6784        **opts,
6785    )
6786    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:
6789def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6790    """
6791    Wrap an expression in parentheses.
6792
6793    Example:
6794        >>> paren("5 + 3").sql()
6795        '(5 + 3)'
6796
6797    Args:
6798        expression: the SQL code string to parse.
6799            If an Expression instance is passed, this is used as-is.
6800        copy: whether to copy the expression or not.
6801
6802    Returns:
6803        The wrapped expression.
6804    """
6805    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):
6821def to_identifier(name, quoted=None, copy=True):
6822    """Builds an identifier.
6823
6824    Args:
6825        name: The name to turn into an identifier.
6826        quoted: Whether to force quote the identifier.
6827        copy: Whether to copy name if it's an Identifier.
6828
6829    Returns:
6830        The identifier ast node.
6831    """
6832
6833    if name is None:
6834        return None
6835
6836    if isinstance(name, Identifier):
6837        identifier = maybe_copy(name, copy)
6838    elif isinstance(name, str):
6839        identifier = Identifier(
6840            this=name,
6841            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6842        )
6843    else:
6844        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6845    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:
6848def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6849    """
6850    Parses a given string into an identifier.
6851
6852    Args:
6853        name: The name to parse into an identifier.
6854        dialect: The dialect to parse against.
6855
6856    Returns:
6857        The identifier ast node.
6858    """
6859    try:
6860        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6861    except ParseError:
6862        expression = to_identifier(name)
6863
6864    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:
6870def to_interval(interval: str | Literal) -> Interval:
6871    """Builds an interval expression from a string like '1 day' or '5 months'."""
6872    if isinstance(interval, Literal):
6873        if not interval.is_string:
6874            raise ValueError("Invalid interval string.")
6875
6876        interval = interval.this
6877
6878    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6879
6880    if not interval_parts:
6881        raise ValueError("Invalid interval string.")
6882
6883    return Interval(
6884        this=Literal.string(interval_parts.group(1)),
6885        unit=Var(this=interval_parts.group(2).upper()),
6886    )

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:
6889def to_table(
6890    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6891) -> Table:
6892    """
6893    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6894    If a table is passed in then that table is returned.
6895
6896    Args:
6897        sql_path: a `[catalog].[schema].[table]` string.
6898        dialect: the source dialect according to which the table name will be parsed.
6899        copy: Whether to copy a table if it is passed in.
6900        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6901
6902    Returns:
6903        A table expression.
6904    """
6905    if isinstance(sql_path, Table):
6906        return maybe_copy(sql_path, copy=copy)
6907
6908    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6909
6910    for k, v in kwargs.items():
6911        table.set(k, v)
6912
6913    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:
6916def to_column(
6917    sql_path: str | Column,
6918    quoted: t.Optional[bool] = None,
6919    dialect: DialectType = None,
6920    copy: bool = True,
6921    **kwargs,
6922) -> Column:
6923    """
6924    Create a column from a `[table].[column]` sql path. Table is optional.
6925    If a column is passed in then that column is returned.
6926
6927    Args:
6928        sql_path: a `[table].[column]` string.
6929        quoted: Whether or not to force quote identifiers.
6930        dialect: the source dialect according to which the column name will be parsed.
6931        copy: Whether to copy a column if it is passed in.
6932        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6933
6934    Returns:
6935        A column expression.
6936    """
6937    if isinstance(sql_path, Column):
6938        return maybe_copy(sql_path, copy=copy)
6939
6940    try:
6941        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6942    except ParseError:
6943        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6944
6945    for k, v in kwargs.items():
6946        col.set(k, v)
6947
6948    if quoted:
6949        for i in col.find_all(Identifier):
6950            i.set("quoted", True)
6951
6952    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):
6955def alias_(
6956    expression: ExpOrStr,
6957    alias: t.Optional[str | Identifier],
6958    table: bool | t.Sequence[str | Identifier] = False,
6959    quoted: t.Optional[bool] = None,
6960    dialect: DialectType = None,
6961    copy: bool = True,
6962    **opts,
6963):
6964    """Create an Alias expression.
6965
6966    Example:
6967        >>> alias_('foo', 'bar').sql()
6968        'foo AS bar'
6969
6970        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
6971        '(SELECT 1, 2) AS bar(a, b)'
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. If the name has
6977            special characters it is quoted.
6978        table: Whether to create a table alias, can also be a list of columns.
6979        quoted: whether to quote the alias
6980        dialect: the dialect used to parse the input expression.
6981        copy: Whether to copy the expression.
6982        **opts: other options to use to parse the input expressions.
6983
6984    Returns:
6985        Alias: the aliased expression
6986    """
6987    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6988    alias = to_identifier(alias, quoted=quoted)
6989
6990    if table:
6991        table_alias = TableAlias(this=alias)
6992        exp.set("alias", table_alias)
6993
6994        if not isinstance(table, bool):
6995            for column in table:
6996                table_alias.append("columns", to_identifier(column, quoted=quoted))
6997
6998        return exp
6999
7000    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7001    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7002    # for the complete Window expression.
7003    #
7004    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7005
7006    if "alias" in exp.arg_types and not isinstance(exp, Window):
7007        exp.set("alias", alias)
7008        return exp
7009    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:
7012def subquery(
7013    expression: ExpOrStr,
7014    alias: t.Optional[Identifier | str] = None,
7015    dialect: DialectType = None,
7016    **opts,
7017) -> Select:
7018    """
7019    Build a subquery expression that's selected from.
7020
7021    Example:
7022        >>> subquery('select x from tbl', 'bar').select('x').sql()
7023        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7024
7025    Args:
7026        expression: the SQL code strings to parse.
7027            If an Expression instance is passed, this is used as-is.
7028        alias: the alias name to use.
7029        dialect: the dialect used to parse the input expression.
7030        **opts: other options to use to parse the input expressions.
7031
7032    Returns:
7033        A new Select instance with the subquery expression included.
7034    """
7035
7036    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7037    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):
7068def column(
7069    col,
7070    table=None,
7071    db=None,
7072    catalog=None,
7073    *,
7074    fields=None,
7075    quoted=None,
7076    copy=True,
7077):
7078    """
7079    Build a Column.
7080
7081    Args:
7082        col: Column name.
7083        table: Table name.
7084        db: Database name.
7085        catalog: Catalog name.
7086        fields: Additional fields using dots.
7087        quoted: Whether to force quotes on the column's identifiers.
7088        copy: Whether to copy identifiers if passed in.
7089
7090    Returns:
7091        The new Column instance.
7092    """
7093    this = Column(
7094        this=to_identifier(col, quoted=quoted, copy=copy),
7095        table=to_identifier(table, quoted=quoted, copy=copy),
7096        db=to_identifier(db, quoted=quoted, copy=copy),
7097        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7098    )
7099
7100    if fields:
7101        this = Dot.build(
7102            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7103        )
7104    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:
7107def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7108    """Cast an expression to a data type.
7109
7110    Example:
7111        >>> cast('x + 1', 'int').sql()
7112        'CAST(x + 1 AS INT)'
7113
7114    Args:
7115        expression: The expression to cast.
7116        to: The datatype to cast to.
7117        copy: Whether to copy the supplied expressions.
7118
7119    Returns:
7120        The new Cast instance.
7121    """
7122    expr = maybe_parse(expression, copy=copy, **opts)
7123    data_type = DataType.build(to, copy=copy, **opts)
7124
7125    if expr.is_type(data_type):
7126        return expr
7127
7128    expr = Cast(this=expr, to=data_type)
7129    expr.type = data_type
7130
7131    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:
7134def table_(
7135    table: Identifier | str,
7136    db: t.Optional[Identifier | str] = None,
7137    catalog: t.Optional[Identifier | str] = None,
7138    quoted: t.Optional[bool] = None,
7139    alias: t.Optional[Identifier | str] = None,
7140) -> Table:
7141    """Build a Table.
7142
7143    Args:
7144        table: Table name.
7145        db: Database name.
7146        catalog: Catalog name.
7147        quote: Whether to force quotes on the table's identifiers.
7148        alias: Table's alias.
7149
7150    Returns:
7151        The new Table instance.
7152    """
7153    return Table(
7154        this=to_identifier(table, quoted=quoted) if table else None,
7155        db=to_identifier(db, quoted=quoted) if db else None,
7156        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7157        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7158    )

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:
7161def values(
7162    values: t.Iterable[t.Tuple[t.Any, ...]],
7163    alias: t.Optional[str] = None,
7164    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7165) -> Values:
7166    """Build VALUES statement.
7167
7168    Example:
7169        >>> values([(1, '2')]).sql()
7170        "VALUES (1, '2')"
7171
7172    Args:
7173        values: values statements that will be converted to SQL
7174        alias: optional alias
7175        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7176         If either are provided then an alias is also required.
7177
7178    Returns:
7179        Values: the Values expression object
7180    """
7181    if columns and not alias:
7182        raise ValueError("Alias is required when providing columns")
7183
7184    return Values(
7185        expressions=[convert(tup) for tup in values],
7186        alias=(
7187            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7188            if columns
7189            else (TableAlias(this=to_identifier(alias)) if alias else None)
7190        ),
7191    )

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:
7194def var(name: t.Optional[ExpOrStr]) -> Var:
7195    """Build a SQL variable.
7196
7197    Example:
7198        >>> repr(var('x'))
7199        'Var(this=x)'
7200
7201        >>> repr(var(column('x', table='y')))
7202        'Var(this=x)'
7203
7204    Args:
7205        name: The name of the var or an expression who's name will become the var.
7206
7207    Returns:
7208        The new variable node.
7209    """
7210    if not name:
7211        raise ValueError("Cannot convert empty name into var.")
7212
7213    if isinstance(name, Expression):
7214        name = name.name
7215    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:
7218def rename_table(
7219    old_name: str | Table,
7220    new_name: str | Table,
7221    dialect: DialectType = None,
7222) -> AlterTable:
7223    """Build ALTER TABLE... RENAME... expression
7224
7225    Args:
7226        old_name: The old name of the table
7227        new_name: The new name of the table
7228        dialect: The dialect to parse the table.
7229
7230    Returns:
7231        Alter table expression
7232    """
7233    old_table = to_table(old_name, dialect=dialect)
7234    new_table = to_table(new_name, dialect=dialect)
7235    return AlterTable(
7236        this=old_table,
7237        actions=[
7238            RenameTable(this=new_table),
7239        ],
7240    )

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:
7243def rename_column(
7244    table_name: str | Table,
7245    old_column_name: str | Column,
7246    new_column_name: str | Column,
7247    exists: t.Optional[bool] = None,
7248    dialect: DialectType = None,
7249) -> AlterTable:
7250    """Build ALTER TABLE... RENAME COLUMN... expression
7251
7252    Args:
7253        table_name: Name of the table
7254        old_column: The old name of the column
7255        new_column: The new name of the column
7256        exists: Whether to add the `IF EXISTS` clause
7257        dialect: The dialect to parse the table/column.
7258
7259    Returns:
7260        Alter table expression
7261    """
7262    table = to_table(table_name, dialect=dialect)
7263    old_column = to_column(old_column_name, dialect=dialect)
7264    new_column = to_column(new_column_name, dialect=dialect)
7265    return AlterTable(
7266        this=table,
7267        actions=[
7268            RenameColumn(this=old_column, to=new_column, exists=exists),
7269        ],
7270    )

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:
7273def convert(value: t.Any, copy: bool = False) -> Expression:
7274    """Convert a python value into an expression object.
7275
7276    Raises an error if a conversion is not possible.
7277
7278    Args:
7279        value: A python object.
7280        copy: Whether to copy `value` (only applies to Expressions and collections).
7281
7282    Returns:
7283        The equivalent expression object.
7284    """
7285    if isinstance(value, Expression):
7286        return maybe_copy(value, copy)
7287    if isinstance(value, str):
7288        return Literal.string(value)
7289    if isinstance(value, bool):
7290        return Boolean(this=value)
7291    if value is None or (isinstance(value, float) and math.isnan(value)):
7292        return null()
7293    if isinstance(value, numbers.Number):
7294        return Literal.number(value)
7295    if isinstance(value, bytes):
7296        return HexString(this=value.hex())
7297    if isinstance(value, datetime.datetime):
7298        datetime_literal = Literal.string(
7299            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7300                sep=" "
7301            )
7302        )
7303        return TimeStrToTime(this=datetime_literal)
7304    if isinstance(value, datetime.date):
7305        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7306        return DateStrToDate(this=date_literal)
7307    if isinstance(value, tuple):
7308        if hasattr(value, "_fields"):
7309            return Struct(
7310                expressions=[
7311                    PropertyEQ(
7312                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7313                    )
7314                    for k in value._fields
7315                ]
7316            )
7317        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7318    if isinstance(value, list):
7319        return Array(expressions=[convert(v, copy=copy) for v in value])
7320    if isinstance(value, dict):
7321        return Map(
7322            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7323            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7324        )
7325    if hasattr(value, "__dict__"):
7326        return Struct(
7327            expressions=[
7328                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7329                for k, v in value.__dict__.items()
7330            ]
7331        )
7332    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:
7335def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7336    """
7337    Replace children of an expression with the result of a lambda fun(child) -> exp.
7338    """
7339    for k, v in tuple(expression.args.items()):
7340        is_list_arg = type(v) is list
7341
7342        child_nodes = v if is_list_arg else [v]
7343        new_child_nodes = []
7344
7345        for cn in child_nodes:
7346            if isinstance(cn, Expression):
7347                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7348                    new_child_nodes.append(child_node)
7349            else:
7350                new_child_nodes.append(cn)
7351
7352        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:
7355def replace_tree(
7356    expression: Expression,
7357    fun: t.Callable,
7358    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7359) -> Expression:
7360    """
7361    Replace an entire tree with the result of function calls on each node.
7362
7363    This will be traversed in reverse dfs, so leaves first.
7364    If new nodes are created as a result of function calls, they will also be traversed.
7365    """
7366    stack = list(expression.dfs(prune=prune))
7367
7368    while stack:
7369        node = stack.pop()
7370        new_node = fun(node)
7371
7372        if new_node is not node:
7373            node.replace(new_node)
7374
7375            if isinstance(new_node, Expression):
7376                stack.append(new_node)
7377
7378    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]:
7381def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7382    """
7383    Return all table names referenced through columns in an expression.
7384
7385    Example:
7386        >>> import sqlglot
7387        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7388        ['a', 'c']
7389
7390    Args:
7391        expression: expression to find table names.
7392        exclude: a table name to exclude
7393
7394    Returns:
7395        A list of unique names.
7396    """
7397    return {
7398        table
7399        for table in (column.table for column in expression.find_all(Column))
7400        if table and table != exclude
7401    }

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:
7404def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7405    """Get the full name of a table as a string.
7406
7407    Args:
7408        table: Table expression node or string.
7409        dialect: The dialect to generate the table name for.
7410        identify: Determines when an identifier should be quoted. Possible values are:
7411            False (default): Never quote, except in cases where it's mandatory by the dialect.
7412            True: Always quote.
7413
7414    Examples:
7415        >>> from sqlglot import exp, parse_one
7416        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7417        'a.b.c'
7418
7419    Returns:
7420        The table name.
7421    """
7422
7423    table = maybe_parse(table, into=Table, dialect=dialect)
7424
7425    if not table:
7426        raise ValueError(f"Cannot parse {table}")
7427
7428    return ".".join(
7429        (
7430            part.sql(dialect=dialect, identify=True, copy=False)
7431            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7432            else part.name
7433        )
7434        for part in table.parts
7435    )

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:
7438def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7439    """Returns a case normalized table name without quotes.
7440
7441    Args:
7442        table: the table to normalize
7443        dialect: the dialect to use for normalization rules
7444        copy: whether to copy the expression.
7445
7446    Examples:
7447        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7448        'A-B.c'
7449    """
7450    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7451
7452    return ".".join(
7453        p.name
7454        for p in normalize_identifiers(
7455            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7456        ).parts
7457    )

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

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:
7687def tuple_(
7688    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7689) -> Tuple:
7690    """
7691    Returns an tuple.
7692
7693    Examples:
7694        >>> tuple_(1, 'x').sql()
7695        '(1, x)'
7696
7697    Args:
7698        expressions: the expressions to add to the tuple.
7699        copy: whether to copy the argument expressions.
7700        dialect: the source dialect.
7701        kwargs: the kwargs used to instantiate the function of interest.
7702
7703    Returns:
7704        A tuple expression.
7705    """
7706    return Tuple(
7707        expressions=[
7708            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7709            for expression in expressions
7710        ]
7711    )

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:
7714def true() -> Boolean:
7715    """
7716    Returns a true Boolean expression.
7717    """
7718    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7721def false() -> Boolean:
7722    """
7723    Returns a false Boolean expression.
7724    """
7725    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7728def null() -> Null:
7729    """
7730    Returns a Null expression.
7731    """
7732    return Null()

Returns a Null expression.

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