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

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

def to_dot(self) -> Dot | Identifier:
1606    def to_dot(self) -> Dot | Identifier:
1607        """Converts the column into a dot expression."""
1608        parts = self.parts
1609        parent = self.parent
1610
1611        while parent:
1612            if isinstance(parent, Dot):
1613                parts.append(parent.expression)
1614            parent = parent.parent
1615
1616        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1619class ColumnPosition(Expression):
1620    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1623class ColumnDef(Expression):
1624    arg_types = {
1625        "this": True,
1626        "kind": False,
1627        "constraints": False,
1628        "exists": False,
1629        "position": False,
1630    }
1631
1632    @property
1633    def constraints(self) -> t.List[ColumnConstraint]:
1634        return self.args.get("constraints") or []
1635
1636    @property
1637    def kind(self) -> t.Optional[DataType]:
1638        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1632    @property
1633    def constraints(self) -> t.List[ColumnConstraint]:
1634        return self.args.get("constraints") or []
kind: Optional[DataType]
1636    @property
1637    def kind(self) -> t.Optional[DataType]:
1638        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1641class AlterColumn(Expression):
1642    arg_types = {
1643        "this": True,
1644        "dtype": False,
1645        "collate": False,
1646        "using": False,
1647        "default": False,
1648        "drop": False,
1649        "comment": False,
1650        "allow_null": False,
1651    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1655class AlterDistStyle(Expression):
1656    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1659class AlterSortKey(Expression):
1660    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1663class AlterSet(Expression):
1664    arg_types = {
1665        "expressions": False,
1666        "option": False,
1667        "tablespace": False,
1668        "access_method": False,
1669        "file_format": False,
1670        "copy_options": False,
1671        "tag": False,
1672        "location": False,
1673        "serde": False,
1674    }
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):
1677class RenameColumn(Expression):
1678    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1681class RenameTable(Expression):
1682    pass
key = 'renametable'
class SwapTable(Expression):
1685class SwapTable(Expression):
1686    pass
key = 'swaptable'
class Comment(Expression):
1689class Comment(Expression):
1690    arg_types = {
1691        "this": True,
1692        "kind": True,
1693        "expression": True,
1694        "exists": False,
1695        "materialized": False,
1696    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1699class Comprehension(Expression):
1700    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):
1704class MergeTreeTTLAction(Expression):
1705    arg_types = {
1706        "this": True,
1707        "delete": False,
1708        "recompress": False,
1709        "to_disk": False,
1710        "to_volume": False,
1711    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1715class MergeTreeTTL(Expression):
1716    arg_types = {
1717        "expressions": True,
1718        "where": False,
1719        "group": False,
1720        "aggregates": False,
1721    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1725class IndexConstraintOption(Expression):
1726    arg_types = {
1727        "key_block_size": False,
1728        "using": False,
1729        "parser": False,
1730        "comment": False,
1731        "visible": False,
1732        "engine_attr": False,
1733        "secondary_engine_attr": False,
1734    }
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):
1737class ColumnConstraint(Expression):
1738    arg_types = {"this": False, "kind": True}
1739
1740    @property
1741    def kind(self) -> ColumnConstraintKind:
1742        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1740    @property
1741    def kind(self) -> ColumnConstraintKind:
1742        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1745class ColumnConstraintKind(Expression):
1746    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1749class AutoIncrementColumnConstraint(ColumnConstraintKind):
1750    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1753class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1754    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1757class CaseSpecificColumnConstraint(ColumnConstraintKind):
1758    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1761class CharacterSetColumnConstraint(ColumnConstraintKind):
1762    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1765class CheckColumnConstraint(ColumnConstraintKind):
1766    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1769class ClusteredColumnConstraint(ColumnConstraintKind):
1770    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1773class CollateColumnConstraint(ColumnConstraintKind):
1774    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1777class CommentColumnConstraint(ColumnConstraintKind):
1778    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1781class CompressColumnConstraint(ColumnConstraintKind):
1782    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1785class DateFormatColumnConstraint(ColumnConstraintKind):
1786    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1789class DefaultColumnConstraint(ColumnConstraintKind):
1790    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1793class EncodeColumnConstraint(ColumnConstraintKind):
1794    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1798class ExcludeColumnConstraint(ColumnConstraintKind):
1799    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1802class EphemeralColumnConstraint(ColumnConstraintKind):
1803    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1806class WithOperator(Expression):
1807    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1810class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1811    # this: True -> ALWAYS, this: False -> BY DEFAULT
1812    arg_types = {
1813        "this": False,
1814        "expression": False,
1815        "on_null": False,
1816        "start": False,
1817        "increment": False,
1818        "minvalue": False,
1819        "maxvalue": False,
1820        "cycle": False,
1821    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1824class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1825    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1830class IndexColumnConstraint(ColumnConstraintKind):
1831    arg_types = {
1832        "this": False,
1833        "expressions": False,
1834        "kind": False,
1835        "index_type": False,
1836        "options": False,
1837        "expression": False,  # Clickhouse
1838        "granularity": False,
1839    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1842class InlineLengthColumnConstraint(ColumnConstraintKind):
1843    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1846class NonClusteredColumnConstraint(ColumnConstraintKind):
1847    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1850class NotForReplicationColumnConstraint(ColumnConstraintKind):
1851    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1855class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1856    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1859class NotNullColumnConstraint(ColumnConstraintKind):
1860    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1864class OnUpdateColumnConstraint(ColumnConstraintKind):
1865    pass
key = 'onupdatecolumnconstraint'
class TagColumnConstraint(ColumnConstraintKind):
1869class TagColumnConstraint(ColumnConstraintKind):
1870    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tagcolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1874class TransformColumnConstraint(ColumnConstraintKind):
1875    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1878class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1879    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1882class TitleColumnConstraint(ColumnConstraintKind):
1883    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1886class UniqueColumnConstraint(ColumnConstraintKind):
1887    arg_types = {"this": False, "index_type": False, "on_conflict": False, "nulls": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1890class UppercaseColumnConstraint(ColumnConstraintKind):
1891    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1894class PathColumnConstraint(ColumnConstraintKind):
1895    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1899class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1900    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1905class ComputedColumnConstraint(ColumnConstraintKind):
1906    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1909class Constraint(Expression):
1910    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1913class Delete(DML):
1914    arg_types = {
1915        "with": False,
1916        "this": False,
1917        "using": False,
1918        "where": False,
1919        "returning": False,
1920        "limit": False,
1921        "tables": False,  # Multiple-Table Syntax (MySQL)
1922    }
1923
1924    def delete(
1925        self,
1926        table: ExpOrStr,
1927        dialect: DialectType = None,
1928        copy: bool = True,
1929        **opts,
1930    ) -> Delete:
1931        """
1932        Create a DELETE expression or replace the table on an existing DELETE expression.
1933
1934        Example:
1935            >>> delete("tbl").sql()
1936            'DELETE FROM tbl'
1937
1938        Args:
1939            table: the table from which to delete.
1940            dialect: the dialect used to parse the input expression.
1941            copy: if `False`, modify this expression instance in-place.
1942            opts: other options to use to parse the input expressions.
1943
1944        Returns:
1945            Delete: the modified expression.
1946        """
1947        return _apply_builder(
1948            expression=table,
1949            instance=self,
1950            arg="this",
1951            dialect=dialect,
1952            into=Table,
1953            copy=copy,
1954            **opts,
1955        )
1956
1957    def where(
1958        self,
1959        *expressions: t.Optional[ExpOrStr],
1960        append: bool = True,
1961        dialect: DialectType = None,
1962        copy: bool = True,
1963        **opts,
1964    ) -> Delete:
1965        """
1966        Append to or set the WHERE expressions.
1967
1968        Example:
1969            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1970            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1971
1972        Args:
1973            *expressions: the SQL code strings to parse.
1974                If an `Expression` instance is passed, it will be used as-is.
1975                Multiple expressions are combined with an AND operator.
1976            append: if `True`, AND the new expressions to any existing expression.
1977                Otherwise, this resets the expression.
1978            dialect: the dialect used to parse the input expressions.
1979            copy: if `False`, modify this expression instance in-place.
1980            opts: other options to use to parse the input expressions.
1981
1982        Returns:
1983            Delete: the modified expression.
1984        """
1985        return _apply_conjunction_builder(
1986            *expressions,
1987            instance=self,
1988            arg="where",
1989            append=append,
1990            into=Where,
1991            dialect=dialect,
1992            copy=copy,
1993            **opts,
1994        )
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:
1924    def delete(
1925        self,
1926        table: ExpOrStr,
1927        dialect: DialectType = None,
1928        copy: bool = True,
1929        **opts,
1930    ) -> Delete:
1931        """
1932        Create a DELETE expression or replace the table on an existing DELETE expression.
1933
1934        Example:
1935            >>> delete("tbl").sql()
1936            'DELETE FROM tbl'
1937
1938        Args:
1939            table: the table from which to delete.
1940            dialect: the dialect used to parse the input expression.
1941            copy: if `False`, modify this expression instance in-place.
1942            opts: other options to use to parse the input expressions.
1943
1944        Returns:
1945            Delete: the modified expression.
1946        """
1947        return _apply_builder(
1948            expression=table,
1949            instance=self,
1950            arg="this",
1951            dialect=dialect,
1952            into=Table,
1953            copy=copy,
1954            **opts,
1955        )

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

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):
1997class Drop(Expression):
1998    arg_types = {
1999        "this": False,
2000        "kind": False,
2001        "expressions": False,
2002        "exists": False,
2003        "temporary": False,
2004        "materialized": False,
2005        "cascade": False,
2006        "constraints": False,
2007        "purge": False,
2008        "cluster": False,
2009    }
2010
2011    @property
2012    def kind(self) -> t.Optional[str]:
2013        kind = self.args.get("kind")
2014        return kind and kind.upper()
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False}
kind: Optional[str]
2011    @property
2012    def kind(self) -> t.Optional[str]:
2013        kind = self.args.get("kind")
2014        return kind and kind.upper()
key = 'drop'
class Filter(Expression):
2017class Filter(Expression):
2018    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2021class Check(Expression):
2022    pass
key = 'check'
class Changes(Expression):
2025class Changes(Expression):
2026    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2030class Connect(Expression):
2031    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2034class CopyParameter(Expression):
2035    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2038class Copy(DML):
2039    arg_types = {
2040        "this": True,
2041        "kind": True,
2042        "files": True,
2043        "credentials": False,
2044        "format": False,
2045        "params": False,
2046    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2049class Credentials(Expression):
2050    arg_types = {
2051        "credentials": False,
2052        "encryption": False,
2053        "storage": False,
2054        "iam_role": False,
2055        "region": False,
2056    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2059class Prior(Expression):
2060    pass
key = 'prior'
class Directory(Expression):
2063class Directory(Expression):
2064    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2065    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2068class ForeignKey(Expression):
2069    arg_types = {
2070        "expressions": True,
2071        "reference": False,
2072        "delete": False,
2073        "update": False,
2074    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2077class ColumnPrefix(Expression):
2078    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2081class PrimaryKey(Expression):
2082    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2087class Into(Expression):
2088    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2091class From(Expression):
2092    @property
2093    def name(self) -> str:
2094        return self.this.name
2095
2096    @property
2097    def alias_or_name(self) -> str:
2098        return self.this.alias_or_name
name: str
2092    @property
2093    def name(self) -> str:
2094        return self.this.name
alias_or_name: str
2096    @property
2097    def alias_or_name(self) -> str:
2098        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2101class Having(Expression):
2102    pass
key = 'having'
class Hint(Expression):
2105class Hint(Expression):
2106    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2109class JoinHint(Expression):
2110    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2113class Identifier(Expression):
2114    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2115
2116    @property
2117    def quoted(self) -> bool:
2118        return bool(self.args.get("quoted"))
2119
2120    @property
2121    def hashable_args(self) -> t.Any:
2122        return (self.this, self.quoted)
2123
2124    @property
2125    def output_name(self) -> str:
2126        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2116    @property
2117    def quoted(self) -> bool:
2118        return bool(self.args.get("quoted"))
hashable_args: Any
2120    @property
2121    def hashable_args(self) -> t.Any:
2122        return (self.this, self.quoted)
output_name: str
2124    @property
2125    def output_name(self) -> str:
2126        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):
2130class Opclass(Expression):
2131    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2134class Index(Expression):
2135    arg_types = {
2136        "this": False,
2137        "table": False,
2138        "unique": False,
2139        "primary": False,
2140        "amp": False,  # teradata
2141        "params": False,
2142    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2145class IndexParameters(Expression):
2146    arg_types = {
2147        "using": False,
2148        "include": False,
2149        "columns": False,
2150        "with_storage": False,
2151        "partition_by": False,
2152        "tablespace": False,
2153        "where": False,
2154        "on": False,
2155    }
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):
2158class Insert(DDL, DML):
2159    arg_types = {
2160        "hint": False,
2161        "with": False,
2162        "is_function": False,
2163        "this": False,
2164        "expression": False,
2165        "conflict": False,
2166        "returning": False,
2167        "overwrite": False,
2168        "exists": False,
2169        "alternative": False,
2170        "where": False,
2171        "ignore": False,
2172        "by_name": False,
2173        "stored": False,
2174        "partition": False,
2175        "settings": False,
2176        "source": False,
2177    }
2178
2179    def with_(
2180        self,
2181        alias: ExpOrStr,
2182        as_: ExpOrStr,
2183        recursive: t.Optional[bool] = None,
2184        append: bool = True,
2185        dialect: DialectType = None,
2186        copy: bool = True,
2187        **opts,
2188    ) -> Insert:
2189        """
2190        Append to or set the common table expressions.
2191
2192        Example:
2193            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2194            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2195
2196        Args:
2197            alias: the SQL code string to parse as the table name.
2198                If an `Expression` instance is passed, this is used as-is.
2199            as_: the SQL code string to parse as the table expression.
2200                If an `Expression` instance is passed, it will be used as-is.
2201            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2202            append: if `True`, add to any existing expressions.
2203                Otherwise, this resets the expressions.
2204            dialect: the dialect used to parse the input expression.
2205            copy: if `False`, modify this expression instance in-place.
2206            opts: other options to use to parse the input expressions.
2207
2208        Returns:
2209            The modified expression.
2210        """
2211        return _apply_cte_builder(
2212            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2213        )
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, 'partition': False, 'settings': False, 'source': 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:
2179    def with_(
2180        self,
2181        alias: ExpOrStr,
2182        as_: ExpOrStr,
2183        recursive: t.Optional[bool] = None,
2184        append: bool = True,
2185        dialect: DialectType = None,
2186        copy: bool = True,
2187        **opts,
2188    ) -> Insert:
2189        """
2190        Append to or set the common table expressions.
2191
2192        Example:
2193            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2194            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2195
2196        Args:
2197            alias: the SQL code string to parse as the table name.
2198                If an `Expression` instance is passed, this is used as-is.
2199            as_: the SQL code string to parse as the table expression.
2200                If an `Expression` instance is passed, it will be used as-is.
2201            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2202            append: if `True`, add to any existing expressions.
2203                Otherwise, this resets the expressions.
2204            dialect: the dialect used to parse the input expression.
2205            copy: if `False`, modify this expression instance in-place.
2206            opts: other options to use to parse the input expressions.
2207
2208        Returns:
2209            The modified expression.
2210        """
2211        return _apply_cte_builder(
2212            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2213        )

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):
2216class OnConflict(Expression):
2217    arg_types = {
2218        "duplicate": False,
2219        "expressions": False,
2220        "action": False,
2221        "conflict_keys": False,
2222        "constraint": False,
2223    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2226class Returning(Expression):
2227    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2231class Introducer(Expression):
2232    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2236class National(Expression):
2237    pass
key = 'national'
class LoadData(Expression):
2240class LoadData(Expression):
2241    arg_types = {
2242        "this": True,
2243        "local": False,
2244        "overwrite": False,
2245        "inpath": True,
2246        "partition": False,
2247        "input_format": False,
2248        "serde": False,
2249    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2252class Partition(Expression):
2253    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2256class PartitionRange(Expression):
2257    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2261class PartitionId(Expression):
2262    pass
key = 'partitionid'
class Fetch(Expression):
2265class Fetch(Expression):
2266    arg_types = {
2267        "direction": False,
2268        "count": False,
2269        "percent": False,
2270        "with_ties": False,
2271    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2274class Group(Expression):
2275    arg_types = {
2276        "expressions": False,
2277        "grouping_sets": False,
2278        "cube": False,
2279        "rollup": False,
2280        "totals": False,
2281        "all": False,
2282    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2285class Cube(Expression):
2286    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2289class Rollup(Expression):
2290    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2293class GroupingSets(Expression):
2294    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2297class Lambda(Expression):
2298    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2301class Limit(Expression):
2302    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):
2305class Literal(Condition):
2306    arg_types = {"this": True, "is_string": True}
2307
2308    @property
2309    def hashable_args(self) -> t.Any:
2310        return (self.this, self.args.get("is_string"))
2311
2312    @classmethod
2313    def number(cls, number) -> Literal:
2314        return cls(this=str(number), is_string=False)
2315
2316    @classmethod
2317    def string(cls, string) -> Literal:
2318        return cls(this=str(string), is_string=True)
2319
2320    @property
2321    def output_name(self) -> str:
2322        return self.name
2323
2324    def to_py(self) -> int | str | Decimal:
2325        if self.is_number:
2326            try:
2327                return int(self.this)
2328            except ValueError:
2329                return Decimal(self.this)
2330        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2308    @property
2309    def hashable_args(self) -> t.Any:
2310        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2312    @classmethod
2313    def number(cls, number) -> Literal:
2314        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2316    @classmethod
2317    def string(cls, string) -> Literal:
2318        return cls(this=str(string), is_string=True)
output_name: str
2320    @property
2321    def output_name(self) -> str:
2322        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:
2324    def to_py(self) -> int | str | Decimal:
2325        if self.is_number:
2326            try:
2327                return int(self.this)
2328            except ValueError:
2329                return Decimal(self.this)
2330        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2333class Join(Expression):
2334    arg_types = {
2335        "this": True,
2336        "on": False,
2337        "side": False,
2338        "kind": False,
2339        "using": False,
2340        "method": False,
2341        "global": False,
2342        "hint": False,
2343        "match_condition": False,  # Snowflake
2344    }
2345
2346    @property
2347    def method(self) -> str:
2348        return self.text("method").upper()
2349
2350    @property
2351    def kind(self) -> str:
2352        return self.text("kind").upper()
2353
2354    @property
2355    def side(self) -> str:
2356        return self.text("side").upper()
2357
2358    @property
2359    def hint(self) -> str:
2360        return self.text("hint").upper()
2361
2362    @property
2363    def alias_or_name(self) -> str:
2364        return self.this.alias_or_name
2365
2366    def on(
2367        self,
2368        *expressions: t.Optional[ExpOrStr],
2369        append: bool = True,
2370        dialect: DialectType = None,
2371        copy: bool = True,
2372        **opts,
2373    ) -> Join:
2374        """
2375        Append to or set the ON expressions.
2376
2377        Example:
2378            >>> import sqlglot
2379            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2380            'JOIN x ON y = 1'
2381
2382        Args:
2383            *expressions: the SQL code strings to parse.
2384                If an `Expression` instance is passed, it will be used as-is.
2385                Multiple expressions are combined with an AND operator.
2386            append: if `True`, AND the new expressions to any existing expression.
2387                Otherwise, this resets the expression.
2388            dialect: the dialect used to parse the input expressions.
2389            copy: if `False`, modify this expression instance in-place.
2390            opts: other options to use to parse the input expressions.
2391
2392        Returns:
2393            The modified Join expression.
2394        """
2395        join = _apply_conjunction_builder(
2396            *expressions,
2397            instance=self,
2398            arg="on",
2399            append=append,
2400            dialect=dialect,
2401            copy=copy,
2402            **opts,
2403        )
2404
2405        if join.kind == "CROSS":
2406            join.set("kind", None)
2407
2408        return join
2409
2410    def using(
2411        self,
2412        *expressions: t.Optional[ExpOrStr],
2413        append: bool = True,
2414        dialect: DialectType = None,
2415        copy: bool = True,
2416        **opts,
2417    ) -> Join:
2418        """
2419        Append to or set the USING expressions.
2420
2421        Example:
2422            >>> import sqlglot
2423            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2424            'JOIN x USING (foo, bla)'
2425
2426        Args:
2427            *expressions: the SQL code strings to parse.
2428                If an `Expression` instance is passed, it will be used as-is.
2429            append: if `True`, concatenate the new expressions to the existing "using" list.
2430                Otherwise, this resets the expression.
2431            dialect: the dialect used to parse the input expressions.
2432            copy: if `False`, modify this expression instance in-place.
2433            opts: other options to use to parse the input expressions.
2434
2435        Returns:
2436            The modified Join expression.
2437        """
2438        join = _apply_list_builder(
2439            *expressions,
2440            instance=self,
2441            arg="using",
2442            append=append,
2443            dialect=dialect,
2444            copy=copy,
2445            **opts,
2446        )
2447
2448        if join.kind == "CROSS":
2449            join.set("kind", None)
2450
2451        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
2346    @property
2347    def method(self) -> str:
2348        return self.text("method").upper()
kind: str
2350    @property
2351    def kind(self) -> str:
2352        return self.text("kind").upper()
side: str
2354    @property
2355    def side(self) -> str:
2356        return self.text("side").upper()
hint: str
2358    @property
2359    def hint(self) -> str:
2360        return self.text("hint").upper()
alias_or_name: str
2362    @property
2363    def alias_or_name(self) -> str:
2364        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:
2366    def on(
2367        self,
2368        *expressions: t.Optional[ExpOrStr],
2369        append: bool = True,
2370        dialect: DialectType = None,
2371        copy: bool = True,
2372        **opts,
2373    ) -> Join:
2374        """
2375        Append to or set the ON expressions.
2376
2377        Example:
2378            >>> import sqlglot
2379            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2380            'JOIN x ON y = 1'
2381
2382        Args:
2383            *expressions: the SQL code strings to parse.
2384                If an `Expression` instance is passed, it will be used as-is.
2385                Multiple expressions are combined with an AND operator.
2386            append: if `True`, AND the new expressions to any existing expression.
2387                Otherwise, this resets the expression.
2388            dialect: the dialect used to parse the input expressions.
2389            copy: if `False`, modify this expression instance in-place.
2390            opts: other options to use to parse the input expressions.
2391
2392        Returns:
2393            The modified Join expression.
2394        """
2395        join = _apply_conjunction_builder(
2396            *expressions,
2397            instance=self,
2398            arg="on",
2399            append=append,
2400            dialect=dialect,
2401            copy=copy,
2402            **opts,
2403        )
2404
2405        if join.kind == "CROSS":
2406            join.set("kind", None)
2407
2408        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:
2410    def using(
2411        self,
2412        *expressions: t.Optional[ExpOrStr],
2413        append: bool = True,
2414        dialect: DialectType = None,
2415        copy: bool = True,
2416        **opts,
2417    ) -> Join:
2418        """
2419        Append to or set the USING expressions.
2420
2421        Example:
2422            >>> import sqlglot
2423            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2424            'JOIN x USING (foo, bla)'
2425
2426        Args:
2427            *expressions: the SQL code strings to parse.
2428                If an `Expression` instance is passed, it will be used as-is.
2429            append: if `True`, concatenate the new expressions to the existing "using" list.
2430                Otherwise, this resets the expression.
2431            dialect: the dialect used to parse the input expressions.
2432            copy: if `False`, modify this expression instance in-place.
2433            opts: other options to use to parse the input expressions.
2434
2435        Returns:
2436            The modified Join expression.
2437        """
2438        join = _apply_list_builder(
2439            *expressions,
2440            instance=self,
2441            arg="using",
2442            append=append,
2443            dialect=dialect,
2444            copy=copy,
2445            **opts,
2446        )
2447
2448        if join.kind == "CROSS":
2449            join.set("kind", None)
2450
2451        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):
2454class Lateral(UDTF):
2455    arg_types = {
2456        "this": True,
2457        "view": False,
2458        "outer": False,
2459        "alias": False,
2460        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2461    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2464class MatchRecognizeMeasure(Expression):
2465    arg_types = {
2466        "this": True,
2467        "window_frame": False,
2468    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2471class MatchRecognize(Expression):
2472    arg_types = {
2473        "partition_by": False,
2474        "order": False,
2475        "measures": False,
2476        "rows": False,
2477        "after": False,
2478        "pattern": False,
2479        "define": False,
2480        "alias": False,
2481    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2486class Final(Expression):
2487    pass
key = 'final'
class Offset(Expression):
2490class Offset(Expression):
2491    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2494class Order(Expression):
2495    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2499class WithFill(Expression):
2500    arg_types = {
2501        "from": False,
2502        "to": False,
2503        "step": False,
2504        "interpolate": False,
2505    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2510class Cluster(Order):
2511    pass
key = 'cluster'
class Distribute(Order):
2514class Distribute(Order):
2515    pass
key = 'distribute'
class Sort(Order):
2518class Sort(Order):
2519    pass
key = 'sort'
class Ordered(Expression):
2522class Ordered(Expression):
2523    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):
2526class Property(Expression):
2527    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2530class AllowedValuesProperty(Expression):
2531    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2534class AlgorithmProperty(Property):
2535    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2538class AutoIncrementProperty(Property):
2539    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2543class AutoRefreshProperty(Property):
2544    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2547class BackupProperty(Property):
2548    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2551class BlockCompressionProperty(Property):
2552    arg_types = {
2553        "autotemp": False,
2554        "always": False,
2555        "default": False,
2556        "manual": False,
2557        "never": False,
2558    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2561class CharacterSetProperty(Property):
2562    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2565class ChecksumProperty(Property):
2566    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2569class CollateProperty(Property):
2570    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2573class CopyGrantsProperty(Property):
2574    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2577class DataBlocksizeProperty(Property):
2578    arg_types = {
2579        "size": False,
2580        "units": False,
2581        "minimum": False,
2582        "maximum": False,
2583        "default": False,
2584    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2587class DataDeletionProperty(Property):
2588    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):
2591class DefinerProperty(Property):
2592    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2595class DistKeyProperty(Property):
2596    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2599class DistStyleProperty(Property):
2600    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2603class EngineProperty(Property):
2604    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2607class HeapProperty(Property):
2608    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2611class ToTableProperty(Property):
2612    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2615class ExecuteAsProperty(Property):
2616    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2619class ExternalProperty(Property):
2620    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2623class FallbackProperty(Property):
2624    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2627class FileFormatProperty(Property):
2628    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2631class FreespaceProperty(Property):
2632    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2635class GlobalProperty(Property):
2636    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2639class IcebergProperty(Property):
2640    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2643class InheritsProperty(Property):
2644    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2647class InputModelProperty(Property):
2648    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2651class OutputModelProperty(Property):
2652    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2655class IsolatedLoadingProperty(Property):
2656    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2659class JournalProperty(Property):
2660    arg_types = {
2661        "no": False,
2662        "dual": False,
2663        "before": False,
2664        "local": False,
2665        "after": False,
2666    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2669class LanguageProperty(Property):
2670    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2674class ClusteredByProperty(Property):
2675    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2678class DictProperty(Property):
2679    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2682class DictSubProperty(Property):
2683    pass
key = 'dictsubproperty'
class DictRange(Property):
2686class DictRange(Property):
2687    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2690class DynamicProperty(Property):
2691    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2696class OnCluster(Property):
2697    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2701class EmptyProperty(Property):
2702    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2705class LikeProperty(Property):
2706    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2709class LocationProperty(Property):
2710    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2713class LockProperty(Property):
2714    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2717class LockingProperty(Property):
2718    arg_types = {
2719        "this": False,
2720        "kind": True,
2721        "for_or_in": False,
2722        "lock_type": True,
2723        "override": False,
2724    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2727class LogProperty(Property):
2728    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2731class MaterializedProperty(Property):
2732    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2735class MergeBlockRatioProperty(Property):
2736    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):
2739class NoPrimaryIndexProperty(Property):
2740    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2743class OnProperty(Property):
2744    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2747class OnCommitProperty(Property):
2748    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2751class PartitionedByProperty(Property):
2752    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2756class PartitionBoundSpec(Expression):
2757    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2758    arg_types = {
2759        "this": False,
2760        "expression": False,
2761        "from_expressions": False,
2762        "to_expressions": False,
2763    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2766class PartitionedOfProperty(Property):
2767    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2768    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2771class StreamingTableProperty(Property):
2772    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2775class RemoteWithConnectionModelProperty(Property):
2776    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2779class ReturnsProperty(Property):
2780    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):
2783class StrictProperty(Property):
2784    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2787class RowFormatProperty(Property):
2788    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2791class RowFormatDelimitedProperty(Property):
2792    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2793    arg_types = {
2794        "fields": False,
2795        "escaped": False,
2796        "collection_items": False,
2797        "map_keys": False,
2798        "lines": False,
2799        "null": False,
2800        "serde": False,
2801    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2804class RowFormatSerdeProperty(Property):
2805    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2809class QueryTransform(Expression):
2810    arg_types = {
2811        "expressions": True,
2812        "command_script": True,
2813        "schema": False,
2814        "row_format_before": False,
2815        "record_writer": False,
2816        "row_format_after": False,
2817        "record_reader": False,
2818    }
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):
2821class SampleProperty(Property):
2822    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2825class SchemaCommentProperty(Property):
2826    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2829class SerdeProperties(Property):
2830    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2833class SetProperty(Property):
2834    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2837class SharingProperty(Property):
2838    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2841class SetConfigProperty(Property):
2842    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2845class SettingsProperty(Property):
2846    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2849class SortKeyProperty(Property):
2850    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2853class SqlReadWriteProperty(Property):
2854    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2857class SqlSecurityProperty(Property):
2858    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2861class StabilityProperty(Property):
2862    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2865class TemporaryProperty(Property):
2866    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2869class SecureProperty(Property):
2870    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2873class TransformModelProperty(Property):
2874    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2877class TransientProperty(Property):
2878    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2881class UnloggedProperty(Property):
2882    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2886class ViewAttributeProperty(Property):
2887    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2890class VolatileProperty(Property):
2891    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2894class WithDataProperty(Property):
2895    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2898class WithJournalTableProperty(Property):
2899    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2902class WithSchemaBindingProperty(Property):
2903    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2906class WithSystemVersioningProperty(Property):
2907    arg_types = {
2908        "on": False,
2909        "this": False,
2910        "data_consistency": False,
2911        "retention_period": False,
2912        "with": True,
2913    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2916class Properties(Expression):
2917    arg_types = {"expressions": True}
2918
2919    NAME_TO_PROPERTY = {
2920        "ALGORITHM": AlgorithmProperty,
2921        "AUTO_INCREMENT": AutoIncrementProperty,
2922        "CHARACTER SET": CharacterSetProperty,
2923        "CLUSTERED_BY": ClusteredByProperty,
2924        "COLLATE": CollateProperty,
2925        "COMMENT": SchemaCommentProperty,
2926        "DEFINER": DefinerProperty,
2927        "DISTKEY": DistKeyProperty,
2928        "DISTSTYLE": DistStyleProperty,
2929        "ENGINE": EngineProperty,
2930        "EXECUTE AS": ExecuteAsProperty,
2931        "FORMAT": FileFormatProperty,
2932        "LANGUAGE": LanguageProperty,
2933        "LOCATION": LocationProperty,
2934        "LOCK": LockProperty,
2935        "PARTITIONED_BY": PartitionedByProperty,
2936        "RETURNS": ReturnsProperty,
2937        "ROW_FORMAT": RowFormatProperty,
2938        "SORTKEY": SortKeyProperty,
2939    }
2940
2941    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2942
2943    # CREATE property locations
2944    # Form: schema specified
2945    #   create [POST_CREATE]
2946    #     table a [POST_NAME]
2947    #     (b int) [POST_SCHEMA]
2948    #     with ([POST_WITH])
2949    #     index (b) [POST_INDEX]
2950    #
2951    # Form: alias selection
2952    #   create [POST_CREATE]
2953    #     table a [POST_NAME]
2954    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2955    #     index (c) [POST_INDEX]
2956    class Location(AutoName):
2957        POST_CREATE = auto()
2958        POST_NAME = auto()
2959        POST_SCHEMA = auto()
2960        POST_WITH = auto()
2961        POST_ALIAS = auto()
2962        POST_EXPRESSION = auto()
2963        POST_INDEX = auto()
2964        UNSUPPORTED = auto()
2965
2966    @classmethod
2967    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2968        expressions = []
2969        for key, value in properties_dict.items():
2970            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2971            if property_cls:
2972                expressions.append(property_cls(this=convert(value)))
2973            else:
2974                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2975
2976        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:
2966    @classmethod
2967    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2968        expressions = []
2969        for key, value in properties_dict.items():
2970            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2971            if property_cls:
2972                expressions.append(property_cls(this=convert(value)))
2973            else:
2974                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2975
2976        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2956    class Location(AutoName):
2957        POST_CREATE = auto()
2958        POST_NAME = auto()
2959        POST_SCHEMA = auto()
2960        POST_WITH = auto()
2961        POST_ALIAS = auto()
2962        POST_EXPRESSION = auto()
2963        POST_INDEX = auto()
2964        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):
2979class Qualify(Expression):
2980    pass
key = 'qualify'
class InputOutputFormat(Expression):
2983class InputOutputFormat(Expression):
2984    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2988class Return(Expression):
2989    pass
key = 'return'
class Reference(Expression):
2992class Reference(Expression):
2993    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2996class Tuple(Expression):
2997    arg_types = {"expressions": False}
2998
2999    def isin(
3000        self,
3001        *expressions: t.Any,
3002        query: t.Optional[ExpOrStr] = None,
3003        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3004        copy: bool = True,
3005        **opts,
3006    ) -> In:
3007        return In(
3008            this=maybe_copy(self, copy),
3009            expressions=[convert(e, copy=copy) for e in expressions],
3010            query=maybe_parse(query, copy=copy, **opts) if query else None,
3011            unnest=(
3012                Unnest(
3013                    expressions=[
3014                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3015                        for e in ensure_list(unnest)
3016                    ]
3017                )
3018                if unnest
3019                else None
3020            ),
3021        )
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:
2999    def isin(
3000        self,
3001        *expressions: t.Any,
3002        query: t.Optional[ExpOrStr] = None,
3003        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3004        copy: bool = True,
3005        **opts,
3006    ) -> In:
3007        return In(
3008            this=maybe_copy(self, copy),
3009            expressions=[convert(e, copy=copy) for e in expressions],
3010            query=maybe_parse(query, copy=copy, **opts) if query else None,
3011            unnest=(
3012                Unnest(
3013                    expressions=[
3014                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3015                        for e in ensure_list(unnest)
3016                    ]
3017                )
3018                if unnest
3019                else None
3020            ),
3021        )
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):
3052class QueryOption(Expression):
3053    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3057class WithTableHint(Expression):
3058    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3062class IndexTableHint(Expression):
3063    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3067class HistoricalData(Expression):
3068    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3071class Table(Expression):
3072    arg_types = {
3073        "this": False,
3074        "alias": False,
3075        "db": False,
3076        "catalog": False,
3077        "laterals": False,
3078        "joins": False,
3079        "pivots": False,
3080        "hints": False,
3081        "system_time": False,
3082        "version": False,
3083        "format": False,
3084        "pattern": False,
3085        "ordinality": False,
3086        "when": False,
3087        "only": False,
3088        "partition": False,
3089        "changes": False,
3090        "rows_from": False,
3091        "sample": False,
3092    }
3093
3094    @property
3095    def name(self) -> str:
3096        if isinstance(self.this, Func):
3097            return ""
3098        return self.this.name
3099
3100    @property
3101    def db(self) -> str:
3102        return self.text("db")
3103
3104    @property
3105    def catalog(self) -> str:
3106        return self.text("catalog")
3107
3108    @property
3109    def selects(self) -> t.List[Expression]:
3110        return []
3111
3112    @property
3113    def named_selects(self) -> t.List[str]:
3114        return []
3115
3116    @property
3117    def parts(self) -> t.List[Expression]:
3118        """Return the parts of a table in order catalog, db, table."""
3119        parts: t.List[Expression] = []
3120
3121        for arg in ("catalog", "db", "this"):
3122            part = self.args.get(arg)
3123
3124            if isinstance(part, Dot):
3125                parts.extend(part.flatten())
3126            elif isinstance(part, Expression):
3127                parts.append(part)
3128
3129        return parts
3130
3131    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3132        parts = self.parts
3133        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3134        alias = self.args.get("alias")
3135        if alias:
3136            col = alias_(col, alias.this, copy=copy)
3137        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, 'changes': False, 'rows_from': False, 'sample': False}
name: str
3094    @property
3095    def name(self) -> str:
3096        if isinstance(self.this, Func):
3097            return ""
3098        return self.this.name
db: str
3100    @property
3101    def db(self) -> str:
3102        return self.text("db")
catalog: str
3104    @property
3105    def catalog(self) -> str:
3106        return self.text("catalog")
selects: List[Expression]
3108    @property
3109    def selects(self) -> t.List[Expression]:
3110        return []
named_selects: List[str]
3112    @property
3113    def named_selects(self) -> t.List[str]:
3114        return []
parts: List[Expression]
3116    @property
3117    def parts(self) -> t.List[Expression]:
3118        """Return the parts of a table in order catalog, db, table."""
3119        parts: t.List[Expression] = []
3120
3121        for arg in ("catalog", "db", "this"):
3122            part = self.args.get(arg)
3123
3124            if isinstance(part, Dot):
3125                parts.extend(part.flatten())
3126            elif isinstance(part, Expression):
3127                parts.append(part)
3128
3129        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3131    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3132        parts = self.parts
3133        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3134        alias = self.args.get("alias")
3135        if alias:
3136            col = alias_(col, alias.this, copy=copy)
3137        return col
key = 'table'
class SetOperation(Query):
3140class SetOperation(Query):
3141    arg_types = {
3142        "with": False,
3143        "this": True,
3144        "expression": True,
3145        "distinct": False,
3146        "by_name": False,
3147        **QUERY_MODIFIERS,
3148    }
3149
3150    def select(
3151        self: S,
3152        *expressions: t.Optional[ExpOrStr],
3153        append: bool = True,
3154        dialect: DialectType = None,
3155        copy: bool = True,
3156        **opts,
3157    ) -> S:
3158        this = maybe_copy(self, copy)
3159        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3160        this.expression.unnest().select(
3161            *expressions, append=append, dialect=dialect, copy=False, **opts
3162        )
3163        return this
3164
3165    @property
3166    def named_selects(self) -> t.List[str]:
3167        return self.this.unnest().named_selects
3168
3169    @property
3170    def is_star(self) -> bool:
3171        return self.this.is_star or self.expression.is_star
3172
3173    @property
3174    def selects(self) -> t.List[Expression]:
3175        return self.this.unnest().selects
3176
3177    @property
3178    def left(self) -> Query:
3179        return self.this
3180
3181    @property
3182    def right(self) -> Query:
3183        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:
3150    def select(
3151        self: S,
3152        *expressions: t.Optional[ExpOrStr],
3153        append: bool = True,
3154        dialect: DialectType = None,
3155        copy: bool = True,
3156        **opts,
3157    ) -> S:
3158        this = maybe_copy(self, copy)
3159        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3160        this.expression.unnest().select(
3161            *expressions, append=append, dialect=dialect, copy=False, **opts
3162        )
3163        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]
3165    @property
3166    def named_selects(self) -> t.List[str]:
3167        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3169    @property
3170    def is_star(self) -> bool:
3171        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3173    @property
3174    def selects(self) -> t.List[Expression]:
3175        return self.this.unnest().selects

Returns the query's projections.

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

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:
3287    def group_by(
3288        self,
3289        *expressions: t.Optional[ExpOrStr],
3290        append: bool = True,
3291        dialect: DialectType = None,
3292        copy: bool = True,
3293        **opts,
3294    ) -> Select:
3295        """
3296        Set the GROUP BY expression.
3297
3298        Example:
3299            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3300            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3301
3302        Args:
3303            *expressions: the SQL code strings to parse.
3304                If a `Group` instance is passed, this is used as-is.
3305                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3306                If nothing is passed in then a group by is not applied to the expression
3307            append: if `True`, add to any existing expressions.
3308                Otherwise, this flattens all the `Group` expression into a single expression.
3309            dialect: the dialect used to parse the input expression.
3310            copy: if `False`, modify this expression instance in-place.
3311            opts: other options to use to parse the input expressions.
3312
3313        Returns:
3314            The modified Select expression.
3315        """
3316        if not expressions:
3317            return self if not copy else self.copy()
3318
3319        return _apply_child_list_builder(
3320            *expressions,
3321            instance=self,
3322            arg="group",
3323            append=append,
3324            copy=copy,
3325            prefix="GROUP BY",
3326            into=Group,
3327            dialect=dialect,
3328            **opts,
3329        )

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:
3331    def sort_by(
3332        self,
3333        *expressions: t.Optional[ExpOrStr],
3334        append: bool = True,
3335        dialect: DialectType = None,
3336        copy: bool = True,
3337        **opts,
3338    ) -> Select:
3339        """
3340        Set the SORT BY expression.
3341
3342        Example:
3343            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3344            'SELECT x FROM tbl SORT BY x DESC'
3345
3346        Args:
3347            *expressions: the SQL code strings to parse.
3348                If a `Group` instance is passed, this is used as-is.
3349                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3350            append: if `True`, add to any existing expressions.
3351                Otherwise, this flattens all the `Order` expression into a single expression.
3352            dialect: the dialect used to parse the input expression.
3353            copy: if `False`, modify this expression instance in-place.
3354            opts: other options to use to parse the input expressions.
3355
3356        Returns:
3357            The modified Select expression.
3358        """
3359        return _apply_child_list_builder(
3360            *expressions,
3361            instance=self,
3362            arg="sort",
3363            append=append,
3364            copy=copy,
3365            prefix="SORT BY",
3366            into=Sort,
3367            dialect=dialect,
3368            **opts,
3369        )

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:
3371    def cluster_by(
3372        self,
3373        *expressions: t.Optional[ExpOrStr],
3374        append: bool = True,
3375        dialect: DialectType = None,
3376        copy: bool = True,
3377        **opts,
3378    ) -> Select:
3379        """
3380        Set the CLUSTER BY expression.
3381
3382        Example:
3383            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3384            'SELECT x FROM tbl CLUSTER BY x DESC'
3385
3386        Args:
3387            *expressions: the SQL code strings to parse.
3388                If a `Group` instance is passed, this is used as-is.
3389                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3390            append: if `True`, add to any existing expressions.
3391                Otherwise, this flattens all the `Order` expression into a single expression.
3392            dialect: the dialect used to parse the input expression.
3393            copy: if `False`, modify this expression instance in-place.
3394            opts: other options to use to parse the input expressions.
3395
3396        Returns:
3397            The modified Select expression.
3398        """
3399        return _apply_child_list_builder(
3400            *expressions,
3401            instance=self,
3402            arg="cluster",
3403            append=append,
3404            copy=copy,
3405            prefix="CLUSTER BY",
3406            into=Cluster,
3407            dialect=dialect,
3408            **opts,
3409        )

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:
3411    def select(
3412        self,
3413        *expressions: t.Optional[ExpOrStr],
3414        append: bool = True,
3415        dialect: DialectType = None,
3416        copy: bool = True,
3417        **opts,
3418    ) -> Select:
3419        return _apply_list_builder(
3420            *expressions,
3421            instance=self,
3422            arg="expressions",
3423            append=append,
3424            dialect=dialect,
3425            into=Expression,
3426            copy=copy,
3427            **opts,
3428        )

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:
3430    def lateral(
3431        self,
3432        *expressions: t.Optional[ExpOrStr],
3433        append: bool = True,
3434        dialect: DialectType = None,
3435        copy: bool = True,
3436        **opts,
3437    ) -> Select:
3438        """
3439        Append to or set the LATERAL expressions.
3440
3441        Example:
3442            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3443            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3444
3445        Args:
3446            *expressions: the SQL code strings to parse.
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            dialect: the dialect used to parse the input expressions.
3451            copy: if `False`, modify this expression instance in-place.
3452            opts: other options to use to parse the input expressions.
3453
3454        Returns:
3455            The modified Select expression.
3456        """
3457        return _apply_list_builder(
3458            *expressions,
3459            instance=self,
3460            arg="laterals",
3461            append=append,
3462            into=Lateral,
3463            prefix="LATERAL VIEW",
3464            dialect=dialect,
3465            copy=copy,
3466            **opts,
3467        )

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:
3469    def join(
3470        self,
3471        expression: ExpOrStr,
3472        on: t.Optional[ExpOrStr] = None,
3473        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3474        append: bool = True,
3475        join_type: t.Optional[str] = None,
3476        join_alias: t.Optional[Identifier | str] = None,
3477        dialect: DialectType = None,
3478        copy: bool = True,
3479        **opts,
3480    ) -> Select:
3481        """
3482        Append to or set the JOIN expressions.
3483
3484        Example:
3485            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3486            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3487
3488            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3489            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3490
3491            Use `join_type` to change the type of join:
3492
3493            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3494            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3495
3496        Args:
3497            expression: the SQL code string to parse.
3498                If an `Expression` instance is passed, it will be used as-is.
3499            on: optionally specify the join "on" criteria as a SQL string.
3500                If an `Expression` instance is passed, it will be used as-is.
3501            using: optionally specify the join "using" criteria as a SQL string.
3502                If an `Expression` instance is passed, it will be used as-is.
3503            append: if `True`, add to any existing expressions.
3504                Otherwise, this resets the expressions.
3505            join_type: if set, alter the parsed join type.
3506            join_alias: an optional alias for the joined source.
3507            dialect: the dialect used to parse the input expressions.
3508            copy: if `False`, modify this expression instance in-place.
3509            opts: other options to use to parse the input expressions.
3510
3511        Returns:
3512            Select: the modified expression.
3513        """
3514        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3515
3516        try:
3517            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3518        except ParseError:
3519            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3520
3521        join = expression if isinstance(expression, Join) else Join(this=expression)
3522
3523        if isinstance(join.this, Select):
3524            join.this.replace(join.this.subquery())
3525
3526        if join_type:
3527            method: t.Optional[Token]
3528            side: t.Optional[Token]
3529            kind: t.Optional[Token]
3530
3531            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3532
3533            if method:
3534                join.set("method", method.text)
3535            if side:
3536                join.set("side", side.text)
3537            if kind:
3538                join.set("kind", kind.text)
3539
3540        if on:
3541            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3542            join.set("on", on)
3543
3544        if using:
3545            join = _apply_list_builder(
3546                *ensure_list(using),
3547                instance=join,
3548                arg="using",
3549                append=append,
3550                copy=copy,
3551                into=Identifier,
3552                **opts,
3553            )
3554
3555        if join_alias:
3556            join.set("this", alias_(join.this, join_alias, table=True))
3557
3558        return _apply_list_builder(
3559            join,
3560            instance=self,
3561            arg="joins",
3562            append=append,
3563            copy=copy,
3564            **opts,
3565        )

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:
3567    def where(
3568        self,
3569        *expressions: t.Optional[ExpOrStr],
3570        append: bool = True,
3571        dialect: DialectType = None,
3572        copy: bool = True,
3573        **opts,
3574    ) -> Select:
3575        """
3576        Append to or set the WHERE expressions.
3577
3578        Example:
3579            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3580            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3581
3582        Args:
3583            *expressions: the SQL code strings to parse.
3584                If an `Expression` instance is passed, it will be used as-is.
3585                Multiple expressions are combined with an AND operator.
3586            append: if `True`, AND the new expressions to any existing expression.
3587                Otherwise, this resets the expression.
3588            dialect: the dialect used to parse the input expressions.
3589            copy: if `False`, modify this expression instance in-place.
3590            opts: other options to use to parse the input expressions.
3591
3592        Returns:
3593            Select: the modified expression.
3594        """
3595        return _apply_conjunction_builder(
3596            *expressions,
3597            instance=self,
3598            arg="where",
3599            append=append,
3600            into=Where,
3601            dialect=dialect,
3602            copy=copy,
3603            **opts,
3604        )

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:
3606    def having(
3607        self,
3608        *expressions: t.Optional[ExpOrStr],
3609        append: bool = True,
3610        dialect: DialectType = None,
3611        copy: bool = True,
3612        **opts,
3613    ) -> Select:
3614        """
3615        Append to or set the HAVING expressions.
3616
3617        Example:
3618            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3619            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3620
3621        Args:
3622            *expressions: the SQL code strings to parse.
3623                If an `Expression` instance is passed, it will be used as-is.
3624                Multiple expressions are combined with an AND operator.
3625            append: if `True`, AND the new expressions to any existing expression.
3626                Otherwise, this resets the expression.
3627            dialect: the dialect used to parse the input expressions.
3628            copy: if `False`, modify this expression instance in-place.
3629            opts: other options to use to parse the input expressions.
3630
3631        Returns:
3632            The modified Select expression.
3633        """
3634        return _apply_conjunction_builder(
3635            *expressions,
3636            instance=self,
3637            arg="having",
3638            append=append,
3639            into=Having,
3640            dialect=dialect,
3641            copy=copy,
3642            **opts,
3643        )

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:
3645    def window(
3646        self,
3647        *expressions: t.Optional[ExpOrStr],
3648        append: bool = True,
3649        dialect: DialectType = None,
3650        copy: bool = True,
3651        **opts,
3652    ) -> Select:
3653        return _apply_list_builder(
3654            *expressions,
3655            instance=self,
3656            arg="windows",
3657            append=append,
3658            into=Window,
3659            dialect=dialect,
3660            copy=copy,
3661            **opts,
3662        )
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:
3664    def qualify(
3665        self,
3666        *expressions: t.Optional[ExpOrStr],
3667        append: bool = True,
3668        dialect: DialectType = None,
3669        copy: bool = True,
3670        **opts,
3671    ) -> Select:
3672        return _apply_conjunction_builder(
3673            *expressions,
3674            instance=self,
3675            arg="qualify",
3676            append=append,
3677            into=Qualify,
3678            dialect=dialect,
3679            copy=copy,
3680            **opts,
3681        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3683    def distinct(
3684        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3685    ) -> Select:
3686        """
3687        Set the OFFSET expression.
3688
3689        Example:
3690            >>> Select().from_("tbl").select("x").distinct().sql()
3691            'SELECT DISTINCT x FROM tbl'
3692
3693        Args:
3694            ons: the expressions to distinct on
3695            distinct: whether the Select should be distinct
3696            copy: if `False`, modify this expression instance in-place.
3697
3698        Returns:
3699            Select: the modified expression.
3700        """
3701        instance = maybe_copy(self, copy)
3702        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3703        instance.set("distinct", Distinct(on=on) if distinct else None)
3704        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:
3706    def ctas(
3707        self,
3708        table: ExpOrStr,
3709        properties: t.Optional[t.Dict] = None,
3710        dialect: DialectType = None,
3711        copy: bool = True,
3712        **opts,
3713    ) -> Create:
3714        """
3715        Convert this expression to a CREATE TABLE AS statement.
3716
3717        Example:
3718            >>> Select().select("*").from_("tbl").ctas("x").sql()
3719            'CREATE TABLE x AS SELECT * FROM tbl'
3720
3721        Args:
3722            table: the SQL code string to parse as the table name.
3723                If another `Expression` instance is passed, it will be used as-is.
3724            properties: an optional mapping of table properties
3725            dialect: the dialect used to parse the input table.
3726            copy: if `False`, modify this expression instance in-place.
3727            opts: other options to use to parse the input table.
3728
3729        Returns:
3730            The new Create expression.
3731        """
3732        instance = maybe_copy(self, copy)
3733        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3734
3735        properties_expression = None
3736        if properties:
3737            properties_expression = Properties.from_dict(properties)
3738
3739        return Create(
3740            this=table_expression,
3741            kind="TABLE",
3742            expression=instance,
3743            properties=properties_expression,
3744        )

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:
3746    def lock(self, update: bool = True, copy: bool = True) -> Select:
3747        """
3748        Set the locking read mode for this expression.
3749
3750        Examples:
3751            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3752            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3753
3754            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3755            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3756
3757        Args:
3758            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3759            copy: if `False`, modify this expression instance in-place.
3760
3761        Returns:
3762            The modified expression.
3763        """
3764        inst = maybe_copy(self, copy)
3765        inst.set("locks", [Lock(update=update)])
3766
3767        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:
3769    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3770        """
3771        Set hints for this expression.
3772
3773        Examples:
3774            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3775            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3776
3777        Args:
3778            hints: The SQL code strings to parse as the hints.
3779                If an `Expression` instance is passed, it will be used as-is.
3780            dialect: The dialect used to parse the hints.
3781            copy: If `False`, modify this expression instance in-place.
3782
3783        Returns:
3784            The modified expression.
3785        """
3786        inst = maybe_copy(self, copy)
3787        inst.set(
3788            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3789        )
3790
3791        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]
3793    @property
3794    def named_selects(self) -> t.List[str]:
3795        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
3797    @property
3798    def is_star(self) -> bool:
3799        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3801    @property
3802    def selects(self) -> t.List[Expression]:
3803        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
3809class Subquery(DerivedTable, Query):
3810    arg_types = {
3811        "this": True,
3812        "alias": False,
3813        "with": False,
3814        **QUERY_MODIFIERS,
3815    }
3816
3817    def unnest(self):
3818        """Returns the first non subquery."""
3819        expression = self
3820        while isinstance(expression, Subquery):
3821            expression = expression.this
3822        return expression
3823
3824    def unwrap(self) -> Subquery:
3825        expression = self
3826        while expression.same_parent and expression.is_wrapper:
3827            expression = t.cast(Subquery, expression.parent)
3828        return expression
3829
3830    def select(
3831        self,
3832        *expressions: t.Optional[ExpOrStr],
3833        append: bool = True,
3834        dialect: DialectType = None,
3835        copy: bool = True,
3836        **opts,
3837    ) -> Subquery:
3838        this = maybe_copy(self, copy)
3839        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3840        return this
3841
3842    @property
3843    def is_wrapper(self) -> bool:
3844        """
3845        Whether this Subquery acts as a simple wrapper around another expression.
3846
3847        SELECT * FROM (((SELECT * FROM t)))
3848                      ^
3849                      This corresponds to a "wrapper" Subquery node
3850        """
3851        return all(v is None for k, v in self.args.items() if k != "this")
3852
3853    @property
3854    def is_star(self) -> bool:
3855        return self.this.is_star
3856
3857    @property
3858    def output_name(self) -> str:
3859        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):
3817    def unnest(self):
3818        """Returns the first non subquery."""
3819        expression = self
3820        while isinstance(expression, Subquery):
3821            expression = expression.this
3822        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3824    def unwrap(self) -> Subquery:
3825        expression = self
3826        while expression.same_parent and expression.is_wrapper:
3827            expression = t.cast(Subquery, expression.parent)
3828        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:
3830    def select(
3831        self,
3832        *expressions: t.Optional[ExpOrStr],
3833        append: bool = True,
3834        dialect: DialectType = None,
3835        copy: bool = True,
3836        **opts,
3837    ) -> Subquery:
3838        this = maybe_copy(self, copy)
3839        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3840        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
3842    @property
3843    def is_wrapper(self) -> bool:
3844        """
3845        Whether this Subquery acts as a simple wrapper around another expression.
3846
3847        SELECT * FROM (((SELECT * FROM t)))
3848                      ^
3849                      This corresponds to a "wrapper" Subquery node
3850        """
3851        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
3853    @property
3854    def is_star(self) -> bool:
3855        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3857    @property
3858    def output_name(self) -> str:
3859        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):
3862class TableSample(Expression):
3863    arg_types = {
3864        "expressions": False,
3865        "method": False,
3866        "bucket_numerator": False,
3867        "bucket_denominator": False,
3868        "bucket_field": False,
3869        "percent": False,
3870        "rows": False,
3871        "size": False,
3872        "seed": False,
3873    }
arg_types = {'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):
3876class Tag(Expression):
3877    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3878
3879    arg_types = {
3880        "this": False,
3881        "prefix": False,
3882        "postfix": False,
3883    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3888class Pivot(Expression):
3889    arg_types = {
3890        "this": False,
3891        "alias": False,
3892        "expressions": False,
3893        "field": False,
3894        "unpivot": False,
3895        "using": False,
3896        "group": False,
3897        "columns": False,
3898        "include_nulls": False,
3899        "default_on_null": False,
3900    }
3901
3902    @property
3903    def unpivot(self) -> bool:
3904        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, 'default_on_null': False}
unpivot: bool
3902    @property
3903    def unpivot(self) -> bool:
3904        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3907class Window(Condition):
3908    arg_types = {
3909        "this": True,
3910        "partition_by": False,
3911        "order": False,
3912        "spec": False,
3913        "alias": False,
3914        "over": False,
3915        "first": False,
3916    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3919class WindowSpec(Expression):
3920    arg_types = {
3921        "kind": False,
3922        "start": False,
3923        "start_side": False,
3924        "end": False,
3925        "end_side": False,
3926    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3929class PreWhere(Expression):
3930    pass
key = 'prewhere'
class Where(Expression):
3933class Where(Expression):
3934    pass
key = 'where'
class Star(Expression):
3937class Star(Expression):
3938    arg_types = {"except": False, "replace": False, "rename": False}
3939
3940    @property
3941    def name(self) -> str:
3942        return "*"
3943
3944    @property
3945    def output_name(self) -> str:
3946        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3940    @property
3941    def name(self) -> str:
3942        return "*"
output_name: str
3944    @property
3945    def output_name(self) -> str:
3946        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):
3949class Parameter(Condition):
3950    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3953class SessionParameter(Condition):
3954    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3957class Placeholder(Condition):
3958    arg_types = {"this": False, "kind": False}
3959
3960    @property
3961    def name(self) -> str:
3962        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3960    @property
3961    def name(self) -> str:
3962        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3965class Null(Condition):
3966    arg_types: t.Dict[str, t.Any] = {}
3967
3968    @property
3969    def name(self) -> str:
3970        return "NULL"
3971
3972    def to_py(self) -> Lit[None]:
3973        return None
arg_types: Dict[str, Any] = {}
name: str
3968    @property
3969    def name(self) -> str:
3970        return "NULL"
def to_py(self) -> Literal[None]:
3972    def to_py(self) -> Lit[None]:
3973        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
3976class Boolean(Condition):
3977    def to_py(self) -> bool:
3978        return self.this
def to_py(self) -> bool:
3977    def to_py(self) -> bool:
3978        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
3981class DataTypeParam(Expression):
3982    arg_types = {"this": True, "expression": False}
3983
3984    @property
3985    def name(self) -> str:
3986        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3984    @property
3985    def name(self) -> str:
3986        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3991class DataType(Expression):
3992    arg_types = {
3993        "this": True,
3994        "expressions": False,
3995        "nested": False,
3996        "values": False,
3997        "prefix": False,
3998        "kind": False,
3999        "nullable": False,
4000    }
4001
4002    class Type(AutoName):
4003        ARRAY = auto()
4004        AGGREGATEFUNCTION = auto()
4005        SIMPLEAGGREGATEFUNCTION = auto()
4006        BIGDECIMAL = auto()
4007        BIGINT = auto()
4008        BIGSERIAL = auto()
4009        BINARY = auto()
4010        BIT = auto()
4011        BOOLEAN = auto()
4012        BPCHAR = auto()
4013        CHAR = auto()
4014        DATE = auto()
4015        DATE32 = auto()
4016        DATEMULTIRANGE = auto()
4017        DATERANGE = auto()
4018        DATETIME = auto()
4019        DATETIME64 = auto()
4020        DECIMAL = auto()
4021        DOUBLE = auto()
4022        ENUM = auto()
4023        ENUM8 = auto()
4024        ENUM16 = auto()
4025        FIXEDSTRING = auto()
4026        FLOAT = auto()
4027        GEOGRAPHY = auto()
4028        GEOMETRY = auto()
4029        HLLSKETCH = auto()
4030        HSTORE = auto()
4031        IMAGE = auto()
4032        INET = auto()
4033        INT = auto()
4034        INT128 = auto()
4035        INT256 = auto()
4036        INT4MULTIRANGE = auto()
4037        INT4RANGE = auto()
4038        INT8MULTIRANGE = auto()
4039        INT8RANGE = auto()
4040        INTERVAL = auto()
4041        IPADDRESS = auto()
4042        IPPREFIX = auto()
4043        IPV4 = auto()
4044        IPV6 = auto()
4045        JSON = auto()
4046        JSONB = auto()
4047        LIST = auto()
4048        LONGBLOB = auto()
4049        LONGTEXT = auto()
4050        LOWCARDINALITY = auto()
4051        MAP = auto()
4052        MEDIUMBLOB = auto()
4053        MEDIUMINT = auto()
4054        MEDIUMTEXT = auto()
4055        MONEY = auto()
4056        NAME = auto()
4057        NCHAR = auto()
4058        NESTED = auto()
4059        NULL = auto()
4060        NULLABLE = auto()
4061        NUMMULTIRANGE = auto()
4062        NUMRANGE = auto()
4063        NVARCHAR = auto()
4064        OBJECT = auto()
4065        ROWVERSION = auto()
4066        SERIAL = auto()
4067        SET = auto()
4068        SMALLINT = auto()
4069        SMALLMONEY = auto()
4070        SMALLSERIAL = auto()
4071        STRUCT = auto()
4072        SUPER = auto()
4073        TEXT = auto()
4074        TINYBLOB = auto()
4075        TINYTEXT = auto()
4076        TIME = auto()
4077        TIMETZ = auto()
4078        TIMESTAMP = auto()
4079        TIMESTAMPNTZ = auto()
4080        TIMESTAMPLTZ = auto()
4081        TIMESTAMPTZ = auto()
4082        TIMESTAMP_S = auto()
4083        TIMESTAMP_MS = auto()
4084        TIMESTAMP_NS = auto()
4085        TINYINT = auto()
4086        TSMULTIRANGE = auto()
4087        TSRANGE = auto()
4088        TSTZMULTIRANGE = auto()
4089        TSTZRANGE = auto()
4090        UBIGINT = auto()
4091        UINT = auto()
4092        UINT128 = auto()
4093        UINT256 = auto()
4094        UMEDIUMINT = auto()
4095        UDECIMAL = auto()
4096        UNIQUEIDENTIFIER = auto()
4097        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4098        USERDEFINED = "USER-DEFINED"
4099        USMALLINT = auto()
4100        UTINYINT = auto()
4101        UUID = auto()
4102        VARBINARY = auto()
4103        VARCHAR = auto()
4104        VARIANT = auto()
4105        VECTOR = auto()
4106        XML = auto()
4107        YEAR = auto()
4108        TDIGEST = auto()
4109
4110    STRUCT_TYPES = {
4111        Type.NESTED,
4112        Type.OBJECT,
4113        Type.STRUCT,
4114    }
4115
4116    NESTED_TYPES = {
4117        *STRUCT_TYPES,
4118        Type.ARRAY,
4119        Type.MAP,
4120    }
4121
4122    TEXT_TYPES = {
4123        Type.CHAR,
4124        Type.NCHAR,
4125        Type.NVARCHAR,
4126        Type.TEXT,
4127        Type.VARCHAR,
4128        Type.NAME,
4129    }
4130
4131    SIGNED_INTEGER_TYPES = {
4132        Type.BIGINT,
4133        Type.INT,
4134        Type.INT128,
4135        Type.INT256,
4136        Type.MEDIUMINT,
4137        Type.SMALLINT,
4138        Type.TINYINT,
4139    }
4140
4141    UNSIGNED_INTEGER_TYPES = {
4142        Type.UBIGINT,
4143        Type.UINT,
4144        Type.UINT128,
4145        Type.UINT256,
4146        Type.UMEDIUMINT,
4147        Type.USMALLINT,
4148        Type.UTINYINT,
4149    }
4150
4151    INTEGER_TYPES = {
4152        *SIGNED_INTEGER_TYPES,
4153        *UNSIGNED_INTEGER_TYPES,
4154        Type.BIT,
4155    }
4156
4157    FLOAT_TYPES = {
4158        Type.DOUBLE,
4159        Type.FLOAT,
4160    }
4161
4162    REAL_TYPES = {
4163        *FLOAT_TYPES,
4164        Type.BIGDECIMAL,
4165        Type.DECIMAL,
4166        Type.MONEY,
4167        Type.SMALLMONEY,
4168        Type.UDECIMAL,
4169    }
4170
4171    NUMERIC_TYPES = {
4172        *INTEGER_TYPES,
4173        *REAL_TYPES,
4174    }
4175
4176    TEMPORAL_TYPES = {
4177        Type.DATE,
4178        Type.DATE32,
4179        Type.DATETIME,
4180        Type.DATETIME64,
4181        Type.TIME,
4182        Type.TIMESTAMP,
4183        Type.TIMESTAMPNTZ,
4184        Type.TIMESTAMPLTZ,
4185        Type.TIMESTAMPTZ,
4186        Type.TIMESTAMP_MS,
4187        Type.TIMESTAMP_NS,
4188        Type.TIMESTAMP_S,
4189        Type.TIMETZ,
4190    }
4191
4192    @classmethod
4193    def build(
4194        cls,
4195        dtype: DATA_TYPE,
4196        dialect: DialectType = None,
4197        udt: bool = False,
4198        copy: bool = True,
4199        **kwargs,
4200    ) -> DataType:
4201        """
4202        Constructs a DataType object.
4203
4204        Args:
4205            dtype: the data type of interest.
4206            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4207            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4208                DataType, thus creating a user-defined type.
4209            copy: whether to copy the data type.
4210            kwargs: additional arguments to pass in the constructor of DataType.
4211
4212        Returns:
4213            The constructed DataType object.
4214        """
4215        from sqlglot import parse_one
4216
4217        if isinstance(dtype, str):
4218            if dtype.upper() == "UNKNOWN":
4219                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4220
4221            try:
4222                data_type_exp = parse_one(
4223                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4224                )
4225            except ParseError:
4226                if udt:
4227                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4228                raise
4229        elif isinstance(dtype, DataType.Type):
4230            data_type_exp = DataType(this=dtype)
4231        elif isinstance(dtype, DataType):
4232            return maybe_copy(dtype, copy)
4233        else:
4234            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4235
4236        return DataType(**{**data_type_exp.args, **kwargs})
4237
4238    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4239        """
4240        Checks whether this DataType matches one of the provided data types. Nested types or precision
4241        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4242
4243        Args:
4244            dtypes: the data types to compare this DataType to.
4245            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4246                If false, it means that NULLABLE<INT> is equivalent to INT.
4247
4248        Returns:
4249            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4250        """
4251        if (
4252            not check_nullable
4253            and self.this == DataType.Type.NULLABLE
4254            and len(self.expressions) == 1
4255        ):
4256            this_type = self.expressions[0]
4257        else:
4258            this_type = self
4259
4260        for dtype in dtypes:
4261            other_type = DataType.build(dtype, copy=False, udt=True)
4262            if (
4263                not check_nullable
4264                and other_type.this == DataType.Type.NULLABLE
4265                and len(other_type.expressions) == 1
4266            ):
4267                other_type = other_type.expressions[0]
4268
4269            if (
4270                other_type.expressions
4271                or this_type.this == DataType.Type.USERDEFINED
4272                or other_type.this == DataType.Type.USERDEFINED
4273            ):
4274                matches = this_type == other_type
4275            else:
4276                matches = this_type.this == other_type.this
4277
4278            if matches:
4279                return True
4280        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>}
NESTED_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.STRUCT: 'STRUCT'>, <Type.MAP: 'MAP'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>}
TEXT_TYPES = {<Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.NAME: 'NAME'>}
SIGNED_INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.INT256: 'INT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.UINT256: 'UINT256'>, <Type.UINT: 'UINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.UINT256: 'UINT256'>, <Type.INT256: 'INT256'>, <Type.UINT: 'UINT'>, <Type.BIT: 'BIT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.MONEY: 'MONEY'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.FLOAT: 'FLOAT'>}
NUMERIC_TYPES = {<Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT256: 'INT256'>, <Type.UINT: 'UINT'>, <Type.BIT: 'BIT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.INT128: 'INT128'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.SMALLINT: 'SMALLINT'>, <Type.MONEY: 'MONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGINT: 'BIGINT'>, <Type.UINT256: 'UINT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT: 'INT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.TINYINT: 'TINYINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME: 'DATETIME'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIME: 'TIME'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4192    @classmethod
4193    def build(
4194        cls,
4195        dtype: DATA_TYPE,
4196        dialect: DialectType = None,
4197        udt: bool = False,
4198        copy: bool = True,
4199        **kwargs,
4200    ) -> DataType:
4201        """
4202        Constructs a DataType object.
4203
4204        Args:
4205            dtype: the data type of interest.
4206            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4207            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4208                DataType, thus creating a user-defined type.
4209            copy: whether to copy the data type.
4210            kwargs: additional arguments to pass in the constructor of DataType.
4211
4212        Returns:
4213            The constructed DataType object.
4214        """
4215        from sqlglot import parse_one
4216
4217        if isinstance(dtype, str):
4218            if dtype.upper() == "UNKNOWN":
4219                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4220
4221            try:
4222                data_type_exp = parse_one(
4223                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4224                )
4225            except ParseError:
4226                if udt:
4227                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4228                raise
4229        elif isinstance(dtype, DataType.Type):
4230            data_type_exp = DataType(this=dtype)
4231        elif isinstance(dtype, DataType):
4232            return maybe_copy(dtype, copy)
4233        else:
4234            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4235
4236        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], check_nullable: bool = False) -> bool:
4238    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4239        """
4240        Checks whether this DataType matches one of the provided data types. Nested types or precision
4241        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4242
4243        Args:
4244            dtypes: the data types to compare this DataType to.
4245            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4246                If false, it means that NULLABLE<INT> is equivalent to INT.
4247
4248        Returns:
4249            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4250        """
4251        if (
4252            not check_nullable
4253            and self.this == DataType.Type.NULLABLE
4254            and len(self.expressions) == 1
4255        ):
4256            this_type = self.expressions[0]
4257        else:
4258            this_type = self
4259
4260        for dtype in dtypes:
4261            other_type = DataType.build(dtype, copy=False, udt=True)
4262            if (
4263                not check_nullable
4264                and other_type.this == DataType.Type.NULLABLE
4265                and len(other_type.expressions) == 1
4266            ):
4267                other_type = other_type.expressions[0]
4268
4269            if (
4270                other_type.expressions
4271                or this_type.this == DataType.Type.USERDEFINED
4272                or other_type.this == DataType.Type.USERDEFINED
4273            ):
4274                matches = this_type == other_type
4275            else:
4276                matches = this_type.this == other_type.this
4277
4278            if matches:
4279                return True
4280        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.
  • check_nullable: whether to take the NULLABLE type constructor into account for the comparison. If false, it means that NULLABLE is equivalent to INT.
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):
4002    class Type(AutoName):
4003        ARRAY = auto()
4004        AGGREGATEFUNCTION = auto()
4005        SIMPLEAGGREGATEFUNCTION = auto()
4006        BIGDECIMAL = auto()
4007        BIGINT = auto()
4008        BIGSERIAL = auto()
4009        BINARY = auto()
4010        BIT = auto()
4011        BOOLEAN = auto()
4012        BPCHAR = auto()
4013        CHAR = auto()
4014        DATE = auto()
4015        DATE32 = auto()
4016        DATEMULTIRANGE = auto()
4017        DATERANGE = auto()
4018        DATETIME = auto()
4019        DATETIME64 = auto()
4020        DECIMAL = auto()
4021        DOUBLE = auto()
4022        ENUM = auto()
4023        ENUM8 = auto()
4024        ENUM16 = auto()
4025        FIXEDSTRING = auto()
4026        FLOAT = auto()
4027        GEOGRAPHY = auto()
4028        GEOMETRY = auto()
4029        HLLSKETCH = auto()
4030        HSTORE = auto()
4031        IMAGE = auto()
4032        INET = auto()
4033        INT = auto()
4034        INT128 = auto()
4035        INT256 = auto()
4036        INT4MULTIRANGE = auto()
4037        INT4RANGE = auto()
4038        INT8MULTIRANGE = auto()
4039        INT8RANGE = auto()
4040        INTERVAL = auto()
4041        IPADDRESS = auto()
4042        IPPREFIX = auto()
4043        IPV4 = auto()
4044        IPV6 = auto()
4045        JSON = auto()
4046        JSONB = auto()
4047        LIST = auto()
4048        LONGBLOB = auto()
4049        LONGTEXT = auto()
4050        LOWCARDINALITY = auto()
4051        MAP = auto()
4052        MEDIUMBLOB = auto()
4053        MEDIUMINT = auto()
4054        MEDIUMTEXT = auto()
4055        MONEY = auto()
4056        NAME = auto()
4057        NCHAR = auto()
4058        NESTED = auto()
4059        NULL = auto()
4060        NULLABLE = auto()
4061        NUMMULTIRANGE = auto()
4062        NUMRANGE = auto()
4063        NVARCHAR = auto()
4064        OBJECT = auto()
4065        ROWVERSION = auto()
4066        SERIAL = auto()
4067        SET = auto()
4068        SMALLINT = auto()
4069        SMALLMONEY = auto()
4070        SMALLSERIAL = auto()
4071        STRUCT = auto()
4072        SUPER = auto()
4073        TEXT = auto()
4074        TINYBLOB = auto()
4075        TINYTEXT = auto()
4076        TIME = auto()
4077        TIMETZ = auto()
4078        TIMESTAMP = auto()
4079        TIMESTAMPNTZ = auto()
4080        TIMESTAMPLTZ = auto()
4081        TIMESTAMPTZ = auto()
4082        TIMESTAMP_S = auto()
4083        TIMESTAMP_MS = auto()
4084        TIMESTAMP_NS = auto()
4085        TINYINT = auto()
4086        TSMULTIRANGE = auto()
4087        TSRANGE = auto()
4088        TSTZMULTIRANGE = auto()
4089        TSTZRANGE = auto()
4090        UBIGINT = auto()
4091        UINT = auto()
4092        UINT128 = auto()
4093        UINT256 = auto()
4094        UMEDIUMINT = auto()
4095        UDECIMAL = auto()
4096        UNIQUEIDENTIFIER = auto()
4097        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4098        USERDEFINED = "USER-DEFINED"
4099        USMALLINT = auto()
4100        UTINYINT = auto()
4101        UUID = auto()
4102        VARBINARY = auto()
4103        VARCHAR = auto()
4104        VARIANT = auto()
4105        VECTOR = auto()
4106        XML = auto()
4107        YEAR = auto()
4108        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'>
VECTOR = <Type.VECTOR: 'VECTOR'>
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):
4287class PseudoType(DataType):
4288    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4292class ObjectIdentifier(DataType):
4293    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4297class SubqueryPredicate(Predicate):
4298    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4301class All(SubqueryPredicate):
4302    pass
key = 'all'
class Any(SubqueryPredicate):
4305class Any(SubqueryPredicate):
4306    pass
key = 'any'
class Exists(SubqueryPredicate):
4309class Exists(SubqueryPredicate):
4310    pass
key = 'exists'
class Command(Expression):
4315class Command(Expression):
4316    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4319class Transaction(Expression):
4320    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4323class Commit(Expression):
4324    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4327class Rollback(Expression):
4328    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4331class Alter(Expression):
4332    arg_types = {
4333        "this": True,
4334        "kind": True,
4335        "actions": True,
4336        "exists": False,
4337        "only": False,
4338        "options": False,
4339        "cluster": False,
4340    }
arg_types = {'this': True, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False}
key = 'alter'
class AddConstraint(Expression):
4343class AddConstraint(Expression):
4344    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4347class DropPartition(Expression):
4348    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4352class ReplacePartition(Expression):
4353    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4357class Binary(Condition):
4358    arg_types = {"this": True, "expression": True}
4359
4360    @property
4361    def left(self) -> Expression:
4362        return self.this
4363
4364    @property
4365    def right(self) -> Expression:
4366        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4360    @property
4361    def left(self) -> Expression:
4362        return self.this
right: Expression
4364    @property
4365    def right(self) -> Expression:
4366        return self.expression
key = 'binary'
class Add(Binary):
4369class Add(Binary):
4370    pass
key = 'add'
class Connector(Binary):
4373class Connector(Binary):
4374    pass
key = 'connector'
class And(Connector):
4377class And(Connector):
4378    pass
key = 'and'
class Or(Connector):
4381class Or(Connector):
4382    pass
key = 'or'
class BitwiseAnd(Binary):
4385class BitwiseAnd(Binary):
4386    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4389class BitwiseLeftShift(Binary):
4390    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4393class BitwiseOr(Binary):
4394    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4397class BitwiseRightShift(Binary):
4398    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4401class BitwiseXor(Binary):
4402    pass
key = 'bitwisexor'
class Div(Binary):
4405class Div(Binary):
4406    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):
4409class Overlaps(Binary):
4410    pass
key = 'overlaps'
class Dot(Binary):
4413class Dot(Binary):
4414    @property
4415    def is_star(self) -> bool:
4416        return self.expression.is_star
4417
4418    @property
4419    def name(self) -> str:
4420        return self.expression.name
4421
4422    @property
4423    def output_name(self) -> str:
4424        return self.name
4425
4426    @classmethod
4427    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4428        """Build a Dot object with a sequence of expressions."""
4429        if len(expressions) < 2:
4430            raise ValueError("Dot requires >= 2 expressions.")
4431
4432        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4433
4434    @property
4435    def parts(self) -> t.List[Expression]:
4436        """Return the parts of a table / column in order catalog, db, table."""
4437        this, *parts = self.flatten()
4438
4439        parts.reverse()
4440
4441        for arg in COLUMN_PARTS:
4442            part = this.args.get(arg)
4443
4444            if isinstance(part, Expression):
4445                parts.append(part)
4446
4447        parts.reverse()
4448        return parts
is_star: bool
4414    @property
4415    def is_star(self) -> bool:
4416        return self.expression.is_star

Checks whether an expression is a star.

name: str
4418    @property
4419    def name(self) -> str:
4420        return self.expression.name
output_name: str
4422    @property
4423    def output_name(self) -> str:
4424        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:
4426    @classmethod
4427    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4428        """Build a Dot object with a sequence of expressions."""
4429        if len(expressions) < 2:
4430            raise ValueError("Dot requires >= 2 expressions.")
4431
4432        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]
4434    @property
4435    def parts(self) -> t.List[Expression]:
4436        """Return the parts of a table / column in order catalog, db, table."""
4437        this, *parts = self.flatten()
4438
4439        parts.reverse()
4440
4441        for arg in COLUMN_PARTS:
4442            part = this.args.get(arg)
4443
4444            if isinstance(part, Expression):
4445                parts.append(part)
4446
4447        parts.reverse()
4448        return parts

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

key = 'dot'
class DPipe(Binary):
4451class DPipe(Binary):
4452    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4455class EQ(Binary, Predicate):
4456    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4459class NullSafeEQ(Binary, Predicate):
4460    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4463class NullSafeNEQ(Binary, Predicate):
4464    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4468class PropertyEQ(Binary):
4469    pass
key = 'propertyeq'
class Distance(Binary):
4472class Distance(Binary):
4473    pass
key = 'distance'
class Escape(Binary):
4476class Escape(Binary):
4477    pass
key = 'escape'
class Glob(Binary, Predicate):
4480class Glob(Binary, Predicate):
4481    pass
key = 'glob'
class GT(Binary, Predicate):
4484class GT(Binary, Predicate):
4485    pass
key = 'gt'
class GTE(Binary, Predicate):
4488class GTE(Binary, Predicate):
4489    pass
key = 'gte'
class ILike(Binary, Predicate):
4492class ILike(Binary, Predicate):
4493    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4496class ILikeAny(Binary, Predicate):
4497    pass
key = 'ilikeany'
class IntDiv(Binary):
4500class IntDiv(Binary):
4501    pass
key = 'intdiv'
class Is(Binary, Predicate):
4504class Is(Binary, Predicate):
4505    pass
key = 'is'
class Kwarg(Binary):
4508class Kwarg(Binary):
4509    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4512class Like(Binary, Predicate):
4513    pass
key = 'like'
class LikeAny(Binary, Predicate):
4516class LikeAny(Binary, Predicate):
4517    pass
key = 'likeany'
class LT(Binary, Predicate):
4520class LT(Binary, Predicate):
4521    pass
key = 'lt'
class LTE(Binary, Predicate):
4524class LTE(Binary, Predicate):
4525    pass
key = 'lte'
class Mod(Binary):
4528class Mod(Binary):
4529    pass
key = 'mod'
class Mul(Binary):
4532class Mul(Binary):
4533    pass
key = 'mul'
class NEQ(Binary, Predicate):
4536class NEQ(Binary, Predicate):
4537    pass
key = 'neq'
class Operator(Binary):
4541class Operator(Binary):
4542    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4545class SimilarTo(Binary, Predicate):
4546    pass
key = 'similarto'
class Slice(Binary):
4549class Slice(Binary):
4550    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4553class Sub(Binary):
4554    pass
key = 'sub'
class Unary(Condition):
4559class Unary(Condition):
4560    pass
key = 'unary'
class BitwiseNot(Unary):
4563class BitwiseNot(Unary):
4564    pass
key = 'bitwisenot'
class Not(Unary):
4567class Not(Unary):
4568    pass
key = 'not'
class Paren(Unary):
4571class Paren(Unary):
4572    @property
4573    def output_name(self) -> str:
4574        return self.this.name
output_name: str
4572    @property
4573    def output_name(self) -> str:
4574        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):
4577class Neg(Unary):
4578    def to_py(self) -> int | Decimal:
4579        if self.is_number:
4580            return self.this.to_py() * -1
4581        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4578    def to_py(self) -> int | Decimal:
4579        if self.is_number:
4580            return self.this.to_py() * -1
4581        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4584class Alias(Expression):
4585    arg_types = {"this": True, "alias": False}
4586
4587    @property
4588    def output_name(self) -> str:
4589        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4587    @property
4588    def output_name(self) -> str:
4589        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):
4594class PivotAlias(Alias):
4595    pass
key = 'pivotalias'
class PivotAny(Expression):
4600class PivotAny(Expression):
4601    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4604class Aliases(Expression):
4605    arg_types = {"this": True, "expressions": True}
4606
4607    @property
4608    def aliases(self):
4609        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4607    @property
4608    def aliases(self):
4609        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4613class AtIndex(Expression):
4614    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4617class AtTimeZone(Expression):
4618    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4621class FromTimeZone(Expression):
4622    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4625class Between(Predicate):
4626    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4629class Bracket(Condition):
4630    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4631    arg_types = {
4632        "this": True,
4633        "expressions": True,
4634        "offset": False,
4635        "safe": False,
4636        "returns_list_for_maps": False,
4637    }
4638
4639    @property
4640    def output_name(self) -> str:
4641        if len(self.expressions) == 1:
4642            return self.expressions[0].output_name
4643
4644        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4639    @property
4640    def output_name(self) -> str:
4641        if len(self.expressions) == 1:
4642            return self.expressions[0].output_name
4643
4644        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):
4647class Distinct(Expression):
4648    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4651class In(Predicate):
4652    arg_types = {
4653        "this": True,
4654        "expressions": False,
4655        "query": False,
4656        "unnest": False,
4657        "field": False,
4658        "is_global": False,
4659    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4663class ForIn(Expression):
4664    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4667class TimeUnit(Expression):
4668    """Automatically converts unit arg into a var."""
4669
4670    arg_types = {"unit": False}
4671
4672    UNABBREVIATED_UNIT_NAME = {
4673        "D": "DAY",
4674        "H": "HOUR",
4675        "M": "MINUTE",
4676        "MS": "MILLISECOND",
4677        "NS": "NANOSECOND",
4678        "Q": "QUARTER",
4679        "S": "SECOND",
4680        "US": "MICROSECOND",
4681        "W": "WEEK",
4682        "Y": "YEAR",
4683    }
4684
4685    VAR_LIKE = (Column, Literal, Var)
4686
4687    def __init__(self, **args):
4688        unit = args.get("unit")
4689        if isinstance(unit, self.VAR_LIKE):
4690            args["unit"] = Var(
4691                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4692            )
4693        elif isinstance(unit, Week):
4694            unit.set("this", Var(this=unit.this.name.upper()))
4695
4696        super().__init__(**args)
4697
4698    @property
4699    def unit(self) -> t.Optional[Var | IntervalSpan]:
4700        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4687    def __init__(self, **args):
4688        unit = args.get("unit")
4689        if isinstance(unit, self.VAR_LIKE):
4690            args["unit"] = Var(
4691                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4692            )
4693        elif isinstance(unit, Week):
4694            unit.set("this", Var(this=unit.this.name.upper()))
4695
4696        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]
4698    @property
4699    def unit(self) -> t.Optional[Var | IntervalSpan]:
4700        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4703class IntervalOp(TimeUnit):
4704    arg_types = {"unit": True, "expression": True}
4705
4706    def interval(self):
4707        return Interval(
4708            this=self.expression.copy(),
4709            unit=self.unit.copy(),
4710        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4706    def interval(self):
4707        return Interval(
4708            this=self.expression.copy(),
4709            unit=self.unit.copy(),
4710        )
key = 'intervalop'
class IntervalSpan(DataType):
4716class IntervalSpan(DataType):
4717    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4720class Interval(TimeUnit):
4721    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4724class IgnoreNulls(Expression):
4725    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4728class RespectNulls(Expression):
4729    pass
key = 'respectnulls'
class HavingMax(Expression):
4733class HavingMax(Expression):
4734    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4738class Func(Condition):
4739    """
4740    The base class for all function expressions.
4741
4742    Attributes:
4743        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4744            treated as a variable length argument and the argument's value will be stored as a list.
4745        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4746            function expression. These values are used to map this node to a name during parsing as
4747            well as to provide the function's name during SQL string generation. By default the SQL
4748            name is set to the expression's class name transformed to snake case.
4749    """
4750
4751    is_var_len_args = False
4752
4753    @classmethod
4754    def from_arg_list(cls, args):
4755        if cls.is_var_len_args:
4756            all_arg_keys = list(cls.arg_types)
4757            # If this function supports variable length argument treat the last argument as such.
4758            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4759            num_non_var = len(non_var_len_arg_keys)
4760
4761            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4762            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4763        else:
4764            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4765
4766        return cls(**args_dict)
4767
4768    @classmethod
4769    def sql_names(cls):
4770        if cls is Func:
4771            raise NotImplementedError(
4772                "SQL name is only supported by concrete function implementations"
4773            )
4774        if "_sql_names" not in cls.__dict__:
4775            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4776        return cls._sql_names
4777
4778    @classmethod
4779    def sql_name(cls):
4780        return cls.sql_names()[0]
4781
4782    @classmethod
4783    def default_parser_mappings(cls):
4784        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):
4753    @classmethod
4754    def from_arg_list(cls, args):
4755        if cls.is_var_len_args:
4756            all_arg_keys = list(cls.arg_types)
4757            # If this function supports variable length argument treat the last argument as such.
4758            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4759            num_non_var = len(non_var_len_arg_keys)
4760
4761            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4762            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4763        else:
4764            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4765
4766        return cls(**args_dict)
@classmethod
def sql_names(cls):
4768    @classmethod
4769    def sql_names(cls):
4770        if cls is Func:
4771            raise NotImplementedError(
4772                "SQL name is only supported by concrete function implementations"
4773            )
4774        if "_sql_names" not in cls.__dict__:
4775            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4776        return cls._sql_names
@classmethod
def sql_name(cls):
4778    @classmethod
4779    def sql_name(cls):
4780        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4782    @classmethod
4783    def default_parser_mappings(cls):
4784        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4787class AggFunc(Func):
4788    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4791class ParameterizedAgg(AggFunc):
4792    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4795class Abs(Func):
4796    pass
key = 'abs'
class ArgMax(AggFunc):
4799class ArgMax(AggFunc):
4800    arg_types = {"this": True, "expression": True, "count": False}
4801    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4804class ArgMin(AggFunc):
4805    arg_types = {"this": True, "expression": True, "count": False}
4806    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4809class ApproxTopK(AggFunc):
4810    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4813class Flatten(Func):
4814    pass
key = 'flatten'
class Transform(Func):
4818class Transform(Func):
4819    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4822class Anonymous(Func):
4823    arg_types = {"this": True, "expressions": False}
4824    is_var_len_args = True
4825
4826    @property
4827    def name(self) -> str:
4828        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
4826    @property
4827    def name(self) -> str:
4828        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4831class AnonymousAggFunc(AggFunc):
4832    arg_types = {"this": True, "expressions": False}
4833    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4837class CombinedAggFunc(AnonymousAggFunc):
4838    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4841class CombinedParameterizedAgg(ParameterizedAgg):
4842    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):
4847class Hll(AggFunc):
4848    arg_types = {"this": True, "expressions": False}
4849    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4852class ApproxDistinct(AggFunc):
4853    arg_types = {"this": True, "accuracy": False}
4854    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4857class Array(Func):
4858    arg_types = {"expressions": False, "bracket_notation": False}
4859    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4863class ToArray(Func):
4864    pass
key = 'toarray'
class List(Func):
4868class List(Func):
4869    arg_types = {"expressions": False}
4870    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4874class Pad(Func):
4875    arg_types = {"this": True, "expression": True, "fill_pattern": False, "is_left": True}
arg_types = {'this': True, 'expression': True, 'fill_pattern': False, 'is_left': True}
key = 'pad'
class ToChar(Func):
4880class ToChar(Func):
4881    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4886class ToNumber(Func):
4887    arg_types = {
4888        "this": True,
4889        "format": False,
4890        "nlsparam": False,
4891        "precision": False,
4892        "scale": False,
4893    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4897class Convert(Func):
4898    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
4901class ConvertTimezone(Func):
4902    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True}
key = 'converttimezone'
class GenerateSeries(Func):
4905class GenerateSeries(Func):
4906    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 ExplodingGenerateSeries(GenerateSeries):
4912class ExplodingGenerateSeries(GenerateSeries):
4913    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
4916class ArrayAgg(AggFunc):
4917    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4920class ArrayUniqueAgg(AggFunc):
4921    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4924class ArrayAll(Func):
4925    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4929class ArrayAny(Func):
4930    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4933class ArrayConcat(Func):
4934    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4935    arg_types = {"this": True, "expressions": False}
4936    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4939class ArrayConstructCompact(Func):
4940    arg_types = {"expressions": True}
4941    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4944class ArrayContains(Binary, Func):
4945    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4948class ArrayContainsAll(Binary, Func):
4949    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4952class ArrayFilter(Func):
4953    arg_types = {"this": True, "expression": True}
4954    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4957class ArrayToString(Func):
4958    arg_types = {"this": True, "expression": True, "null": False}
4959    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4962class StringToArray(Func):
4963    arg_types = {"this": True, "expression": True, "null": False}
4964    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4967class ArrayOverlaps(Binary, Func):
4968    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4971class ArraySize(Func):
4972    arg_types = {"this": True, "expression": False}
4973    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4976class ArraySort(Func):
4977    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4980class ArraySum(Func):
4981    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4984class ArrayUnionAgg(AggFunc):
4985    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4988class Avg(AggFunc):
4989    pass
key = 'avg'
class AnyValue(AggFunc):
4992class AnyValue(AggFunc):
4993    pass
key = 'anyvalue'
class Lag(AggFunc):
4996class Lag(AggFunc):
4997    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5000class Lead(AggFunc):
5001    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5006class First(AggFunc):
5007    pass
key = 'first'
class Last(AggFunc):
5010class Last(AggFunc):
5011    pass
key = 'last'
class FirstValue(AggFunc):
5014class FirstValue(AggFunc):
5015    pass
key = 'firstvalue'
class LastValue(AggFunc):
5018class LastValue(AggFunc):
5019    pass
key = 'lastvalue'
class NthValue(AggFunc):
5022class NthValue(AggFunc):
5023    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5026class Case(Func):
5027    arg_types = {"this": False, "ifs": True, "default": False}
5028
5029    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5030        instance = maybe_copy(self, copy)
5031        instance.append(
5032            "ifs",
5033            If(
5034                this=maybe_parse(condition, copy=copy, **opts),
5035                true=maybe_parse(then, copy=copy, **opts),
5036            ),
5037        )
5038        return instance
5039
5040    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5041        instance = maybe_copy(self, copy)
5042        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5043        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:
5029    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5030        instance = maybe_copy(self, copy)
5031        instance.append(
5032            "ifs",
5033            If(
5034                this=maybe_parse(condition, copy=copy, **opts),
5035                true=maybe_parse(then, copy=copy, **opts),
5036            ),
5037        )
5038        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5040    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5041        instance = maybe_copy(self, copy)
5042        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5043        return instance
key = 'case'
class Cast(Func):
5046class Cast(Func):
5047    arg_types = {
5048        "this": True,
5049        "to": True,
5050        "format": False,
5051        "safe": False,
5052        "action": False,
5053    }
5054
5055    @property
5056    def name(self) -> str:
5057        return self.this.name
5058
5059    @property
5060    def to(self) -> DataType:
5061        return self.args["to"]
5062
5063    @property
5064    def output_name(self) -> str:
5065        return self.name
5066
5067    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5068        """
5069        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5070        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5071        array<int> != array<float>.
5072
5073        Args:
5074            dtypes: the data types to compare this Cast's DataType to.
5075
5076        Returns:
5077            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5078        """
5079        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5055    @property
5056    def name(self) -> str:
5057        return self.this.name
to: DataType
5059    @property
5060    def to(self) -> DataType:
5061        return self.args["to"]
output_name: str
5063    @property
5064    def output_name(self) -> str:
5065        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:
5067    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5068        """
5069        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5070        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5071        array<int> != array<float>.
5072
5073        Args:
5074            dtypes: the data types to compare this Cast's DataType to.
5075
5076        Returns:
5077            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5078        """
5079        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):
5082class TryCast(Cast):
5083    pass
key = 'trycast'
class Try(Func):
5086class Try(Func):
5087    pass
key = 'try'
class CastToStrType(Func):
5090class CastToStrType(Func):
5091    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5094class Collate(Binary, Func):
5095    pass
key = 'collate'
class Ceil(Func):
5098class Ceil(Func):
5099    arg_types = {"this": True, "decimals": False}
5100    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5103class Coalesce(Func):
5104    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5105    is_var_len_args = True
5106    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5109class Chr(Func):
5110    arg_types = {"this": True, "charset": False, "expressions": False}
5111    is_var_len_args = True
5112    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5115class Concat(Func):
5116    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5117    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5120class ConcatWs(Concat):
5121    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5125class ConnectByRoot(Func):
5126    pass
key = 'connectbyroot'
class Count(AggFunc):
5129class Count(AggFunc):
5130    arg_types = {"this": False, "expressions": False}
5131    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5134class CountIf(AggFunc):
5135    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5139class Cbrt(Func):
5140    pass
key = 'cbrt'
class CurrentDate(Func):
5143class CurrentDate(Func):
5144    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5147class CurrentDatetime(Func):
5148    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5151class CurrentTime(Func):
5152    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5155class CurrentTimestamp(Func):
5156    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5159class CurrentUser(Func):
5160    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5163class DateAdd(Func, IntervalOp):
5164    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5167class DateSub(Func, IntervalOp):
5168    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5171class DateDiff(Func, TimeUnit):
5172    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5173    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5176class DateTrunc(Func):
5177    arg_types = {"unit": True, "this": True, "zone": False}
5178
5179    def __init__(self, **args):
5180        unit = args.get("unit")
5181        if isinstance(unit, TimeUnit.VAR_LIKE):
5182            args["unit"] = Literal.string(
5183                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5184            )
5185        elif isinstance(unit, Week):
5186            unit.set("this", Literal.string(unit.this.name.upper()))
5187
5188        super().__init__(**args)
5189
5190    @property
5191    def unit(self) -> Expression:
5192        return self.args["unit"]
DateTrunc(**args)
5179    def __init__(self, **args):
5180        unit = args.get("unit")
5181        if isinstance(unit, TimeUnit.VAR_LIKE):
5182            args["unit"] = Literal.string(
5183                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5184            )
5185        elif isinstance(unit, Week):
5186            unit.set("this", Literal.string(unit.this.name.upper()))
5187
5188        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5190    @property
5191    def unit(self) -> Expression:
5192        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5197class Datetime(Func):
5198    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5201class DatetimeAdd(Func, IntervalOp):
5202    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5205class DatetimeSub(Func, IntervalOp):
5206    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5209class DatetimeDiff(Func, TimeUnit):
5210    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5213class DatetimeTrunc(Func, TimeUnit):
5214    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5217class DayOfWeek(Func):
5218    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5221class DayOfMonth(Func):
5222    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5225class DayOfYear(Func):
5226    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5229class ToDays(Func):
5230    pass
key = 'todays'
class WeekOfYear(Func):
5233class WeekOfYear(Func):
5234    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5237class MonthsBetween(Func):
5238    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5241class LastDay(Func, TimeUnit):
5242    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5243    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5246class Extract(Func):
5247    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5250class Timestamp(Func):
5251    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5254class TimestampAdd(Func, TimeUnit):
5255    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5258class TimestampSub(Func, TimeUnit):
5259    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5262class TimestampDiff(Func, TimeUnit):
5263    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5264    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5267class TimestampTrunc(Func, TimeUnit):
5268    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5271class TimeAdd(Func, TimeUnit):
5272    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5275class TimeSub(Func, TimeUnit):
5276    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5279class TimeDiff(Func, TimeUnit):
5280    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5283class TimeTrunc(Func, TimeUnit):
5284    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5287class DateFromParts(Func):
5288    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5289    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5292class TimeFromParts(Func):
5293    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5294    arg_types = {
5295        "hour": True,
5296        "min": True,
5297        "sec": True,
5298        "nano": False,
5299        "fractions": False,
5300        "precision": False,
5301    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5304class DateStrToDate(Func):
5305    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5308class DateToDateStr(Func):
5309    pass
key = 'datetodatestr'
class DateToDi(Func):
5312class DateToDi(Func):
5313    pass
key = 'datetodi'
class Date(Func):
5317class Date(Func):
5318    arg_types = {"this": False, "zone": False, "expressions": False}
5319    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5322class Day(Func):
5323    pass
key = 'day'
class Decode(Func):
5326class Decode(Func):
5327    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5330class DiToDate(Func):
5331    pass
key = 'ditodate'
class Encode(Func):
5334class Encode(Func):
5335    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5338class Exp(Func):
5339    pass
key = 'exp'
class Explode(Func):
5343class Explode(Func):
5344    arg_types = {"this": True, "expressions": False}
5345    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5348class ExplodeOuter(Explode):
5349    pass
key = 'explodeouter'
class Posexplode(Explode):
5352class Posexplode(Explode):
5353    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5356class PosexplodeOuter(Posexplode, ExplodeOuter):
5357    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5360class Unnest(Func, UDTF):
5361    arg_types = {
5362        "expressions": True,
5363        "alias": False,
5364        "offset": False,
5365        "explode_array": False,
5366    }
5367
5368    @property
5369    def selects(self) -> t.List[Expression]:
5370        columns = super().selects
5371        offset = self.args.get("offset")
5372        if offset:
5373            columns = columns + [to_identifier("offset") if offset is True else offset]
5374        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5368    @property
5369    def selects(self) -> t.List[Expression]:
5370        columns = super().selects
5371        offset = self.args.get("offset")
5372        if offset:
5373            columns = columns + [to_identifier("offset") if offset is True else offset]
5374        return columns
key = 'unnest'
class Floor(Func):
5377class Floor(Func):
5378    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5381class FromBase64(Func):
5382    pass
key = 'frombase64'
class ToBase64(Func):
5385class ToBase64(Func):
5386    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5390class FromISO8601Timestamp(Func):
5391    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5394class GapFill(Func):
5395    arg_types = {
5396        "this": True,
5397        "ts_column": True,
5398        "bucket_width": True,
5399        "partitioning_columns": False,
5400        "value_columns": False,
5401        "origin": False,
5402        "ignore_nulls": False,
5403    }
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):
5407class GenerateDateArray(Func):
5408    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5412class GenerateTimestampArray(Func):
5413    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5416class Greatest(Func):
5417    arg_types = {"this": True, "expressions": False}
5418    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5421class GroupConcat(AggFunc):
5422    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5425class Hex(Func):
5426    pass
key = 'hex'
class LowerHex(Hex):
5429class LowerHex(Hex):
5430    pass
key = 'lowerhex'
class Xor(Connector, Func):
5433class Xor(Connector, Func):
5434    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5437class If(Func):
5438    arg_types = {"this": True, "true": True, "false": False}
5439    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5442class Nullif(Func):
5443    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5446class Initcap(Func):
5447    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5450class IsNan(Func):
5451    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5454class IsInf(Func):
5455    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5459class JSON(Expression):
5460    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5463class JSONPath(Expression):
5464    arg_types = {"expressions": True}
5465
5466    @property
5467    def output_name(self) -> str:
5468        last_segment = self.expressions[-1].this
5469        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5466    @property
5467    def output_name(self) -> str:
5468        last_segment = self.expressions[-1].this
5469        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):
5472class JSONPathPart(Expression):
5473    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5476class JSONPathFilter(JSONPathPart):
5477    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5480class JSONPathKey(JSONPathPart):
5481    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5484class JSONPathRecursive(JSONPathPart):
5485    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5488class JSONPathRoot(JSONPathPart):
5489    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5492class JSONPathScript(JSONPathPart):
5493    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5496class JSONPathSlice(JSONPathPart):
5497    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5500class JSONPathSelector(JSONPathPart):
5501    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5504class JSONPathSubscript(JSONPathPart):
5505    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5508class JSONPathUnion(JSONPathPart):
5509    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5512class JSONPathWildcard(JSONPathPart):
5513    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5516class FormatJson(Expression):
5517    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5520class JSONKeyValue(Expression):
5521    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5524class JSONObject(Func):
5525    arg_types = {
5526        "expressions": False,
5527        "null_handling": False,
5528        "unique_keys": False,
5529        "return_type": False,
5530        "encoding": False,
5531    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5534class JSONObjectAgg(AggFunc):
5535    arg_types = {
5536        "expressions": False,
5537        "null_handling": False,
5538        "unique_keys": False,
5539        "return_type": False,
5540        "encoding": False,
5541    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5545class JSONArray(Func):
5546    arg_types = {
5547        "expressions": True,
5548        "null_handling": False,
5549        "return_type": False,
5550        "strict": False,
5551    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5555class JSONArrayAgg(Func):
5556    arg_types = {
5557        "this": True,
5558        "order": False,
5559        "null_handling": False,
5560        "return_type": False,
5561        "strict": False,
5562    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5567class JSONColumnDef(Expression):
5568    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):
5571class JSONSchema(Expression):
5572    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
5576class JSONValue(Expression):
5577    arg_types = {
5578        "this": True,
5579        "path": True,
5580        "returning": False,
5581        "on_empty": False,
5582        "on_error": False,
5583    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_empty': False, 'on_error': False}
key = 'jsonvalue'
class JSONTable(Func):
5587class JSONTable(Func):
5588    arg_types = {
5589        "this": True,
5590        "schema": True,
5591        "path": False,
5592        "error_handling": False,
5593        "empty_handling": False,
5594    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5598class ObjectInsert(Func):
5599    arg_types = {
5600        "this": True,
5601        "key": True,
5602        "value": True,
5603        "update_flag": False,
5604    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5607class OpenJSONColumnDef(Expression):
5608    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):
5611class OpenJSON(Func):
5612    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5615class JSONBContains(Binary, Func):
5616    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5619class JSONExtract(Binary, Func):
5620    arg_types = {
5621        "this": True,
5622        "expression": True,
5623        "only_json_types": False,
5624        "expressions": False,
5625        "variant_extract": False,
5626    }
5627    _sql_names = ["JSON_EXTRACT"]
5628    is_var_len_args = True
5629
5630    @property
5631    def output_name(self) -> str:
5632        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False, 'variant_extract': False}
is_var_len_args = True
output_name: str
5630    @property
5631    def output_name(self) -> str:
5632        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):
5635class JSONExtractScalar(Binary, Func):
5636    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5637    _sql_names = ["JSON_EXTRACT_SCALAR"]
5638    is_var_len_args = True
5639
5640    @property
5641    def output_name(self) -> str:
5642        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
5640    @property
5641    def output_name(self) -> str:
5642        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):
5645class JSONBExtract(Binary, Func):
5646    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5649class JSONBExtractScalar(Binary, Func):
5650    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5653class JSONFormat(Func):
5654    arg_types = {"this": False, "options": False}
5655    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5659class JSONArrayContains(Binary, Predicate, Func):
5660    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5663class ParseJSON(Func):
5664    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5665    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5666    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5667    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5670class Least(Func):
5671    arg_types = {"this": True, "expressions": False}
5672    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5675class Left(Func):
5676    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5683class Length(Func):
5684    arg_types = {"this": True, "binary": False}
5685    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5688class Levenshtein(Func):
5689    arg_types = {
5690        "this": True,
5691        "expression": False,
5692        "ins_cost": False,
5693        "del_cost": False,
5694        "sub_cost": False,
5695    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5698class Ln(Func):
5699    pass
key = 'ln'
class Log(Func):
5702class Log(Func):
5703    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5706class LogicalOr(AggFunc):
5707    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5710class LogicalAnd(AggFunc):
5711    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5714class Lower(Func):
5715    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5718class Map(Func):
5719    arg_types = {"keys": False, "values": False}
5720
5721    @property
5722    def keys(self) -> t.List[Expression]:
5723        keys = self.args.get("keys")
5724        return keys.expressions if keys else []
5725
5726    @property
5727    def values(self) -> t.List[Expression]:
5728        values = self.args.get("values")
5729        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5721    @property
5722    def keys(self) -> t.List[Expression]:
5723        keys = self.args.get("keys")
5724        return keys.expressions if keys else []
values: List[Expression]
5726    @property
5727    def values(self) -> t.List[Expression]:
5728        values = self.args.get("values")
5729        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5733class ToMap(Func):
5734    pass
key = 'tomap'
class MapFromEntries(Func):
5737class MapFromEntries(Func):
5738    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5742class ScopeResolution(Expression):
5743    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
5746class Stream(Expression):
5747    pass
key = 'stream'
class StarMap(Func):
5750class StarMap(Func):
5751    pass
key = 'starmap'
class VarMap(Func):
5754class VarMap(Func):
5755    arg_types = {"keys": True, "values": True}
5756    is_var_len_args = True
5757
5758    @property
5759    def keys(self) -> t.List[Expression]:
5760        return self.args["keys"].expressions
5761
5762    @property
5763    def values(self) -> t.List[Expression]:
5764        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5758    @property
5759    def keys(self) -> t.List[Expression]:
5760        return self.args["keys"].expressions
values: List[Expression]
5762    @property
5763    def values(self) -> t.List[Expression]:
5764        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5768class MatchAgainst(Func):
5769    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5772class Max(AggFunc):
5773    arg_types = {"this": True, "expressions": False}
5774    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5777class MD5(Func):
5778    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5782class MD5Digest(Func):
5783    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5786class Min(AggFunc):
5787    arg_types = {"this": True, "expressions": False}
5788    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5791class Month(Func):
5792    pass
key = 'month'
class AddMonths(Func):
5795class AddMonths(Func):
5796    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5799class Nvl2(Func):
5800    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5804class Predict(Func):
5805    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5808class Pow(Binary, Func):
5809    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5812class PercentileCont(AggFunc):
5813    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5816class PercentileDisc(AggFunc):
5817    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5820class Quantile(AggFunc):
5821    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5824class ApproxQuantile(Quantile):
5825    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):
5828class Quarter(Func):
5829    pass
key = 'quarter'
class Rand(Func):
5834class Rand(Func):
5835    _sql_names = ["RAND", "RANDOM"]
5836    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5839class Randn(Func):
5840    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5843class RangeN(Func):
5844    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5847class ReadCSV(Func):
5848    _sql_names = ["READ_CSV"]
5849    is_var_len_args = True
5850    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5853class Reduce(Func):
5854    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):
5857class RegexpExtract(Func):
5858    arg_types = {
5859        "this": True,
5860        "expression": True,
5861        "position": False,
5862        "occurrence": False,
5863        "parameters": False,
5864        "group": False,
5865    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5868class RegexpReplace(Func):
5869    arg_types = {
5870        "this": True,
5871        "expression": True,
5872        "replacement": False,
5873        "position": False,
5874        "occurrence": False,
5875        "modifiers": False,
5876    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5879class RegexpLike(Binary, Func):
5880    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5883class RegexpILike(Binary, Func):
5884    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5889class RegexpSplit(Func):
5890    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5893class Repeat(Func):
5894    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5899class Round(Func):
5900    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5903class RowNumber(Func):
5904    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5907class SafeDivide(Func):
5908    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5911class SHA(Func):
5912    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5915class SHA2(Func):
5916    _sql_names = ["SHA2"]
5917    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5920class Sign(Func):
5921    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5924class SortArray(Func):
5925    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5928class Split(Func):
5929    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5934class Substring(Func):
5935    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5938class StandardHash(Func):
5939    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5942class StartsWith(Func):
5943    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5944    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5947class StrPosition(Func):
5948    arg_types = {
5949        "this": True,
5950        "substr": True,
5951        "position": False,
5952        "instance": False,
5953    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5956class StrToDate(Func):
5957    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
5960class StrToTime(Func):
5961    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):
5966class StrToUnix(Func):
5967    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5972class StrToMap(Func):
5973    arg_types = {
5974        "this": True,
5975        "pair_delim": False,
5976        "key_value_delim": False,
5977        "duplicate_resolution_callback": False,
5978    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5981class NumberToStr(Func):
5982    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5985class FromBase(Func):
5986    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5989class Struct(Func):
5990    arg_types = {"expressions": False}
5991    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5994class StructExtract(Func):
5995    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6000class Stuff(Func):
6001    _sql_names = ["STUFF", "INSERT"]
6002    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):
6005class Sum(AggFunc):
6006    pass
key = 'sum'
class Sqrt(Func):
6009class Sqrt(Func):
6010    pass
key = 'sqrt'
class Stddev(AggFunc):
6013class Stddev(AggFunc):
6014    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6017class StddevPop(AggFunc):
6018    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6021class StddevSamp(AggFunc):
6022    pass
key = 'stddevsamp'
class Time(Func):
6026class Time(Func):
6027    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6030class TimeToStr(Func):
6031    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
arg_types = {'this': True, 'format': True, 'culture': False, 'zone': False}
key = 'timetostr'
class TimeToTimeStr(Func):
6034class TimeToTimeStr(Func):
6035    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6038class TimeToUnix(Func):
6039    pass
key = 'timetounix'
class TimeStrToDate(Func):
6042class TimeStrToDate(Func):
6043    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6046class TimeStrToTime(Func):
6047    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6050class TimeStrToUnix(Func):
6051    pass
key = 'timestrtounix'
class Trim(Func):
6054class Trim(Func):
6055    arg_types = {
6056        "this": True,
6057        "expression": False,
6058        "position": False,
6059        "collation": False,
6060    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6063class TsOrDsAdd(Func, TimeUnit):
6064    # return_type is used to correctly cast the arguments of this expression when transpiling it
6065    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6066
6067    @property
6068    def return_type(self) -> DataType:
6069        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
6067    @property
6068    def return_type(self) -> DataType:
6069        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6072class TsOrDsDiff(Func, TimeUnit):
6073    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6076class TsOrDsToDateStr(Func):
6077    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6080class TsOrDsToDate(Func):
6081    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6084class TsOrDsToTime(Func):
6085    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6088class TsOrDsToTimestamp(Func):
6089    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6092class TsOrDiToDi(Func):
6093    pass
key = 'tsorditodi'
class Unhex(Func):
6096class Unhex(Func):
6097    pass
key = 'unhex'
class UnixDate(Func):
6101class UnixDate(Func):
6102    pass
key = 'unixdate'
class UnixToStr(Func):
6105class UnixToStr(Func):
6106    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6111class UnixToTime(Func):
6112    arg_types = {
6113        "this": True,
6114        "scale": False,
6115        "zone": False,
6116        "hours": False,
6117        "minutes": False,
6118        "format": False,
6119    }
6120
6121    SECONDS = Literal.number(0)
6122    DECIS = Literal.number(1)
6123    CENTIS = Literal.number(2)
6124    MILLIS = Literal.number(3)
6125    DECIMILLIS = Literal.number(4)
6126    CENTIMILLIS = Literal.number(5)
6127    MICROS = Literal.number(6)
6128    DECIMICROS = Literal.number(7)
6129    CENTIMICROS = Literal.number(8)
6130    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):
6133class UnixToTimeStr(Func):
6134    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
6137class TimestampFromParts(Func):
6138    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6139    arg_types = {
6140        "year": True,
6141        "month": True,
6142        "day": True,
6143        "hour": True,
6144        "min": True,
6145        "sec": True,
6146        "nano": False,
6147        "zone": False,
6148        "milli": False,
6149    }
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):
6152class Upper(Func):
6153    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6156class Corr(Binary, AggFunc):
6157    pass
key = 'corr'
class Variance(AggFunc):
6160class Variance(AggFunc):
6161    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6164class VariancePop(AggFunc):
6165    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6168class CovarSamp(Binary, AggFunc):
6169    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6172class CovarPop(Binary, AggFunc):
6173    pass
key = 'covarpop'
class Week(Func):
6176class Week(Func):
6177    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6180class XMLTable(Func):
6181    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):
6184class Year(Func):
6185    pass
key = 'year'
class Use(Expression):
6188class Use(Expression):
6189    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6192class Merge(Expression):
6193    arg_types = {
6194        "this": True,
6195        "using": True,
6196        "on": True,
6197        "expressions": True,
6198        "with": False,
6199    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6202class When(Func):
6203    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):
6208class NextValueFor(Func):
6209    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6214class Semicolon(Expression):
6215    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 'ConvertTimezone'>, <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 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <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 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Pad'>, <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'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, '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'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, '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'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PAD': <class 'Pad'>, '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'>, 'STDEV': <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:
6255def maybe_parse(
6256    sql_or_expression: ExpOrStr,
6257    *,
6258    into: t.Optional[IntoType] = None,
6259    dialect: DialectType = None,
6260    prefix: t.Optional[str] = None,
6261    copy: bool = False,
6262    **opts,
6263) -> Expression:
6264    """Gracefully handle a possible string or expression.
6265
6266    Example:
6267        >>> maybe_parse("1")
6268        Literal(this=1, is_string=False)
6269        >>> maybe_parse(to_identifier("x"))
6270        Identifier(this=x, quoted=False)
6271
6272    Args:
6273        sql_or_expression: the SQL code string or an expression
6274        into: the SQLGlot Expression to parse into
6275        dialect: the dialect used to parse the input expressions (in the case that an
6276            input expression is a SQL string).
6277        prefix: a string to prefix the sql with before it gets parsed
6278            (automatically includes a space)
6279        copy: whether to copy the expression.
6280        **opts: other options to use to parse the input expressions (again, in the case
6281            that an input expression is a SQL string).
6282
6283    Returns:
6284        Expression: the parsed or given expression.
6285    """
6286    if isinstance(sql_or_expression, Expression):
6287        if copy:
6288            return sql_or_expression.copy()
6289        return sql_or_expression
6290
6291    if sql_or_expression is None:
6292        raise ParseError("SQL cannot be None")
6293
6294    import sqlglot
6295
6296    sql = str(sql_or_expression)
6297    if prefix:
6298        sql = f"{prefix} {sql}"
6299
6300    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):
6311def maybe_copy(instance, copy=True):
6312    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:
6532def union(
6533    left: ExpOrStr,
6534    right: ExpOrStr,
6535    distinct: bool = True,
6536    dialect: DialectType = None,
6537    copy: bool = True,
6538    **opts,
6539) -> Union:
6540    """
6541    Initializes a syntax tree from one UNION expression.
6542
6543    Example:
6544        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6545        'SELECT * FROM foo UNION SELECT * FROM bla'
6546
6547    Args:
6548        left: the SQL code string corresponding to the left-hand side.
6549            If an `Expression` instance is passed, it will be used as-is.
6550        right: the SQL code string corresponding to the right-hand side.
6551            If an `Expression` instance is passed, it will be used as-is.
6552        distinct: set the DISTINCT flag if and only if this is true.
6553        dialect: the dialect used to parse the input expression.
6554        copy: whether to copy the expression.
6555        opts: other options to use to parse the input expressions.
6556
6557    Returns:
6558        The new Union instance.
6559    """
6560    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6561    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6562
6563    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:
6566def intersect(
6567    left: ExpOrStr,
6568    right: ExpOrStr,
6569    distinct: bool = True,
6570    dialect: DialectType = None,
6571    copy: bool = True,
6572    **opts,
6573) -> Intersect:
6574    """
6575    Initializes a syntax tree from one INTERSECT expression.
6576
6577    Example:
6578        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6579        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6580
6581    Args:
6582        left: the SQL code string corresponding to the left-hand side.
6583            If an `Expression` instance is passed, it will be used as-is.
6584        right: the SQL code string corresponding to the right-hand side.
6585            If an `Expression` instance is passed, it will be used as-is.
6586        distinct: set the DISTINCT flag if and only if this is true.
6587        dialect: the dialect used to parse the input expression.
6588        copy: whether to copy the expression.
6589        opts: other options to use to parse the input expressions.
6590
6591    Returns:
6592        The new Intersect instance.
6593    """
6594    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6595    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6596
6597    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:
6600def except_(
6601    left: ExpOrStr,
6602    right: ExpOrStr,
6603    distinct: bool = True,
6604    dialect: DialectType = None,
6605    copy: bool = True,
6606    **opts,
6607) -> Except:
6608    """
6609    Initializes a syntax tree from one EXCEPT expression.
6610
6611    Example:
6612        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6613        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6614
6615    Args:
6616        left: the SQL code string corresponding to the left-hand side.
6617            If an `Expression` instance is passed, it will be used as-is.
6618        right: the SQL code string corresponding to the right-hand side.
6619            If an `Expression` instance is passed, it will be used as-is.
6620        distinct: set the DISTINCT flag if and only if this is true.
6621        dialect: the dialect used to parse the input expression.
6622        copy: whether to copy the expression.
6623        opts: other options to use to parse the input expressions.
6624
6625    Returns:
6626        The new Except instance.
6627    """
6628    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6629    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6630
6631    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:
6634def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6635    """
6636    Initializes a syntax tree from one or multiple SELECT expressions.
6637
6638    Example:
6639        >>> select("col1", "col2").from_("tbl").sql()
6640        'SELECT col1, col2 FROM tbl'
6641
6642    Args:
6643        *expressions: the SQL code string to parse as the expressions of a
6644            SELECT statement. If an Expression instance is passed, this is used as-is.
6645        dialect: the dialect used to parse the input expressions (in the case that an
6646            input expression is a SQL string).
6647        **opts: other options to use to parse the input expressions (again, in the case
6648            that an input expression is a SQL string).
6649
6650    Returns:
6651        Select: the syntax tree for the SELECT statement.
6652    """
6653    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:
6656def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6657    """
6658    Initializes a syntax tree from a FROM expression.
6659
6660    Example:
6661        >>> from_("tbl").select("col1", "col2").sql()
6662        'SELECT col1, col2 FROM tbl'
6663
6664    Args:
6665        *expression: the SQL code string to parse as the FROM expressions of a
6666            SELECT statement. If an Expression instance is passed, this is used as-is.
6667        dialect: the dialect used to parse the input expression (in the case that the
6668            input expression is a SQL string).
6669        **opts: other options to use to parse the input expressions (again, in the case
6670            that the input expression is a SQL string).
6671
6672    Returns:
6673        Select: the syntax tree for the SELECT statement.
6674    """
6675    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:
6678def update(
6679    table: str | Table,
6680    properties: dict,
6681    where: t.Optional[ExpOrStr] = None,
6682    from_: t.Optional[ExpOrStr] = None,
6683    dialect: DialectType = None,
6684    **opts,
6685) -> Update:
6686    """
6687    Creates an update statement.
6688
6689    Example:
6690        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6691        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6692
6693    Args:
6694        *properties: dictionary of properties to set which are
6695            auto converted to sql objects eg None -> NULL
6696        where: sql conditional parsed into a WHERE statement
6697        from_: sql statement parsed into a FROM statement
6698        dialect: the dialect used to parse the input expressions.
6699        **opts: other options to use to parse the input expressions.
6700
6701    Returns:
6702        Update: the syntax tree for the UPDATE statement.
6703    """
6704    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6705    update_expr.set(
6706        "expressions",
6707        [
6708            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6709            for k, v in properties.items()
6710        ],
6711    )
6712    if from_:
6713        update_expr.set(
6714            "from",
6715            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6716        )
6717    if isinstance(where, Condition):
6718        where = Where(this=where)
6719    if where:
6720        update_expr.set(
6721            "where",
6722            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6723        )
6724    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:
6727def delete(
6728    table: ExpOrStr,
6729    where: t.Optional[ExpOrStr] = None,
6730    returning: t.Optional[ExpOrStr] = None,
6731    dialect: DialectType = None,
6732    **opts,
6733) -> Delete:
6734    """
6735    Builds a delete statement.
6736
6737    Example:
6738        >>> delete("my_table", where="id > 1").sql()
6739        'DELETE FROM my_table WHERE id > 1'
6740
6741    Args:
6742        where: sql conditional parsed into a WHERE statement
6743        returning: sql conditional parsed into a RETURNING statement
6744        dialect: the dialect used to parse the input expressions.
6745        **opts: other options to use to parse the input expressions.
6746
6747    Returns:
6748        Delete: the syntax tree for the DELETE statement.
6749    """
6750    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6751    if where:
6752        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6753    if returning:
6754        delete_expr = t.cast(
6755            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6756        )
6757    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:
6760def insert(
6761    expression: ExpOrStr,
6762    into: ExpOrStr,
6763    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6764    overwrite: t.Optional[bool] = None,
6765    returning: t.Optional[ExpOrStr] = None,
6766    dialect: DialectType = None,
6767    copy: bool = True,
6768    **opts,
6769) -> Insert:
6770    """
6771    Builds an INSERT statement.
6772
6773    Example:
6774        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6775        'INSERT INTO tbl VALUES (1, 2, 3)'
6776
6777    Args:
6778        expression: the sql string or expression of the INSERT statement
6779        into: the tbl to insert data to.
6780        columns: optionally the table's column names.
6781        overwrite: whether to INSERT OVERWRITE or not.
6782        returning: sql conditional parsed into a RETURNING statement
6783        dialect: the dialect used to parse the input expressions.
6784        copy: whether to copy the expression.
6785        **opts: other options to use to parse the input expressions.
6786
6787    Returns:
6788        Insert: the syntax tree for the INSERT statement.
6789    """
6790    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6791    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6792
6793    if columns:
6794        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6795
6796    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6797
6798    if returning:
6799        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6800
6801    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:
6804def condition(
6805    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6806) -> Condition:
6807    """
6808    Initialize a logical condition expression.
6809
6810    Example:
6811        >>> condition("x=1").sql()
6812        'x = 1'
6813
6814        This is helpful for composing larger logical syntax trees:
6815        >>> where = condition("x=1")
6816        >>> where = where.and_("y=1")
6817        >>> Select().from_("tbl").select("*").where(where).sql()
6818        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6819
6820    Args:
6821        *expression: the SQL code string to parse.
6822            If an Expression instance is passed, this is used as-is.
6823        dialect: the dialect used to parse the input expression (in the case that the
6824            input expression is a SQL string).
6825        copy: Whether to copy `expression` (only applies to expressions).
6826        **opts: other options to use to parse the input expressions (again, in the case
6827            that the input expression is a SQL string).
6828
6829    Returns:
6830        The new Condition instance
6831    """
6832    return maybe_parse(
6833        expression,
6834        into=Condition,
6835        dialect=dialect,
6836        copy=copy,
6837        **opts,
6838    )

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:
6841def and_(
6842    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6843) -> Condition:
6844    """
6845    Combine multiple conditions with an AND logical operator.
6846
6847    Example:
6848        >>> and_("x=1", and_("y=1", "z=1")).sql()
6849        'x = 1 AND (y = 1 AND z = 1)'
6850
6851    Args:
6852        *expressions: the SQL code strings to parse.
6853            If an Expression instance is passed, this is used as-is.
6854        dialect: the dialect used to parse the input expression.
6855        copy: whether to copy `expressions` (only applies to Expressions).
6856        **opts: other options to use to parse the input expressions.
6857
6858    Returns:
6859        The new condition
6860    """
6861    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:
6864def or_(
6865    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6866) -> Condition:
6867    """
6868    Combine multiple conditions with an OR logical operator.
6869
6870    Example:
6871        >>> or_("x=1", or_("y=1", "z=1")).sql()
6872        'x = 1 OR (y = 1 OR z = 1)'
6873
6874    Args:
6875        *expressions: the SQL code strings to parse.
6876            If an Expression instance is passed, this is used as-is.
6877        dialect: the dialect used to parse the input expression.
6878        copy: whether to copy `expressions` (only applies to Expressions).
6879        **opts: other options to use to parse the input expressions.
6880
6881    Returns:
6882        The new condition
6883    """
6884    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:
6887def xor(
6888    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6889) -> Condition:
6890    """
6891    Combine multiple conditions with an XOR logical operator.
6892
6893    Example:
6894        >>> xor("x=1", xor("y=1", "z=1")).sql()
6895        'x = 1 XOR (y = 1 XOR z = 1)'
6896
6897    Args:
6898        *expressions: the SQL code strings to parse.
6899            If an Expression instance is passed, this is used as-is.
6900        dialect: the dialect used to parse the input expression.
6901        copy: whether to copy `expressions` (only applies to Expressions).
6902        **opts: other options to use to parse the input expressions.
6903
6904    Returns:
6905        The new condition
6906    """
6907    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:
6910def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6911    """
6912    Wrap a condition with a NOT operator.
6913
6914    Example:
6915        >>> not_("this_suit='black'").sql()
6916        "NOT this_suit = 'black'"
6917
6918    Args:
6919        expression: the SQL code string to parse.
6920            If an Expression instance is passed, this is used as-is.
6921        dialect: the dialect used to parse the input expression.
6922        copy: whether to copy the expression or not.
6923        **opts: other options to use to parse the input expressions.
6924
6925    Returns:
6926        The new condition.
6927    """
6928    this = condition(
6929        expression,
6930        dialect=dialect,
6931        copy=copy,
6932        **opts,
6933    )
6934    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:
6937def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6938    """
6939    Wrap an expression in parentheses.
6940
6941    Example:
6942        >>> paren("5 + 3").sql()
6943        '(5 + 3)'
6944
6945    Args:
6946        expression: the SQL code string to parse.
6947            If an Expression instance is passed, this is used as-is.
6948        copy: whether to copy the expression or not.
6949
6950    Returns:
6951        The wrapped expression.
6952    """
6953    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):
6969def to_identifier(name, quoted=None, copy=True):
6970    """Builds an identifier.
6971
6972    Args:
6973        name: The name to turn into an identifier.
6974        quoted: Whether to force quote the identifier.
6975        copy: Whether to copy name if it's an Identifier.
6976
6977    Returns:
6978        The identifier ast node.
6979    """
6980
6981    if name is None:
6982        return None
6983
6984    if isinstance(name, Identifier):
6985        identifier = maybe_copy(name, copy)
6986    elif isinstance(name, str):
6987        identifier = Identifier(
6988            this=name,
6989            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6990        )
6991    else:
6992        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6993    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:
6996def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6997    """
6998    Parses a given string into an identifier.
6999
7000    Args:
7001        name: The name to parse into an identifier.
7002        dialect: The dialect to parse against.
7003
7004    Returns:
7005        The identifier ast node.
7006    """
7007    try:
7008        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7009    except (ParseError, TokenError):
7010        expression = to_identifier(name)
7011
7012    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:
7018def to_interval(interval: str | Literal) -> Interval:
7019    """Builds an interval expression from a string like '1 day' or '5 months'."""
7020    if isinstance(interval, Literal):
7021        if not interval.is_string:
7022            raise ValueError("Invalid interval string.")
7023
7024        interval = interval.this
7025
7026    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
7027
7028    if not interval_parts:
7029        raise ValueError("Invalid interval string.")
7030
7031    return Interval(
7032        this=Literal.string(interval_parts.group(1)),
7033        unit=Var(this=interval_parts.group(2).upper()),
7034    )

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:
7037def to_table(
7038    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7039) -> Table:
7040    """
7041    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7042    If a table is passed in then that table is returned.
7043
7044    Args:
7045        sql_path: a `[catalog].[schema].[table]` string.
7046        dialect: the source dialect according to which the table name will be parsed.
7047        copy: Whether to copy a table if it is passed in.
7048        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7049
7050    Returns:
7051        A table expression.
7052    """
7053    if isinstance(sql_path, Table):
7054        return maybe_copy(sql_path, copy=copy)
7055
7056    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7057
7058    for k, v in kwargs.items():
7059        table.set(k, v)
7060
7061    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:
7064def to_column(
7065    sql_path: str | Column,
7066    quoted: t.Optional[bool] = None,
7067    dialect: DialectType = None,
7068    copy: bool = True,
7069    **kwargs,
7070) -> Column:
7071    """
7072    Create a column from a `[table].[column]` sql path. Table is optional.
7073    If a column is passed in then that column is returned.
7074
7075    Args:
7076        sql_path: a `[table].[column]` string.
7077        quoted: Whether or not to force quote identifiers.
7078        dialect: the source dialect according to which the column name will be parsed.
7079        copy: Whether to copy a column if it is passed in.
7080        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7081
7082    Returns:
7083        A column expression.
7084    """
7085    if isinstance(sql_path, Column):
7086        return maybe_copy(sql_path, copy=copy)
7087
7088    try:
7089        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7090    except ParseError:
7091        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7092
7093    for k, v in kwargs.items():
7094        col.set(k, v)
7095
7096    if quoted:
7097        for i in col.find_all(Identifier):
7098            i.set("quoted", True)
7099
7100    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):
7103def alias_(
7104    expression: ExpOrStr,
7105    alias: t.Optional[str | Identifier],
7106    table: bool | t.Sequence[str | Identifier] = False,
7107    quoted: t.Optional[bool] = None,
7108    dialect: DialectType = None,
7109    copy: bool = True,
7110    **opts,
7111):
7112    """Create an Alias expression.
7113
7114    Example:
7115        >>> alias_('foo', 'bar').sql()
7116        'foo AS bar'
7117
7118        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7119        '(SELECT 1, 2) AS bar(a, b)'
7120
7121    Args:
7122        expression: the SQL code strings to parse.
7123            If an Expression instance is passed, this is used as-is.
7124        alias: the alias name to use. If the name has
7125            special characters it is quoted.
7126        table: Whether to create a table alias, can also be a list of columns.
7127        quoted: whether to quote the alias
7128        dialect: the dialect used to parse the input expression.
7129        copy: Whether to copy the expression.
7130        **opts: other options to use to parse the input expressions.
7131
7132    Returns:
7133        Alias: the aliased expression
7134    """
7135    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7136    alias = to_identifier(alias, quoted=quoted)
7137
7138    if table:
7139        table_alias = TableAlias(this=alias)
7140        exp.set("alias", table_alias)
7141
7142        if not isinstance(table, bool):
7143            for column in table:
7144                table_alias.append("columns", to_identifier(column, quoted=quoted))
7145
7146        return exp
7147
7148    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7149    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7150    # for the complete Window expression.
7151    #
7152    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7153
7154    if "alias" in exp.arg_types and not isinstance(exp, Window):
7155        exp.set("alias", alias)
7156        return exp
7157    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:
7160def subquery(
7161    expression: ExpOrStr,
7162    alias: t.Optional[Identifier | str] = None,
7163    dialect: DialectType = None,
7164    **opts,
7165) -> Select:
7166    """
7167    Build a subquery expression that's selected from.
7168
7169    Example:
7170        >>> subquery('select x from tbl', 'bar').select('x').sql()
7171        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7172
7173    Args:
7174        expression: the SQL code strings to parse.
7175            If an Expression instance is passed, this is used as-is.
7176        alias: the alias name to use.
7177        dialect: the dialect used to parse the input expression.
7178        **opts: other options to use to parse the input expressions.
7179
7180    Returns:
7181        A new Select instance with the subquery expression included.
7182    """
7183
7184    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7185    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):
7216def column(
7217    col,
7218    table=None,
7219    db=None,
7220    catalog=None,
7221    *,
7222    fields=None,
7223    quoted=None,
7224    copy=True,
7225):
7226    """
7227    Build a Column.
7228
7229    Args:
7230        col: Column name.
7231        table: Table name.
7232        db: Database name.
7233        catalog: Catalog name.
7234        fields: Additional fields using dots.
7235        quoted: Whether to force quotes on the column's identifiers.
7236        copy: Whether to copy identifiers if passed in.
7237
7238    Returns:
7239        The new Column instance.
7240    """
7241    this = Column(
7242        this=to_identifier(col, quoted=quoted, copy=copy),
7243        table=to_identifier(table, quoted=quoted, copy=copy),
7244        db=to_identifier(db, quoted=quoted, copy=copy),
7245        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7246    )
7247
7248    if fields:
7249        this = Dot.build(
7250            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7251        )
7252    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, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Cast:
7255def cast(
7256    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7257) -> Cast:
7258    """Cast an expression to a data type.
7259
7260    Example:
7261        >>> cast('x + 1', 'int').sql()
7262        'CAST(x + 1 AS INT)'
7263
7264    Args:
7265        expression: The expression to cast.
7266        to: The datatype to cast to.
7267        copy: Whether to copy the supplied expressions.
7268        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7269            - The expression to be cast is already a exp.Cast expression
7270            - The existing cast is to a type that is logically equivalent to new type
7271
7272            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7273            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7274            and instead just return the original expression `CAST(x as DATETIME)`.
7275
7276            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7277            mapping is applied in the target dialect generator.
7278
7279    Returns:
7280        The new Cast instance.
7281    """
7282    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
7283    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
7284
7285    # dont re-cast if the expression is already a cast to the correct type
7286    if isinstance(expr, Cast):
7287        from sqlglot.dialects.dialect import Dialect
7288
7289        target_dialect = Dialect.get_or_raise(dialect)
7290        type_mapping = target_dialect.generator_class.TYPE_MAPPING
7291
7292        existing_cast_type: DataType.Type = expr.to.this
7293        new_cast_type: DataType.Type = data_type.this
7294        types_are_equivalent = type_mapping.get(
7295            existing_cast_type, existing_cast_type
7296        ) == type_mapping.get(new_cast_type, new_cast_type)
7297        if expr.is_type(data_type) or types_are_equivalent:
7298            return expr
7299
7300    expr = Cast(this=expr, to=data_type)
7301    expr.type = data_type
7302
7303    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.
  • dialect: The target dialect. This is used to prevent a re-cast in the following scenario:

    • The expression to be cast is already a exp.Cast expression
    • The existing cast is to a type that is logically equivalent to new type

    For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP, but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return CAST(x (as DATETIME) as TIMESTAMP) and instead just return the original expression CAST(x as DATETIME).

    This is to prevent it being output as a double cast CAST(x (as TIMESTAMP) as TIMESTAMP) once the DATETIME -> TIMESTAMP mapping is applied in the target dialect generator.

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:
7306def table_(
7307    table: Identifier | str,
7308    db: t.Optional[Identifier | str] = None,
7309    catalog: t.Optional[Identifier | str] = None,
7310    quoted: t.Optional[bool] = None,
7311    alias: t.Optional[Identifier | str] = None,
7312) -> Table:
7313    """Build a Table.
7314
7315    Args:
7316        table: Table name.
7317        db: Database name.
7318        catalog: Catalog name.
7319        quote: Whether to force quotes on the table's identifiers.
7320        alias: Table's alias.
7321
7322    Returns:
7323        The new Table instance.
7324    """
7325    return Table(
7326        this=to_identifier(table, quoted=quoted) if table else None,
7327        db=to_identifier(db, quoted=quoted) if db else None,
7328        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7329        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7330    )

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:
7333def values(
7334    values: t.Iterable[t.Tuple[t.Any, ...]],
7335    alias: t.Optional[str] = None,
7336    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7337) -> Values:
7338    """Build VALUES statement.
7339
7340    Example:
7341        >>> values([(1, '2')]).sql()
7342        "VALUES (1, '2')"
7343
7344    Args:
7345        values: values statements that will be converted to SQL
7346        alias: optional alias
7347        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7348         If either are provided then an alias is also required.
7349
7350    Returns:
7351        Values: the Values expression object
7352    """
7353    if columns and not alias:
7354        raise ValueError("Alias is required when providing columns")
7355
7356    return Values(
7357        expressions=[convert(tup) for tup in values],
7358        alias=(
7359            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7360            if columns
7361            else (TableAlias(this=to_identifier(alias)) if alias else None)
7362        ),
7363    )

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:
7366def var(name: t.Optional[ExpOrStr]) -> Var:
7367    """Build a SQL variable.
7368
7369    Example:
7370        >>> repr(var('x'))
7371        'Var(this=x)'
7372
7373        >>> repr(var(column('x', table='y')))
7374        'Var(this=x)'
7375
7376    Args:
7377        name: The name of the var or an expression who's name will become the var.
7378
7379    Returns:
7380        The new variable node.
7381    """
7382    if not name:
7383        raise ValueError("Cannot convert empty name into var.")
7384
7385    if isinstance(name, Expression):
7386        name = name.name
7387    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) -> Alter:
7390def rename_table(
7391    old_name: str | Table,
7392    new_name: str | Table,
7393    dialect: DialectType = None,
7394) -> Alter:
7395    """Build ALTER TABLE... RENAME... expression
7396
7397    Args:
7398        old_name: The old name of the table
7399        new_name: The new name of the table
7400        dialect: The dialect to parse the table.
7401
7402    Returns:
7403        Alter table expression
7404    """
7405    old_table = to_table(old_name, dialect=dialect)
7406    new_table = to_table(new_name, dialect=dialect)
7407    return Alter(
7408        this=old_table,
7409        kind="TABLE",
7410        actions=[
7411            RenameTable(this=new_table),
7412        ],
7413    )

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) -> Alter:
7416def rename_column(
7417    table_name: str | Table,
7418    old_column_name: str | Column,
7419    new_column_name: str | Column,
7420    exists: t.Optional[bool] = None,
7421    dialect: DialectType = None,
7422) -> Alter:
7423    """Build ALTER TABLE... RENAME COLUMN... expression
7424
7425    Args:
7426        table_name: Name of the table
7427        old_column: The old name of the column
7428        new_column: The new name of the column
7429        exists: Whether to add the `IF EXISTS` clause
7430        dialect: The dialect to parse the table/column.
7431
7432    Returns:
7433        Alter table expression
7434    """
7435    table = to_table(table_name, dialect=dialect)
7436    old_column = to_column(old_column_name, dialect=dialect)
7437    new_column = to_column(new_column_name, dialect=dialect)
7438    return Alter(
7439        this=table,
7440        kind="TABLE",
7441        actions=[
7442            RenameColumn(this=old_column, to=new_column, exists=exists),
7443        ],
7444    )

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:
7447def convert(value: t.Any, copy: bool = False) -> Expression:
7448    """Convert a python value into an expression object.
7449
7450    Raises an error if a conversion is not possible.
7451
7452    Args:
7453        value: A python object.
7454        copy: Whether to copy `value` (only applies to Expressions and collections).
7455
7456    Returns:
7457        The equivalent expression object.
7458    """
7459    if isinstance(value, Expression):
7460        return maybe_copy(value, copy)
7461    if isinstance(value, str):
7462        return Literal.string(value)
7463    if isinstance(value, bool):
7464        return Boolean(this=value)
7465    if value is None or (isinstance(value, float) and math.isnan(value)):
7466        return null()
7467    if isinstance(value, numbers.Number):
7468        return Literal.number(value)
7469    if isinstance(value, bytes):
7470        return HexString(this=value.hex())
7471    if isinstance(value, datetime.datetime):
7472        datetime_literal = Literal.string(value.isoformat(sep=" "))
7473
7474        tz = None
7475        if value.tzinfo:
7476            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
7477            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
7478            tz = Literal.string(str(value.tzinfo))
7479
7480        return TimeStrToTime(this=datetime_literal, zone=tz)
7481    if isinstance(value, datetime.date):
7482        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7483        return DateStrToDate(this=date_literal)
7484    if isinstance(value, tuple):
7485        if hasattr(value, "_fields"):
7486            return Struct(
7487                expressions=[
7488                    PropertyEQ(
7489                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7490                    )
7491                    for k in value._fields
7492                ]
7493            )
7494        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7495    if isinstance(value, list):
7496        return Array(expressions=[convert(v, copy=copy) for v in value])
7497    if isinstance(value, dict):
7498        return Map(
7499            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7500            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7501        )
7502    if hasattr(value, "__dict__"):
7503        return Struct(
7504            expressions=[
7505                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7506                for k, v in value.__dict__.items()
7507            ]
7508        )
7509    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:
7512def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7513    """
7514    Replace children of an expression with the result of a lambda fun(child) -> exp.
7515    """
7516    for k, v in tuple(expression.args.items()):
7517        is_list_arg = type(v) is list
7518
7519        child_nodes = v if is_list_arg else [v]
7520        new_child_nodes = []
7521
7522        for cn in child_nodes:
7523            if isinstance(cn, Expression):
7524                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7525                    new_child_nodes.append(child_node)
7526            else:
7527                new_child_nodes.append(cn)
7528
7529        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:
7532def replace_tree(
7533    expression: Expression,
7534    fun: t.Callable,
7535    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7536) -> Expression:
7537    """
7538    Replace an entire tree with the result of function calls on each node.
7539
7540    This will be traversed in reverse dfs, so leaves first.
7541    If new nodes are created as a result of function calls, they will also be traversed.
7542    """
7543    stack = list(expression.dfs(prune=prune))
7544
7545    while stack:
7546        node = stack.pop()
7547        new_node = fun(node)
7548
7549        if new_node is not node:
7550            node.replace(new_node)
7551
7552            if isinstance(new_node, Expression):
7553                stack.append(new_node)
7554
7555    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]:
7558def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7559    """
7560    Return all table names referenced through columns in an expression.
7561
7562    Example:
7563        >>> import sqlglot
7564        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7565        ['a', 'c']
7566
7567    Args:
7568        expression: expression to find table names.
7569        exclude: a table name to exclude
7570
7571    Returns:
7572        A list of unique names.
7573    """
7574    return {
7575        table
7576        for table in (column.table for column in expression.find_all(Column))
7577        if table and table != exclude
7578    }

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:
7581def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7582    """Get the full name of a table as a string.
7583
7584    Args:
7585        table: Table expression node or string.
7586        dialect: The dialect to generate the table name for.
7587        identify: Determines when an identifier should be quoted. Possible values are:
7588            False (default): Never quote, except in cases where it's mandatory by the dialect.
7589            True: Always quote.
7590
7591    Examples:
7592        >>> from sqlglot import exp, parse_one
7593        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7594        'a.b.c'
7595
7596    Returns:
7597        The table name.
7598    """
7599
7600    table = maybe_parse(table, into=Table, dialect=dialect)
7601
7602    if not table:
7603        raise ValueError(f"Cannot parse {table}")
7604
7605    return ".".join(
7606        (
7607            part.sql(dialect=dialect, identify=True, copy=False)
7608            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7609            else part.name
7610        )
7611        for part in table.parts
7612    )

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:
7615def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7616    """Returns a case normalized table name without quotes.
7617
7618    Args:
7619        table: the table to normalize
7620        dialect: the dialect to use for normalization rules
7621        copy: whether to copy the expression.
7622
7623    Examples:
7624        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7625        'A-B.c'
7626    """
7627    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7628
7629    return ".".join(
7630        p.name
7631        for p in normalize_identifiers(
7632            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7633        ).parts
7634    )

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:
7637def replace_tables(
7638    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7639) -> E:
7640    """Replace all tables in expression according to the mapping.
7641
7642    Args:
7643        expression: expression node to be transformed and replaced.
7644        mapping: mapping of table names.
7645        dialect: the dialect of the mapping table
7646        copy: whether to copy the expression.
7647
7648    Examples:
7649        >>> from sqlglot import exp, parse_one
7650        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7651        'SELECT * FROM c /* a.b */'
7652
7653    Returns:
7654        The mapped expression.
7655    """
7656
7657    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7658
7659    def _replace_tables(node: Expression) -> Expression:
7660        if isinstance(node, Table):
7661            original = normalize_table_name(node, dialect=dialect)
7662            new_name = mapping.get(original)
7663
7664            if new_name:
7665                table = to_table(
7666                    new_name,
7667                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7668                    dialect=dialect,
7669                )
7670                table.add_comments([original])
7671                return table
7672        return node
7673
7674    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:
7677def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7678    """Replace placeholders in an expression.
7679
7680    Args:
7681        expression: expression node to be transformed and replaced.
7682        args: positional names that will substitute unnamed placeholders in the given order.
7683        kwargs: keyword arguments that will substitute named placeholders.
7684
7685    Examples:
7686        >>> from sqlglot import exp, parse_one
7687        >>> replace_placeholders(
7688        ...     parse_one("select * from :tbl where ? = ?"),
7689        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7690        ... ).sql()
7691        "SELECT * FROM foo WHERE str_col = 'b'"
7692
7693    Returns:
7694        The mapped expression.
7695    """
7696
7697    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7698        if isinstance(node, Placeholder):
7699            if node.this:
7700                new_name = kwargs.get(node.this)
7701                if new_name is not None:
7702                    return convert(new_name)
7703            else:
7704                try:
7705                    return convert(next(args))
7706                except StopIteration:
7707                    pass
7708        return node
7709
7710    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:
7713def expand(
7714    expression: Expression,
7715    sources: t.Dict[str, Query],
7716    dialect: DialectType = None,
7717    copy: bool = True,
7718) -> Expression:
7719    """Transforms an expression by expanding all referenced sources into subqueries.
7720
7721    Examples:
7722        >>> from sqlglot import parse_one
7723        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7724        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7725
7726        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7727        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7728
7729    Args:
7730        expression: The expression to expand.
7731        sources: A dictionary of name to Queries.
7732        dialect: The dialect of the sources dict.
7733        copy: Whether to copy the expression during transformation. Defaults to True.
7734
7735    Returns:
7736        The transformed expression.
7737    """
7738    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7739
7740    def _expand(node: Expression):
7741        if isinstance(node, Table):
7742            name = normalize_table_name(node, dialect=dialect)
7743            source = sources.get(name)
7744            if source:
7745                subquery = source.subquery(node.alias or name)
7746                subquery.comments = [f"source: {name}"]
7747                return subquery.transform(_expand, copy=False)
7748        return node
7749
7750    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:
7753def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7754    """
7755    Returns a Func expression.
7756
7757    Examples:
7758        >>> func("abs", 5).sql()
7759        'ABS(5)'
7760
7761        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7762        'CAST(5 AS DOUBLE)'
7763
7764    Args:
7765        name: the name of the function to build.
7766        args: the args used to instantiate the function of interest.
7767        copy: whether to copy the argument expressions.
7768        dialect: the source dialect.
7769        kwargs: the kwargs used to instantiate the function of interest.
7770
7771    Note:
7772        The arguments `args` and `kwargs` are mutually exclusive.
7773
7774    Returns:
7775        An instance of the function of interest, or an anonymous function, if `name` doesn't
7776        correspond to an existing `sqlglot.expressions.Func` class.
7777    """
7778    if args and kwargs:
7779        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7780
7781    from sqlglot.dialects.dialect import Dialect
7782
7783    dialect = Dialect.get_or_raise(dialect)
7784
7785    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7786    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7787
7788    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7789    if constructor:
7790        if converted:
7791            if "dialect" in constructor.__code__.co_varnames:
7792                function = constructor(converted, dialect=dialect)
7793            else:
7794                function = constructor(converted)
7795        elif constructor.__name__ == "from_arg_list":
7796            function = constructor.__self__(**kwargs)  # type: ignore
7797        else:
7798            constructor = FUNCTION_BY_NAME.get(name.upper())
7799            if constructor:
7800                function = constructor(**kwargs)
7801            else:
7802                raise ValueError(
7803                    f"Unable to convert '{name}' into a Func. Either manually construct "
7804                    "the Func expression of interest or parse the function call."
7805                )
7806    else:
7807        kwargs = kwargs or {"expressions": converted}
7808        function = Anonymous(this=name, **kwargs)
7809
7810    for error_message in function.error_messages(converted):
7811        raise ValueError(error_message)
7812
7813    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:
7816def case(
7817    expression: t.Optional[ExpOrStr] = None,
7818    **opts,
7819) -> Case:
7820    """
7821    Initialize a CASE statement.
7822
7823    Example:
7824        case().when("a = 1", "foo").else_("bar")
7825
7826    Args:
7827        expression: Optionally, the input expression (not all dialects support this)
7828        **opts: Extra keyword arguments for parsing `expression`
7829    """
7830    if expression is not None:
7831        this = maybe_parse(expression, **opts)
7832    else:
7833        this = None
7834    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:
7837def array(
7838    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7839) -> Array:
7840    """
7841    Returns an array.
7842
7843    Examples:
7844        >>> array(1, 'x').sql()
7845        'ARRAY(1, x)'
7846
7847    Args:
7848        expressions: the expressions to add to the array.
7849        copy: whether to copy the argument expressions.
7850        dialect: the source dialect.
7851        kwargs: the kwargs used to instantiate the function of interest.
7852
7853    Returns:
7854        An array expression.
7855    """
7856    return Array(
7857        expressions=[
7858            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7859            for expression in expressions
7860        ]
7861    )

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:
7864def tuple_(
7865    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7866) -> Tuple:
7867    """
7868    Returns an tuple.
7869
7870    Examples:
7871        >>> tuple_(1, 'x').sql()
7872        '(1, x)'
7873
7874    Args:
7875        expressions: the expressions to add to the tuple.
7876        copy: whether to copy the argument expressions.
7877        dialect: the source dialect.
7878        kwargs: the kwargs used to instantiate the function of interest.
7879
7880    Returns:
7881        A tuple expression.
7882    """
7883    return Tuple(
7884        expressions=[
7885            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7886            for expression in expressions
7887        ]
7888    )

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:
7891def true() -> Boolean:
7892    """
7893    Returns a true Boolean expression.
7894    """
7895    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7898def false() -> Boolean:
7899    """
7900    Returns a false Boolean expression.
7901    """
7902    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7905def null() -> Null:
7906    """
7907    Returns a Null expression.
7908    """
7909    return Null()

Returns a Null expression.

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