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

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

def to_dot(self) -> Dot | Identifier:
1600    def to_dot(self) -> Dot | Identifier:
1601        """Converts the column into a dot expression."""
1602        parts = self.parts
1603        parent = self.parent
1604
1605        while parent:
1606            if isinstance(parent, Dot):
1607                parts.append(parent.expression)
1608            parent = parent.parent
1609
1610        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

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

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

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):
1991class Drop(Expression):
1992    arg_types = {
1993        "this": False,
1994        "kind": False,
1995        "expressions": False,
1996        "exists": False,
1997        "temporary": False,
1998        "materialized": False,
1999        "cascade": False,
2000        "constraints": False,
2001        "purge": False,
2002        "cluster": False,
2003    }
2004
2005    @property
2006    def kind(self) -> t.Optional[str]:
2007        kind = self.args.get("kind")
2008        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]
2005    @property
2006    def kind(self) -> t.Optional[str]:
2007        kind = self.args.get("kind")
2008        return kind and kind.upper()
key = 'drop'
class Filter(Expression):
2011class Filter(Expression):
2012    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2015class Check(Expression):
2016    pass
key = 'check'
class Changes(Expression):
2019class Changes(Expression):
2020    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2024class Connect(Expression):
2025    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2028class CopyParameter(Expression):
2029    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2032class Copy(DML):
2033    arg_types = {
2034        "this": True,
2035        "kind": True,
2036        "files": True,
2037        "credentials": False,
2038        "format": False,
2039        "params": False,
2040    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2043class Credentials(Expression):
2044    arg_types = {
2045        "credentials": False,
2046        "encryption": False,
2047        "storage": False,
2048        "iam_role": False,
2049        "region": False,
2050    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2053class Prior(Expression):
2054    pass
key = 'prior'
class Directory(Expression):
2057class Directory(Expression):
2058    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2059    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2062class ForeignKey(Expression):
2063    arg_types = {
2064        "expressions": True,
2065        "reference": False,
2066        "delete": False,
2067        "update": False,
2068    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2071class ColumnPrefix(Expression):
2072    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2075class PrimaryKey(Expression):
2076    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2081class Into(Expression):
2082    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2085class From(Expression):
2086    @property
2087    def name(self) -> str:
2088        return self.this.name
2089
2090    @property
2091    def alias_or_name(self) -> str:
2092        return self.this.alias_or_name
name: str
2086    @property
2087    def name(self) -> str:
2088        return self.this.name
alias_or_name: str
2090    @property
2091    def alias_or_name(self) -> str:
2092        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2095class Having(Expression):
2096    pass
key = 'having'
class Hint(Expression):
2099class Hint(Expression):
2100    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2103class JoinHint(Expression):
2104    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2107class Identifier(Expression):
2108    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2109
2110    @property
2111    def quoted(self) -> bool:
2112        return bool(self.args.get("quoted"))
2113
2114    @property
2115    def hashable_args(self) -> t.Any:
2116        return (self.this, self.quoted)
2117
2118    @property
2119    def output_name(self) -> str:
2120        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2110    @property
2111    def quoted(self) -> bool:
2112        return bool(self.args.get("quoted"))
hashable_args: Any
2114    @property
2115    def hashable_args(self) -> t.Any:
2116        return (self.this, self.quoted)
output_name: str
2118    @property
2119    def output_name(self) -> str:
2120        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):
2124class Opclass(Expression):
2125    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2128class Index(Expression):
2129    arg_types = {
2130        "this": False,
2131        "table": False,
2132        "unique": False,
2133        "primary": False,
2134        "amp": False,  # teradata
2135        "params": False,
2136    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2139class IndexParameters(Expression):
2140    arg_types = {
2141        "using": False,
2142        "include": False,
2143        "columns": False,
2144        "with_storage": False,
2145        "partition_by": False,
2146        "tablespace": False,
2147        "where": False,
2148        "on": False,
2149    }
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):
2152class Insert(DDL, DML):
2153    arg_types = {
2154        "hint": False,
2155        "with": False,
2156        "is_function": False,
2157        "this": False,
2158        "expression": False,
2159        "conflict": False,
2160        "returning": False,
2161        "overwrite": False,
2162        "exists": False,
2163        "alternative": False,
2164        "where": False,
2165        "ignore": False,
2166        "by_name": False,
2167        "stored": False,
2168        "partition": False,
2169        "settings": False,
2170    }
2171
2172    def with_(
2173        self,
2174        alias: ExpOrStr,
2175        as_: ExpOrStr,
2176        recursive: t.Optional[bool] = None,
2177        append: bool = True,
2178        dialect: DialectType = None,
2179        copy: bool = True,
2180        **opts,
2181    ) -> Insert:
2182        """
2183        Append to or set the common table expressions.
2184
2185        Example:
2186            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2187            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2188
2189        Args:
2190            alias: the SQL code string to parse as the table name.
2191                If an `Expression` instance is passed, this is used as-is.
2192            as_: the SQL code string to parse as the table expression.
2193                If an `Expression` instance is passed, it will be used as-is.
2194            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2195            append: if `True`, add to any existing expressions.
2196                Otherwise, this resets the expressions.
2197            dialect: the dialect used to parse the input expression.
2198            copy: if `False`, modify this expression instance in-place.
2199            opts: other options to use to parse the input expressions.
2200
2201        Returns:
2202            The modified expression.
2203        """
2204        return _apply_cte_builder(
2205            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2206        )
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}
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:
2172    def with_(
2173        self,
2174        alias: ExpOrStr,
2175        as_: ExpOrStr,
2176        recursive: t.Optional[bool] = None,
2177        append: bool = True,
2178        dialect: DialectType = None,
2179        copy: bool = True,
2180        **opts,
2181    ) -> Insert:
2182        """
2183        Append to or set the common table expressions.
2184
2185        Example:
2186            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2187            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2188
2189        Args:
2190            alias: the SQL code string to parse as the table name.
2191                If an `Expression` instance is passed, this is used as-is.
2192            as_: the SQL code string to parse as the table expression.
2193                If an `Expression` instance is passed, it will be used as-is.
2194            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2195            append: if `True`, add to any existing expressions.
2196                Otherwise, this resets the expressions.
2197            dialect: the dialect used to parse the input expression.
2198            copy: if `False`, modify this expression instance in-place.
2199            opts: other options to use to parse the input expressions.
2200
2201        Returns:
2202            The modified expression.
2203        """
2204        return _apply_cte_builder(
2205            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2206        )

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):
2209class OnConflict(Expression):
2210    arg_types = {
2211        "duplicate": False,
2212        "expressions": False,
2213        "action": False,
2214        "conflict_keys": False,
2215        "constraint": False,
2216    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2219class Returning(Expression):
2220    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2224class Introducer(Expression):
2225    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2229class National(Expression):
2230    pass
key = 'national'
class LoadData(Expression):
2233class LoadData(Expression):
2234    arg_types = {
2235        "this": True,
2236        "local": False,
2237        "overwrite": False,
2238        "inpath": True,
2239        "partition": False,
2240        "input_format": False,
2241        "serde": False,
2242    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2245class Partition(Expression):
2246    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2249class PartitionRange(Expression):
2250    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2254class PartitionId(Expression):
2255    pass
key = 'partitionid'
class Fetch(Expression):
2258class Fetch(Expression):
2259    arg_types = {
2260        "direction": False,
2261        "count": False,
2262        "percent": False,
2263        "with_ties": False,
2264    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2267class Group(Expression):
2268    arg_types = {
2269        "expressions": False,
2270        "grouping_sets": False,
2271        "cube": False,
2272        "rollup": False,
2273        "totals": False,
2274        "all": False,
2275    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2278class Lambda(Expression):
2279    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2282class Limit(Expression):
2283    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):
2286class Literal(Condition):
2287    arg_types = {"this": True, "is_string": True}
2288
2289    @property
2290    def hashable_args(self) -> t.Any:
2291        return (self.this, self.args.get("is_string"))
2292
2293    @classmethod
2294    def number(cls, number) -> Literal:
2295        return cls(this=str(number), is_string=False)
2296
2297    @classmethod
2298    def string(cls, string) -> Literal:
2299        return cls(this=str(string), is_string=True)
2300
2301    @property
2302    def output_name(self) -> str:
2303        return self.name
2304
2305    def to_py(self) -> int | str | Decimal:
2306        if self.is_number:
2307            try:
2308                return int(self.this)
2309            except ValueError:
2310                return Decimal(self.this)
2311        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2289    @property
2290    def hashable_args(self) -> t.Any:
2291        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2293    @classmethod
2294    def number(cls, number) -> Literal:
2295        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2297    @classmethod
2298    def string(cls, string) -> Literal:
2299        return cls(this=str(string), is_string=True)
output_name: str
2301    @property
2302    def output_name(self) -> str:
2303        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:
2305    def to_py(self) -> int | str | Decimal:
2306        if self.is_number:
2307            try:
2308                return int(self.this)
2309            except ValueError:
2310                return Decimal(self.this)
2311        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2314class Join(Expression):
2315    arg_types = {
2316        "this": True,
2317        "on": False,
2318        "side": False,
2319        "kind": False,
2320        "using": False,
2321        "method": False,
2322        "global": False,
2323        "hint": False,
2324        "match_condition": False,  # Snowflake
2325    }
2326
2327    @property
2328    def method(self) -> str:
2329        return self.text("method").upper()
2330
2331    @property
2332    def kind(self) -> str:
2333        return self.text("kind").upper()
2334
2335    @property
2336    def side(self) -> str:
2337        return self.text("side").upper()
2338
2339    @property
2340    def hint(self) -> str:
2341        return self.text("hint").upper()
2342
2343    @property
2344    def alias_or_name(self) -> str:
2345        return self.this.alias_or_name
2346
2347    def on(
2348        self,
2349        *expressions: t.Optional[ExpOrStr],
2350        append: bool = True,
2351        dialect: DialectType = None,
2352        copy: bool = True,
2353        **opts,
2354    ) -> Join:
2355        """
2356        Append to or set the ON expressions.
2357
2358        Example:
2359            >>> import sqlglot
2360            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2361            'JOIN x ON y = 1'
2362
2363        Args:
2364            *expressions: the SQL code strings to parse.
2365                If an `Expression` instance is passed, it will be used as-is.
2366                Multiple expressions are combined with an AND operator.
2367            append: if `True`, AND the new expressions to any existing expression.
2368                Otherwise, this resets the expression.
2369            dialect: the dialect used to parse the input expressions.
2370            copy: if `False`, modify this expression instance in-place.
2371            opts: other options to use to parse the input expressions.
2372
2373        Returns:
2374            The modified Join expression.
2375        """
2376        join = _apply_conjunction_builder(
2377            *expressions,
2378            instance=self,
2379            arg="on",
2380            append=append,
2381            dialect=dialect,
2382            copy=copy,
2383            **opts,
2384        )
2385
2386        if join.kind == "CROSS":
2387            join.set("kind", None)
2388
2389        return join
2390
2391    def using(
2392        self,
2393        *expressions: t.Optional[ExpOrStr],
2394        append: bool = True,
2395        dialect: DialectType = None,
2396        copy: bool = True,
2397        **opts,
2398    ) -> Join:
2399        """
2400        Append to or set the USING expressions.
2401
2402        Example:
2403            >>> import sqlglot
2404            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2405            'JOIN x USING (foo, bla)'
2406
2407        Args:
2408            *expressions: the SQL code strings to parse.
2409                If an `Expression` instance is passed, it will be used as-is.
2410            append: if `True`, concatenate the new expressions to the existing "using" list.
2411                Otherwise, this resets the expression.
2412            dialect: the dialect used to parse the input expressions.
2413            copy: if `False`, modify this expression instance in-place.
2414            opts: other options to use to parse the input expressions.
2415
2416        Returns:
2417            The modified Join expression.
2418        """
2419        join = _apply_list_builder(
2420            *expressions,
2421            instance=self,
2422            arg="using",
2423            append=append,
2424            dialect=dialect,
2425            copy=copy,
2426            **opts,
2427        )
2428
2429        if join.kind == "CROSS":
2430            join.set("kind", None)
2431
2432        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
2327    @property
2328    def method(self) -> str:
2329        return self.text("method").upper()
kind: str
2331    @property
2332    def kind(self) -> str:
2333        return self.text("kind").upper()
side: str
2335    @property
2336    def side(self) -> str:
2337        return self.text("side").upper()
hint: str
2339    @property
2340    def hint(self) -> str:
2341        return self.text("hint").upper()
alias_or_name: str
2343    @property
2344    def alias_or_name(self) -> str:
2345        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:
2347    def on(
2348        self,
2349        *expressions: t.Optional[ExpOrStr],
2350        append: bool = True,
2351        dialect: DialectType = None,
2352        copy: bool = True,
2353        **opts,
2354    ) -> Join:
2355        """
2356        Append to or set the ON expressions.
2357
2358        Example:
2359            >>> import sqlglot
2360            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2361            'JOIN x ON y = 1'
2362
2363        Args:
2364            *expressions: the SQL code strings to parse.
2365                If an `Expression` instance is passed, it will be used as-is.
2366                Multiple expressions are combined with an AND operator.
2367            append: if `True`, AND the new expressions to any existing expression.
2368                Otherwise, this resets the expression.
2369            dialect: the dialect used to parse the input expressions.
2370            copy: if `False`, modify this expression instance in-place.
2371            opts: other options to use to parse the input expressions.
2372
2373        Returns:
2374            The modified Join expression.
2375        """
2376        join = _apply_conjunction_builder(
2377            *expressions,
2378            instance=self,
2379            arg="on",
2380            append=append,
2381            dialect=dialect,
2382            copy=copy,
2383            **opts,
2384        )
2385
2386        if join.kind == "CROSS":
2387            join.set("kind", None)
2388
2389        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:
2391    def using(
2392        self,
2393        *expressions: t.Optional[ExpOrStr],
2394        append: bool = True,
2395        dialect: DialectType = None,
2396        copy: bool = True,
2397        **opts,
2398    ) -> Join:
2399        """
2400        Append to or set the USING expressions.
2401
2402        Example:
2403            >>> import sqlglot
2404            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2405            'JOIN x USING (foo, bla)'
2406
2407        Args:
2408            *expressions: the SQL code strings to parse.
2409                If an `Expression` instance is passed, it will be used as-is.
2410            append: if `True`, concatenate the new expressions to the existing "using" list.
2411                Otherwise, this resets the expression.
2412            dialect: the dialect used to parse the input expressions.
2413            copy: if `False`, modify this expression instance in-place.
2414            opts: other options to use to parse the input expressions.
2415
2416        Returns:
2417            The modified Join expression.
2418        """
2419        join = _apply_list_builder(
2420            *expressions,
2421            instance=self,
2422            arg="using",
2423            append=append,
2424            dialect=dialect,
2425            copy=copy,
2426            **opts,
2427        )
2428
2429        if join.kind == "CROSS":
2430            join.set("kind", None)
2431
2432        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):
2435class Lateral(UDTF):
2436    arg_types = {
2437        "this": True,
2438        "view": False,
2439        "outer": False,
2440        "alias": False,
2441        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2442    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2445class MatchRecognizeMeasure(Expression):
2446    arg_types = {
2447        "this": True,
2448        "window_frame": False,
2449    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2452class MatchRecognize(Expression):
2453    arg_types = {
2454        "partition_by": False,
2455        "order": False,
2456        "measures": False,
2457        "rows": False,
2458        "after": False,
2459        "pattern": False,
2460        "define": False,
2461        "alias": False,
2462    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2467class Final(Expression):
2468    pass
key = 'final'
class Offset(Expression):
2471class Offset(Expression):
2472    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2475class Order(Expression):
2476    arg_types = {
2477        "this": False,
2478        "expressions": True,
2479        "interpolate": False,
2480        "siblings": False,
2481    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2485class WithFill(Expression):
2486    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2491class Cluster(Order):
2492    pass
key = 'cluster'
class Distribute(Order):
2495class Distribute(Order):
2496    pass
key = 'distribute'
class Sort(Order):
2499class Sort(Order):
2500    pass
key = 'sort'
class Ordered(Expression):
2503class Ordered(Expression):
2504    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):
2507class Property(Expression):
2508    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2511class AllowedValuesProperty(Expression):
2512    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2515class AlgorithmProperty(Property):
2516    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2519class AutoIncrementProperty(Property):
2520    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2524class AutoRefreshProperty(Property):
2525    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2528class BackupProperty(Property):
2529    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2532class BlockCompressionProperty(Property):
2533    arg_types = {
2534        "autotemp": False,
2535        "always": False,
2536        "default": False,
2537        "manual": False,
2538        "never": False,
2539    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2542class CharacterSetProperty(Property):
2543    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2546class ChecksumProperty(Property):
2547    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2550class CollateProperty(Property):
2551    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2554class CopyGrantsProperty(Property):
2555    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2558class DataBlocksizeProperty(Property):
2559    arg_types = {
2560        "size": False,
2561        "units": False,
2562        "minimum": False,
2563        "maximum": False,
2564        "default": False,
2565    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2568class DataDeletionProperty(Property):
2569    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):
2572class DefinerProperty(Property):
2573    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2576class DistKeyProperty(Property):
2577    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2580class DistStyleProperty(Property):
2581    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2584class EngineProperty(Property):
2585    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2588class HeapProperty(Property):
2589    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2592class ToTableProperty(Property):
2593    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2596class ExecuteAsProperty(Property):
2597    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2600class ExternalProperty(Property):
2601    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2604class FallbackProperty(Property):
2605    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2608class FileFormatProperty(Property):
2609    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2612class FreespaceProperty(Property):
2613    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2616class GlobalProperty(Property):
2617    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2620class IcebergProperty(Property):
2621    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2624class InheritsProperty(Property):
2625    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2628class InputModelProperty(Property):
2629    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2632class OutputModelProperty(Property):
2633    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2636class IsolatedLoadingProperty(Property):
2637    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2640class JournalProperty(Property):
2641    arg_types = {
2642        "no": False,
2643        "dual": False,
2644        "before": False,
2645        "local": False,
2646        "after": False,
2647    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2650class LanguageProperty(Property):
2651    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2655class ClusteredByProperty(Property):
2656    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2659class DictProperty(Property):
2660    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2663class DictSubProperty(Property):
2664    pass
key = 'dictsubproperty'
class DictRange(Property):
2667class DictRange(Property):
2668    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2671class DynamicProperty(Property):
2672    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2677class OnCluster(Property):
2678    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2682class EmptyProperty(Property):
2683    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2686class LikeProperty(Property):
2687    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2690class LocationProperty(Property):
2691    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2694class LockProperty(Property):
2695    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2698class LockingProperty(Property):
2699    arg_types = {
2700        "this": False,
2701        "kind": True,
2702        "for_or_in": False,
2703        "lock_type": True,
2704        "override": False,
2705    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2708class LogProperty(Property):
2709    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2712class MaterializedProperty(Property):
2713    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2716class MergeBlockRatioProperty(Property):
2717    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):
2720class NoPrimaryIndexProperty(Property):
2721    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2724class OnProperty(Property):
2725    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2728class OnCommitProperty(Property):
2729    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2732class PartitionedByProperty(Property):
2733    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2737class PartitionBoundSpec(Expression):
2738    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2739    arg_types = {
2740        "this": False,
2741        "expression": False,
2742        "from_expressions": False,
2743        "to_expressions": False,
2744    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2747class PartitionedOfProperty(Property):
2748    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2749    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2752class StreamingTableProperty(Property):
2753    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2756class RemoteWithConnectionModelProperty(Property):
2757    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2760class ReturnsProperty(Property):
2761    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):
2764class StrictProperty(Property):
2765    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2768class RowFormatProperty(Property):
2769    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2772class RowFormatDelimitedProperty(Property):
2773    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2774    arg_types = {
2775        "fields": False,
2776        "escaped": False,
2777        "collection_items": False,
2778        "map_keys": False,
2779        "lines": False,
2780        "null": False,
2781        "serde": False,
2782    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2785class RowFormatSerdeProperty(Property):
2786    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2790class QueryTransform(Expression):
2791    arg_types = {
2792        "expressions": True,
2793        "command_script": True,
2794        "schema": False,
2795        "row_format_before": False,
2796        "record_writer": False,
2797        "row_format_after": False,
2798        "record_reader": False,
2799    }
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):
2802class SampleProperty(Property):
2803    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2806class SchemaCommentProperty(Property):
2807    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2810class SerdeProperties(Property):
2811    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2814class SetProperty(Property):
2815    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2818class SharingProperty(Property):
2819    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2822class SetConfigProperty(Property):
2823    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2826class SettingsProperty(Property):
2827    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2830class SortKeyProperty(Property):
2831    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2834class SqlReadWriteProperty(Property):
2835    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2838class SqlSecurityProperty(Property):
2839    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2842class StabilityProperty(Property):
2843    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2846class TemporaryProperty(Property):
2847    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2850class SecureProperty(Property):
2851    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2854class TransformModelProperty(Property):
2855    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2858class TransientProperty(Property):
2859    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2862class UnloggedProperty(Property):
2863    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2867class ViewAttributeProperty(Property):
2868    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2871class VolatileProperty(Property):
2872    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2875class WithDataProperty(Property):
2876    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2879class WithJournalTableProperty(Property):
2880    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2883class WithSchemaBindingProperty(Property):
2884    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2887class WithSystemVersioningProperty(Property):
2888    arg_types = {
2889        "on": False,
2890        "this": False,
2891        "data_consistency": False,
2892        "retention_period": False,
2893        "with": True,
2894    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2897class Properties(Expression):
2898    arg_types = {"expressions": True}
2899
2900    NAME_TO_PROPERTY = {
2901        "ALGORITHM": AlgorithmProperty,
2902        "AUTO_INCREMENT": AutoIncrementProperty,
2903        "CHARACTER SET": CharacterSetProperty,
2904        "CLUSTERED_BY": ClusteredByProperty,
2905        "COLLATE": CollateProperty,
2906        "COMMENT": SchemaCommentProperty,
2907        "DEFINER": DefinerProperty,
2908        "DISTKEY": DistKeyProperty,
2909        "DISTSTYLE": DistStyleProperty,
2910        "ENGINE": EngineProperty,
2911        "EXECUTE AS": ExecuteAsProperty,
2912        "FORMAT": FileFormatProperty,
2913        "LANGUAGE": LanguageProperty,
2914        "LOCATION": LocationProperty,
2915        "LOCK": LockProperty,
2916        "PARTITIONED_BY": PartitionedByProperty,
2917        "RETURNS": ReturnsProperty,
2918        "ROW_FORMAT": RowFormatProperty,
2919        "SORTKEY": SortKeyProperty,
2920    }
2921
2922    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2923
2924    # CREATE property locations
2925    # Form: schema specified
2926    #   create [POST_CREATE]
2927    #     table a [POST_NAME]
2928    #     (b int) [POST_SCHEMA]
2929    #     with ([POST_WITH])
2930    #     index (b) [POST_INDEX]
2931    #
2932    # Form: alias selection
2933    #   create [POST_CREATE]
2934    #     table a [POST_NAME]
2935    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2936    #     index (c) [POST_INDEX]
2937    class Location(AutoName):
2938        POST_CREATE = auto()
2939        POST_NAME = auto()
2940        POST_SCHEMA = auto()
2941        POST_WITH = auto()
2942        POST_ALIAS = auto()
2943        POST_EXPRESSION = auto()
2944        POST_INDEX = auto()
2945        UNSUPPORTED = auto()
2946
2947    @classmethod
2948    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2949        expressions = []
2950        for key, value in properties_dict.items():
2951            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2952            if property_cls:
2953                expressions.append(property_cls(this=convert(value)))
2954            else:
2955                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2956
2957        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:
2947    @classmethod
2948    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2949        expressions = []
2950        for key, value in properties_dict.items():
2951            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2952            if property_cls:
2953                expressions.append(property_cls(this=convert(value)))
2954            else:
2955                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2956
2957        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2937    class Location(AutoName):
2938        POST_CREATE = auto()
2939        POST_NAME = auto()
2940        POST_SCHEMA = auto()
2941        POST_WITH = auto()
2942        POST_ALIAS = auto()
2943        POST_EXPRESSION = auto()
2944        POST_INDEX = auto()
2945        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):
2960class Qualify(Expression):
2961    pass
key = 'qualify'
class InputOutputFormat(Expression):
2964class InputOutputFormat(Expression):
2965    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2969class Return(Expression):
2970    pass
key = 'return'
class Reference(Expression):
2973class Reference(Expression):
2974    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2977class Tuple(Expression):
2978    arg_types = {"expressions": False}
2979
2980    def isin(
2981        self,
2982        *expressions: t.Any,
2983        query: t.Optional[ExpOrStr] = None,
2984        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2985        copy: bool = True,
2986        **opts,
2987    ) -> In:
2988        return In(
2989            this=maybe_copy(self, copy),
2990            expressions=[convert(e, copy=copy) for e in expressions],
2991            query=maybe_parse(query, copy=copy, **opts) if query else None,
2992            unnest=(
2993                Unnest(
2994                    expressions=[
2995                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2996                        for e in ensure_list(unnest)
2997                    ]
2998                )
2999                if unnest
3000                else None
3001            ),
3002        )
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:
2980    def isin(
2981        self,
2982        *expressions: t.Any,
2983        query: t.Optional[ExpOrStr] = None,
2984        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2985        copy: bool = True,
2986        **opts,
2987    ) -> In:
2988        return In(
2989            this=maybe_copy(self, copy),
2990            expressions=[convert(e, copy=copy) for e in expressions],
2991            query=maybe_parse(query, copy=copy, **opts) if query else None,
2992            unnest=(
2993                Unnest(
2994                    expressions=[
2995                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2996                        for e in ensure_list(unnest)
2997                    ]
2998                )
2999                if unnest
3000                else None
3001            ),
3002        )
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):
3033class QueryOption(Expression):
3034    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3038class WithTableHint(Expression):
3039    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3043class IndexTableHint(Expression):
3044    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3048class HistoricalData(Expression):
3049    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3052class Table(Expression):
3053    arg_types = {
3054        "this": False,
3055        "alias": False,
3056        "db": False,
3057        "catalog": False,
3058        "laterals": False,
3059        "joins": False,
3060        "pivots": False,
3061        "hints": False,
3062        "system_time": False,
3063        "version": False,
3064        "format": False,
3065        "pattern": False,
3066        "ordinality": False,
3067        "when": False,
3068        "only": False,
3069        "partition": False,
3070        "changes": False,
3071        "rows_from": False,
3072    }
3073
3074    @property
3075    def name(self) -> str:
3076        if isinstance(self.this, Func):
3077            return ""
3078        return self.this.name
3079
3080    @property
3081    def db(self) -> str:
3082        return self.text("db")
3083
3084    @property
3085    def catalog(self) -> str:
3086        return self.text("catalog")
3087
3088    @property
3089    def selects(self) -> t.List[Expression]:
3090        return []
3091
3092    @property
3093    def named_selects(self) -> t.List[str]:
3094        return []
3095
3096    @property
3097    def parts(self) -> t.List[Expression]:
3098        """Return the parts of a table in order catalog, db, table."""
3099        parts: t.List[Expression] = []
3100
3101        for arg in ("catalog", "db", "this"):
3102            part = self.args.get(arg)
3103
3104            if isinstance(part, Dot):
3105                parts.extend(part.flatten())
3106            elif isinstance(part, Expression):
3107                parts.append(part)
3108
3109        return parts
3110
3111    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3112        parts = self.parts
3113        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3114        alias = self.args.get("alias")
3115        if alias:
3116            col = alias_(col, alias.this, copy=copy)
3117        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}
name: str
3074    @property
3075    def name(self) -> str:
3076        if isinstance(self.this, Func):
3077            return ""
3078        return self.this.name
db: str
3080    @property
3081    def db(self) -> str:
3082        return self.text("db")
catalog: str
3084    @property
3085    def catalog(self) -> str:
3086        return self.text("catalog")
selects: List[Expression]
3088    @property
3089    def selects(self) -> t.List[Expression]:
3090        return []
named_selects: List[str]
3092    @property
3093    def named_selects(self) -> t.List[str]:
3094        return []
parts: List[Expression]
3096    @property
3097    def parts(self) -> t.List[Expression]:
3098        """Return the parts of a table in order catalog, db, table."""
3099        parts: t.List[Expression] = []
3100
3101        for arg in ("catalog", "db", "this"):
3102            part = self.args.get(arg)
3103
3104            if isinstance(part, Dot):
3105                parts.extend(part.flatten())
3106            elif isinstance(part, Expression):
3107                parts.append(part)
3108
3109        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3111    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3112        parts = self.parts
3113        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3114        alias = self.args.get("alias")
3115        if alias:
3116            col = alias_(col, alias.this, copy=copy)
3117        return col
key = 'table'
class SetOperation(Query):
3120class SetOperation(Query):
3121    arg_types = {
3122        "with": False,
3123        "this": True,
3124        "expression": True,
3125        "distinct": False,
3126        "by_name": False,
3127        **QUERY_MODIFIERS,
3128    }
3129
3130    def select(
3131        self: S,
3132        *expressions: t.Optional[ExpOrStr],
3133        append: bool = True,
3134        dialect: DialectType = None,
3135        copy: bool = True,
3136        **opts,
3137    ) -> S:
3138        this = maybe_copy(self, copy)
3139        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3140        this.expression.unnest().select(
3141            *expressions, append=append, dialect=dialect, copy=False, **opts
3142        )
3143        return this
3144
3145    @property
3146    def named_selects(self) -> t.List[str]:
3147        return self.this.unnest().named_selects
3148
3149    @property
3150    def is_star(self) -> bool:
3151        return self.this.is_star or self.expression.is_star
3152
3153    @property
3154    def selects(self) -> t.List[Expression]:
3155        return self.this.unnest().selects
3156
3157    @property
3158    def left(self) -> Query:
3159        return self.this
3160
3161    @property
3162    def right(self) -> Query:
3163        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:
3130    def select(
3131        self: S,
3132        *expressions: t.Optional[ExpOrStr],
3133        append: bool = True,
3134        dialect: DialectType = None,
3135        copy: bool = True,
3136        **opts,
3137    ) -> S:
3138        this = maybe_copy(self, copy)
3139        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3140        this.expression.unnest().select(
3141            *expressions, append=append, dialect=dialect, copy=False, **opts
3142        )
3143        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]
3145    @property
3146    def named_selects(self) -> t.List[str]:
3147        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3149    @property
3150    def is_star(self) -> bool:
3151        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3153    @property
3154    def selects(self) -> t.List[Expression]:
3155        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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:
3351    def cluster_by(
3352        self,
3353        *expressions: t.Optional[ExpOrStr],
3354        append: bool = True,
3355        dialect: DialectType = None,
3356        copy: bool = True,
3357        **opts,
3358    ) -> Select:
3359        """
3360        Set the CLUSTER BY expression.
3361
3362        Example:
3363            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3364            'SELECT x FROM tbl CLUSTER BY x DESC'
3365
3366        Args:
3367            *expressions: the SQL code strings to parse.
3368                If a `Group` instance is passed, this is used as-is.
3369                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3370            append: if `True`, add to any existing expressions.
3371                Otherwise, this flattens all the `Order` expression into a single expression.
3372            dialect: the dialect used to parse the input expression.
3373            copy: if `False`, modify this expression instance in-place.
3374            opts: other options to use to parse the input expressions.
3375
3376        Returns:
3377            The modified Select expression.
3378        """
3379        return _apply_child_list_builder(
3380            *expressions,
3381            instance=self,
3382            arg="cluster",
3383            append=append,
3384            copy=copy,
3385            prefix="CLUSTER BY",
3386            into=Cluster,
3387            dialect=dialect,
3388            **opts,
3389        )

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:
3391    def select(
3392        self,
3393        *expressions: t.Optional[ExpOrStr],
3394        append: bool = True,
3395        dialect: DialectType = None,
3396        copy: bool = True,
3397        **opts,
3398    ) -> Select:
3399        return _apply_list_builder(
3400            *expressions,
3401            instance=self,
3402            arg="expressions",
3403            append=append,
3404            dialect=dialect,
3405            into=Expression,
3406            copy=copy,
3407            **opts,
3408        )

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:
3410    def lateral(
3411        self,
3412        *expressions: t.Optional[ExpOrStr],
3413        append: bool = True,
3414        dialect: DialectType = None,
3415        copy: bool = True,
3416        **opts,
3417    ) -> Select:
3418        """
3419        Append to or set the LATERAL expressions.
3420
3421        Example:
3422            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3423            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3424
3425        Args:
3426            *expressions: the SQL code strings to parse.
3427                If an `Expression` instance is passed, it will be used as-is.
3428            append: if `True`, add to any existing expressions.
3429                Otherwise, this resets the expressions.
3430            dialect: the dialect used to parse the input expressions.
3431            copy: if `False`, modify this expression instance in-place.
3432            opts: other options to use to parse the input expressions.
3433
3434        Returns:
3435            The modified Select expression.
3436        """
3437        return _apply_list_builder(
3438            *expressions,
3439            instance=self,
3440            arg="laterals",
3441            append=append,
3442            into=Lateral,
3443            prefix="LATERAL VIEW",
3444            dialect=dialect,
3445            copy=copy,
3446            **opts,
3447        )

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

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

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:
3586    def having(
3587        self,
3588        *expressions: t.Optional[ExpOrStr],
3589        append: bool = True,
3590        dialect: DialectType = None,
3591        copy: bool = True,
3592        **opts,
3593    ) -> Select:
3594        """
3595        Append to or set the HAVING expressions.
3596
3597        Example:
3598            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3599            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3600
3601        Args:
3602            *expressions: the SQL code strings to parse.
3603                If an `Expression` instance is passed, it will be used as-is.
3604                Multiple expressions are combined with an AND operator.
3605            append: if `True`, AND the new expressions to any existing expression.
3606                Otherwise, this resets the expression.
3607            dialect: the dialect used to parse the input expressions.
3608            copy: if `False`, modify this expression instance in-place.
3609            opts: other options to use to parse the input expressions.
3610
3611        Returns:
3612            The modified Select expression.
3613        """
3614        return _apply_conjunction_builder(
3615            *expressions,
3616            instance=self,
3617            arg="having",
3618            append=append,
3619            into=Having,
3620            dialect=dialect,
3621            copy=copy,
3622            **opts,
3623        )

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:
3625    def window(
3626        self,
3627        *expressions: t.Optional[ExpOrStr],
3628        append: bool = True,
3629        dialect: DialectType = None,
3630        copy: bool = True,
3631        **opts,
3632    ) -> Select:
3633        return _apply_list_builder(
3634            *expressions,
3635            instance=self,
3636            arg="windows",
3637            append=append,
3638            into=Window,
3639            dialect=dialect,
3640            copy=copy,
3641            **opts,
3642        )
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:
3644    def qualify(
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_conjunction_builder(
3653            *expressions,
3654            instance=self,
3655            arg="qualify",
3656            append=append,
3657            into=Qualify,
3658            dialect=dialect,
3659            copy=copy,
3660            **opts,
3661        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3663    def distinct(
3664        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3665    ) -> Select:
3666        """
3667        Set the OFFSET expression.
3668
3669        Example:
3670            >>> Select().from_("tbl").select("x").distinct().sql()
3671            'SELECT DISTINCT x FROM tbl'
3672
3673        Args:
3674            ons: the expressions to distinct on
3675            distinct: whether the Select should be distinct
3676            copy: if `False`, modify this expression instance in-place.
3677
3678        Returns:
3679            Select: the modified expression.
3680        """
3681        instance = maybe_copy(self, copy)
3682        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3683        instance.set("distinct", Distinct(on=on) if distinct else None)
3684        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:
3686    def ctas(
3687        self,
3688        table: ExpOrStr,
3689        properties: t.Optional[t.Dict] = None,
3690        dialect: DialectType = None,
3691        copy: bool = True,
3692        **opts,
3693    ) -> Create:
3694        """
3695        Convert this expression to a CREATE TABLE AS statement.
3696
3697        Example:
3698            >>> Select().select("*").from_("tbl").ctas("x").sql()
3699            'CREATE TABLE x AS SELECT * FROM tbl'
3700
3701        Args:
3702            table: the SQL code string to parse as the table name.
3703                If another `Expression` instance is passed, it will be used as-is.
3704            properties: an optional mapping of table properties
3705            dialect: the dialect used to parse the input table.
3706            copy: if `False`, modify this expression instance in-place.
3707            opts: other options to use to parse the input table.
3708
3709        Returns:
3710            The new Create expression.
3711        """
3712        instance = maybe_copy(self, copy)
3713        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3714
3715        properties_expression = None
3716        if properties:
3717            properties_expression = Properties.from_dict(properties)
3718
3719        return Create(
3720            this=table_expression,
3721            kind="TABLE",
3722            expression=instance,
3723            properties=properties_expression,
3724        )

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:
3726    def lock(self, update: bool = True, copy: bool = True) -> Select:
3727        """
3728        Set the locking read mode for this expression.
3729
3730        Examples:
3731            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3732            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3733
3734            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3735            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3736
3737        Args:
3738            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3739            copy: if `False`, modify this expression instance in-place.
3740
3741        Returns:
3742            The modified expression.
3743        """
3744        inst = maybe_copy(self, copy)
3745        inst.set("locks", [Lock(update=update)])
3746
3747        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:
3749    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3750        """
3751        Set hints for this expression.
3752
3753        Examples:
3754            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3755            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3756
3757        Args:
3758            hints: The SQL code strings to parse as the hints.
3759                If an `Expression` instance is passed, it will be used as-is.
3760            dialect: The dialect used to parse the hints.
3761            copy: If `False`, modify this expression instance in-place.
3762
3763        Returns:
3764            The modified expression.
3765        """
3766        inst = maybe_copy(self, copy)
3767        inst.set(
3768            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3769        )
3770
3771        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]
3773    @property
3774    def named_selects(self) -> t.List[str]:
3775        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
3777    @property
3778    def is_star(self) -> bool:
3779        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3781    @property
3782    def selects(self) -> t.List[Expression]:
3783        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
3789class Subquery(DerivedTable, Query):
3790    arg_types = {
3791        "this": True,
3792        "alias": False,
3793        "with": False,
3794        **QUERY_MODIFIERS,
3795    }
3796
3797    def unnest(self):
3798        """Returns the first non subquery."""
3799        expression = self
3800        while isinstance(expression, Subquery):
3801            expression = expression.this
3802        return expression
3803
3804    def unwrap(self) -> Subquery:
3805        expression = self
3806        while expression.same_parent and expression.is_wrapper:
3807            expression = t.cast(Subquery, expression.parent)
3808        return expression
3809
3810    def select(
3811        self,
3812        *expressions: t.Optional[ExpOrStr],
3813        append: bool = True,
3814        dialect: DialectType = None,
3815        copy: bool = True,
3816        **opts,
3817    ) -> Subquery:
3818        this = maybe_copy(self, copy)
3819        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3820        return this
3821
3822    @property
3823    def is_wrapper(self) -> bool:
3824        """
3825        Whether this Subquery acts as a simple wrapper around another expression.
3826
3827        SELECT * FROM (((SELECT * FROM t)))
3828                      ^
3829                      This corresponds to a "wrapper" Subquery node
3830        """
3831        return all(v is None for k, v in self.args.items() if k != "this")
3832
3833    @property
3834    def is_star(self) -> bool:
3835        return self.this.is_star
3836
3837    @property
3838    def output_name(self) -> str:
3839        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):
3797    def unnest(self):
3798        """Returns the first non subquery."""
3799        expression = self
3800        while isinstance(expression, Subquery):
3801            expression = expression.this
3802        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3804    def unwrap(self) -> Subquery:
3805        expression = self
3806        while expression.same_parent and expression.is_wrapper:
3807            expression = t.cast(Subquery, expression.parent)
3808        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:
3810    def select(
3811        self,
3812        *expressions: t.Optional[ExpOrStr],
3813        append: bool = True,
3814        dialect: DialectType = None,
3815        copy: bool = True,
3816        **opts,
3817    ) -> Subquery:
3818        this = maybe_copy(self, copy)
3819        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3820        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
3822    @property
3823    def is_wrapper(self) -> bool:
3824        """
3825        Whether this Subquery acts as a simple wrapper around another expression.
3826
3827        SELECT * FROM (((SELECT * FROM t)))
3828                      ^
3829                      This corresponds to a "wrapper" Subquery node
3830        """
3831        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
3833    @property
3834    def is_star(self) -> bool:
3835        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3837    @property
3838    def output_name(self) -> str:
3839        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):
3842class TableSample(Expression):
3843    arg_types = {
3844        "this": False,
3845        "expressions": False,
3846        "method": False,
3847        "bucket_numerator": False,
3848        "bucket_denominator": False,
3849        "bucket_field": False,
3850        "percent": False,
3851        "rows": False,
3852        "size": False,
3853        "seed": False,
3854    }
arg_types = {'this': False, 'expressions': False, 'method': False, 'bucket_numerator': False, 'bucket_denominator': False, 'bucket_field': False, 'percent': False, 'rows': False, 'size': False, 'seed': False}
key = 'tablesample'
class Tag(Expression):
3857class Tag(Expression):
3858    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3859
3860    arg_types = {
3861        "this": False,
3862        "prefix": False,
3863        "postfix": False,
3864    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3869class Pivot(Expression):
3870    arg_types = {
3871        "this": False,
3872        "alias": False,
3873        "expressions": False,
3874        "field": False,
3875        "unpivot": False,
3876        "using": False,
3877        "group": False,
3878        "columns": False,
3879        "include_nulls": False,
3880        "default_on_null": False,
3881    }
3882
3883    @property
3884    def unpivot(self) -> bool:
3885        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
3883    @property
3884    def unpivot(self) -> bool:
3885        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3888class Window(Condition):
3889    arg_types = {
3890        "this": True,
3891        "partition_by": False,
3892        "order": False,
3893        "spec": False,
3894        "alias": False,
3895        "over": False,
3896        "first": False,
3897    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3900class WindowSpec(Expression):
3901    arg_types = {
3902        "kind": False,
3903        "start": False,
3904        "start_side": False,
3905        "end": False,
3906        "end_side": False,
3907    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3910class PreWhere(Expression):
3911    pass
key = 'prewhere'
class Where(Expression):
3914class Where(Expression):
3915    pass
key = 'where'
class Star(Expression):
3918class Star(Expression):
3919    arg_types = {"except": False, "replace": False, "rename": False}
3920
3921    @property
3922    def name(self) -> str:
3923        return "*"
3924
3925    @property
3926    def output_name(self) -> str:
3927        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3921    @property
3922    def name(self) -> str:
3923        return "*"
output_name: str
3925    @property
3926    def output_name(self) -> str:
3927        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):
3930class Parameter(Condition):
3931    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3934class SessionParameter(Condition):
3935    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3938class Placeholder(Condition):
3939    arg_types = {"this": False, "kind": False}
3940
3941    @property
3942    def name(self) -> str:
3943        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3941    @property
3942    def name(self) -> str:
3943        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3946class Null(Condition):
3947    arg_types: t.Dict[str, t.Any] = {}
3948
3949    @property
3950    def name(self) -> str:
3951        return "NULL"
3952
3953    def to_py(self) -> Lit[None]:
3954        return None
arg_types: Dict[str, Any] = {}
name: str
3949    @property
3950    def name(self) -> str:
3951        return "NULL"
def to_py(self) -> Literal[None]:
3953    def to_py(self) -> Lit[None]:
3954        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
3957class Boolean(Condition):
3958    def to_py(self) -> bool:
3959        return self.this
def to_py(self) -> bool:
3958    def to_py(self) -> bool:
3959        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

name: str
4399    @property
4400    def name(self) -> str:
4401        return self.expression.name
output_name: str
4403    @property
4404    def output_name(self) -> str:
4405        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:
4407    @classmethod
4408    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4409        """Build a Dot object with a sequence of expressions."""
4410        if len(expressions) < 2:
4411            raise ValueError("Dot requires >= 2 expressions.")
4412
4413        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]
4415    @property
4416    def parts(self) -> t.List[Expression]:
4417        """Return the parts of a table / column in order catalog, db, table."""
4418        this, *parts = self.flatten()
4419
4420        parts.reverse()
4421
4422        for arg in COLUMN_PARTS:
4423            part = this.args.get(arg)
4424
4425            if isinstance(part, Expression):
4426                parts.append(part)
4427
4428        parts.reverse()
4429        return parts

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

key = 'dot'
class DPipe(Binary):
4432class DPipe(Binary):
4433    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4436class EQ(Binary, Predicate):
4437    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4440class NullSafeEQ(Binary, Predicate):
4441    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4444class NullSafeNEQ(Binary, Predicate):
4445    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4449class PropertyEQ(Binary):
4450    pass
key = 'propertyeq'
class Distance(Binary):
4453class Distance(Binary):
4454    pass
key = 'distance'
class Escape(Binary):
4457class Escape(Binary):
4458    pass
key = 'escape'
class Glob(Binary, Predicate):
4461class Glob(Binary, Predicate):
4462    pass
key = 'glob'
class GT(Binary, Predicate):
4465class GT(Binary, Predicate):
4466    pass
key = 'gt'
class GTE(Binary, Predicate):
4469class GTE(Binary, Predicate):
4470    pass
key = 'gte'
class ILike(Binary, Predicate):
4473class ILike(Binary, Predicate):
4474    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4477class ILikeAny(Binary, Predicate):
4478    pass
key = 'ilikeany'
class IntDiv(Binary):
4481class IntDiv(Binary):
4482    pass
key = 'intdiv'
class Is(Binary, Predicate):
4485class Is(Binary, Predicate):
4486    pass
key = 'is'
class Kwarg(Binary):
4489class Kwarg(Binary):
4490    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4493class Like(Binary, Predicate):
4494    pass
key = 'like'
class LikeAny(Binary, Predicate):
4497class LikeAny(Binary, Predicate):
4498    pass
key = 'likeany'
class LT(Binary, Predicate):
4501class LT(Binary, Predicate):
4502    pass
key = 'lt'
class LTE(Binary, Predicate):
4505class LTE(Binary, Predicate):
4506    pass
key = 'lte'
class Mod(Binary):
4509class Mod(Binary):
4510    pass
key = 'mod'
class Mul(Binary):
4513class Mul(Binary):
4514    pass
key = 'mul'
class NEQ(Binary, Predicate):
4517class NEQ(Binary, Predicate):
4518    pass
key = 'neq'
class Operator(Binary):
4522class Operator(Binary):
4523    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4526class SimilarTo(Binary, Predicate):
4527    pass
key = 'similarto'
class Slice(Binary):
4530class Slice(Binary):
4531    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4534class Sub(Binary):
4535    pass
key = 'sub'
class Unary(Condition):
4540class Unary(Condition):
4541    pass
key = 'unary'
class BitwiseNot(Unary):
4544class BitwiseNot(Unary):
4545    pass
key = 'bitwisenot'
class Not(Unary):
4548class Not(Unary):
4549    pass
key = 'not'
class Paren(Unary):
4552class Paren(Unary):
4553    @property
4554    def output_name(self) -> str:
4555        return self.this.name
output_name: str
4553    @property
4554    def output_name(self) -> str:
4555        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):
4558class Neg(Unary):
4559    def to_py(self) -> int | Decimal:
4560        if self.is_number:
4561            return self.this.to_py() * -1
4562        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4559    def to_py(self) -> int | Decimal:
4560        if self.is_number:
4561            return self.this.to_py() * -1
4562        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4565class Alias(Expression):
4566    arg_types = {"this": True, "alias": False}
4567
4568    @property
4569    def output_name(self) -> str:
4570        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4568    @property
4569    def output_name(self) -> str:
4570        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):
4575class PivotAlias(Alias):
4576    pass
key = 'pivotalias'
class PivotAny(Expression):
4581class PivotAny(Expression):
4582    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4585class Aliases(Expression):
4586    arg_types = {"this": True, "expressions": True}
4587
4588    @property
4589    def aliases(self):
4590        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4588    @property
4589    def aliases(self):
4590        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4594class AtIndex(Expression):
4595    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4598class AtTimeZone(Expression):
4599    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4602class FromTimeZone(Expression):
4603    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4606class Between(Predicate):
4607    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4610class Bracket(Condition):
4611    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4612    arg_types = {
4613        "this": True,
4614        "expressions": True,
4615        "offset": False,
4616        "safe": False,
4617        "returns_list_for_maps": False,
4618    }
4619
4620    @property
4621    def output_name(self) -> str:
4622        if len(self.expressions) == 1:
4623            return self.expressions[0].output_name
4624
4625        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4620    @property
4621    def output_name(self) -> str:
4622        if len(self.expressions) == 1:
4623            return self.expressions[0].output_name
4624
4625        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):
4628class Distinct(Expression):
4629    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4632class In(Predicate):
4633    arg_types = {
4634        "this": True,
4635        "expressions": False,
4636        "query": False,
4637        "unnest": False,
4638        "field": False,
4639        "is_global": False,
4640    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4644class ForIn(Expression):
4645    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4648class TimeUnit(Expression):
4649    """Automatically converts unit arg into a var."""
4650
4651    arg_types = {"unit": False}
4652
4653    UNABBREVIATED_UNIT_NAME = {
4654        "D": "DAY",
4655        "H": "HOUR",
4656        "M": "MINUTE",
4657        "MS": "MILLISECOND",
4658        "NS": "NANOSECOND",
4659        "Q": "QUARTER",
4660        "S": "SECOND",
4661        "US": "MICROSECOND",
4662        "W": "WEEK",
4663        "Y": "YEAR",
4664    }
4665
4666    VAR_LIKE = (Column, Literal, Var)
4667
4668    def __init__(self, **args):
4669        unit = args.get("unit")
4670        if isinstance(unit, self.VAR_LIKE):
4671            args["unit"] = Var(
4672                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4673            )
4674        elif isinstance(unit, Week):
4675            unit.set("this", Var(this=unit.this.name.upper()))
4676
4677        super().__init__(**args)
4678
4679    @property
4680    def unit(self) -> t.Optional[Var | IntervalSpan]:
4681        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4668    def __init__(self, **args):
4669        unit = args.get("unit")
4670        if isinstance(unit, self.VAR_LIKE):
4671            args["unit"] = Var(
4672                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4673            )
4674        elif isinstance(unit, Week):
4675            unit.set("this", Var(this=unit.this.name.upper()))
4676
4677        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]
4679    @property
4680    def unit(self) -> t.Optional[Var | IntervalSpan]:
4681        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4684class IntervalOp(TimeUnit):
4685    arg_types = {"unit": True, "expression": True}
4686
4687    def interval(self):
4688        return Interval(
4689            this=self.expression.copy(),
4690            unit=self.unit.copy(),
4691        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4687    def interval(self):
4688        return Interval(
4689            this=self.expression.copy(),
4690            unit=self.unit.copy(),
4691        )
key = 'intervalop'
class IntervalSpan(DataType):
4697class IntervalSpan(DataType):
4698    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4701class Interval(TimeUnit):
4702    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4705class IgnoreNulls(Expression):
4706    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4709class RespectNulls(Expression):
4710    pass
key = 'respectnulls'
class HavingMax(Expression):
4714class HavingMax(Expression):
4715    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4719class Func(Condition):
4720    """
4721    The base class for all function expressions.
4722
4723    Attributes:
4724        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4725            treated as a variable length argument and the argument's value will be stored as a list.
4726        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4727            function expression. These values are used to map this node to a name during parsing as
4728            well as to provide the function's name during SQL string generation. By default the SQL
4729            name is set to the expression's class name transformed to snake case.
4730    """
4731
4732    is_var_len_args = False
4733
4734    @classmethod
4735    def from_arg_list(cls, args):
4736        if cls.is_var_len_args:
4737            all_arg_keys = list(cls.arg_types)
4738            # If this function supports variable length argument treat the last argument as such.
4739            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4740            num_non_var = len(non_var_len_arg_keys)
4741
4742            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4743            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4744        else:
4745            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4746
4747        return cls(**args_dict)
4748
4749    @classmethod
4750    def sql_names(cls):
4751        if cls is Func:
4752            raise NotImplementedError(
4753                "SQL name is only supported by concrete function implementations"
4754            )
4755        if "_sql_names" not in cls.__dict__:
4756            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4757        return cls._sql_names
4758
4759    @classmethod
4760    def sql_name(cls):
4761        return cls.sql_names()[0]
4762
4763    @classmethod
4764    def default_parser_mappings(cls):
4765        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):
4734    @classmethod
4735    def from_arg_list(cls, args):
4736        if cls.is_var_len_args:
4737            all_arg_keys = list(cls.arg_types)
4738            # If this function supports variable length argument treat the last argument as such.
4739            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4740            num_non_var = len(non_var_len_arg_keys)
4741
4742            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4743            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4744        else:
4745            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4746
4747        return cls(**args_dict)
@classmethod
def sql_names(cls):
4749    @classmethod
4750    def sql_names(cls):
4751        if cls is Func:
4752            raise NotImplementedError(
4753                "SQL name is only supported by concrete function implementations"
4754            )
4755        if "_sql_names" not in cls.__dict__:
4756            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4757        return cls._sql_names
@classmethod
def sql_name(cls):
4759    @classmethod
4760    def sql_name(cls):
4761        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4763    @classmethod
4764    def default_parser_mappings(cls):
4765        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4768class AggFunc(Func):
4769    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4772class ParameterizedAgg(AggFunc):
4773    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4776class Abs(Func):
4777    pass
key = 'abs'
class ArgMax(AggFunc):
4780class ArgMax(AggFunc):
4781    arg_types = {"this": True, "expression": True, "count": False}
4782    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4785class ArgMin(AggFunc):
4786    arg_types = {"this": True, "expression": True, "count": False}
4787    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4790class ApproxTopK(AggFunc):
4791    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4794class Flatten(Func):
4795    pass
key = 'flatten'
class Transform(Func):
4799class Transform(Func):
4800    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4803class Anonymous(Func):
4804    arg_types = {"this": True, "expressions": False}
4805    is_var_len_args = True
4806
4807    @property
4808    def name(self) -> str:
4809        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
4807    @property
4808    def name(self) -> str:
4809        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4812class AnonymousAggFunc(AggFunc):
4813    arg_types = {"this": True, "expressions": False}
4814    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4818class CombinedAggFunc(AnonymousAggFunc):
4819    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4822class CombinedParameterizedAgg(ParameterizedAgg):
4823    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):
4828class Hll(AggFunc):
4829    arg_types = {"this": True, "expressions": False}
4830    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4833class ApproxDistinct(AggFunc):
4834    arg_types = {"this": True, "accuracy": False}
4835    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4838class Array(Func):
4839    arg_types = {"expressions": False, "bracket_notation": False}
4840    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4844class ToArray(Func):
4845    pass
key = 'toarray'
class List(Func):
4849class List(Func):
4850    arg_types = {"expressions": False}
4851    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4855class Pad(Func):
4856    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):
4861class ToChar(Func):
4862    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4867class ToNumber(Func):
4868    arg_types = {
4869        "this": True,
4870        "format": False,
4871        "nlsparam": False,
4872        "precision": False,
4873        "scale": False,
4874    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4878class Convert(Func):
4879    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
4882class ConvertTimezone(Func):
4883    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):
4886class GenerateSeries(Func):
4887    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):
4893class ExplodingGenerateSeries(GenerateSeries):
4894    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
4897class ArrayAgg(AggFunc):
4898    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4901class ArrayUniqueAgg(AggFunc):
4902    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4905class ArrayAll(Func):
4906    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4910class ArrayAny(Func):
4911    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4914class ArrayConcat(Func):
4915    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4916    arg_types = {"this": True, "expressions": False}
4917    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4920class ArrayConstructCompact(Func):
4921    arg_types = {"expressions": True}
4922    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4925class ArrayContains(Binary, Func):
4926    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4929class ArrayContainsAll(Binary, Func):
4930    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4933class ArrayFilter(Func):
4934    arg_types = {"this": True, "expression": True}
4935    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4938class ArrayToString(Func):
4939    arg_types = {"this": True, "expression": True, "null": False}
4940    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4943class StringToArray(Func):
4944    arg_types = {"this": True, "expression": True, "null": False}
4945    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4948class ArrayOverlaps(Binary, Func):
4949    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4952class ArraySize(Func):
4953    arg_types = {"this": True, "expression": False}
4954    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4957class ArraySort(Func):
4958    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4961class ArraySum(Func):
4962    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4965class ArrayUnionAgg(AggFunc):
4966    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4969class Avg(AggFunc):
4970    pass
key = 'avg'
class AnyValue(AggFunc):
4973class AnyValue(AggFunc):
4974    pass
key = 'anyvalue'
class Lag(AggFunc):
4977class Lag(AggFunc):
4978    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4981class Lead(AggFunc):
4982    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4987class First(AggFunc):
4988    pass
key = 'first'
class Last(AggFunc):
4991class Last(AggFunc):
4992    pass
key = 'last'
class FirstValue(AggFunc):
4995class FirstValue(AggFunc):
4996    pass
key = 'firstvalue'
class LastValue(AggFunc):
4999class LastValue(AggFunc):
5000    pass
key = 'lastvalue'
class NthValue(AggFunc):
5003class NthValue(AggFunc):
5004    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5007class Case(Func):
5008    arg_types = {"this": False, "ifs": True, "default": False}
5009
5010    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5011        instance = maybe_copy(self, copy)
5012        instance.append(
5013            "ifs",
5014            If(
5015                this=maybe_parse(condition, copy=copy, **opts),
5016                true=maybe_parse(then, copy=copy, **opts),
5017            ),
5018        )
5019        return instance
5020
5021    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5022        instance = maybe_copy(self, copy)
5023        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5024        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:
5010    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5011        instance = maybe_copy(self, copy)
5012        instance.append(
5013            "ifs",
5014            If(
5015                this=maybe_parse(condition, copy=copy, **opts),
5016                true=maybe_parse(then, copy=copy, **opts),
5017            ),
5018        )
5019        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5021    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5022        instance = maybe_copy(self, copy)
5023        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5024        return instance
key = 'case'
class Cast(Func):
5027class Cast(Func):
5028    arg_types = {
5029        "this": True,
5030        "to": True,
5031        "format": False,
5032        "safe": False,
5033        "action": False,
5034    }
5035
5036    @property
5037    def name(self) -> str:
5038        return self.this.name
5039
5040    @property
5041    def to(self) -> DataType:
5042        return self.args["to"]
5043
5044    @property
5045    def output_name(self) -> str:
5046        return self.name
5047
5048    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5049        """
5050        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5051        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5052        array<int> != array<float>.
5053
5054        Args:
5055            dtypes: the data types to compare this Cast's DataType to.
5056
5057        Returns:
5058            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5059        """
5060        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5036    @property
5037    def name(self) -> str:
5038        return self.this.name
to: DataType
5040    @property
5041    def to(self) -> DataType:
5042        return self.args["to"]
output_name: str
5044    @property
5045    def output_name(self) -> str:
5046        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:
5048    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5049        """
5050        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5051        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5052        array<int> != array<float>.
5053
5054        Args:
5055            dtypes: the data types to compare this Cast's DataType to.
5056
5057        Returns:
5058            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5059        """
5060        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):
5063class TryCast(Cast):
5064    pass
key = 'trycast'
class Try(Func):
5067class Try(Func):
5068    pass
key = 'try'
class CastToStrType(Func):
5071class CastToStrType(Func):
5072    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5075class Collate(Binary, Func):
5076    pass
key = 'collate'
class Ceil(Func):
5079class Ceil(Func):
5080    arg_types = {"this": True, "decimals": False}
5081    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5084class Coalesce(Func):
5085    arg_types = {"this": True, "expressions": False}
5086    is_var_len_args = True
5087    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5090class Chr(Func):
5091    arg_types = {"this": True, "charset": False, "expressions": False}
5092    is_var_len_args = True
5093    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5096class Concat(Func):
5097    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5098    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5101class ConcatWs(Concat):
5102    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5106class ConnectByRoot(Func):
5107    pass
key = 'connectbyroot'
class Count(AggFunc):
5110class Count(AggFunc):
5111    arg_types = {"this": False, "expressions": False}
5112    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5115class CountIf(AggFunc):
5116    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5120class Cbrt(Func):
5121    pass
key = 'cbrt'
class CurrentDate(Func):
5124class CurrentDate(Func):
5125    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5128class CurrentDatetime(Func):
5129    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5132class CurrentTime(Func):
5133    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5136class CurrentTimestamp(Func):
5137    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5140class CurrentUser(Func):
5141    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5144class DateAdd(Func, IntervalOp):
5145    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5148class DateSub(Func, IntervalOp):
5149    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5152class DateDiff(Func, TimeUnit):
5153    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5154    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5157class DateTrunc(Func):
5158    arg_types = {"unit": True, "this": True, "zone": False}
5159
5160    def __init__(self, **args):
5161        unit = args.get("unit")
5162        if isinstance(unit, TimeUnit.VAR_LIKE):
5163            args["unit"] = Literal.string(
5164                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5165            )
5166        elif isinstance(unit, Week):
5167            unit.set("this", Literal.string(unit.this.name.upper()))
5168
5169        super().__init__(**args)
5170
5171    @property
5172    def unit(self) -> Expression:
5173        return self.args["unit"]
DateTrunc(**args)
5160    def __init__(self, **args):
5161        unit = args.get("unit")
5162        if isinstance(unit, TimeUnit.VAR_LIKE):
5163            args["unit"] = Literal.string(
5164                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5165            )
5166        elif isinstance(unit, Week):
5167            unit.set("this", Literal.string(unit.this.name.upper()))
5168
5169        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5171    @property
5172    def unit(self) -> Expression:
5173        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5178class Datetime(Func):
5179    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5182class DatetimeAdd(Func, IntervalOp):
5183    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5186class DatetimeSub(Func, IntervalOp):
5187    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5190class DatetimeDiff(Func, TimeUnit):
5191    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5194class DatetimeTrunc(Func, TimeUnit):
5195    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5198class DayOfWeek(Func):
5199    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5202class DayOfMonth(Func):
5203    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5206class DayOfYear(Func):
5207    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5210class ToDays(Func):
5211    pass
key = 'todays'
class WeekOfYear(Func):
5214class WeekOfYear(Func):
5215    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5218class MonthsBetween(Func):
5219    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5222class LastDay(Func, TimeUnit):
5223    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5224    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5227class Extract(Func):
5228    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5231class Timestamp(Func):
5232    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5235class TimestampAdd(Func, TimeUnit):
5236    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5239class TimestampSub(Func, TimeUnit):
5240    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5243class TimestampDiff(Func, TimeUnit):
5244    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5245    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5248class TimestampTrunc(Func, TimeUnit):
5249    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5252class TimeAdd(Func, TimeUnit):
5253    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5256class TimeSub(Func, TimeUnit):
5257    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5260class TimeDiff(Func, TimeUnit):
5261    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5264class TimeTrunc(Func, TimeUnit):
5265    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5268class DateFromParts(Func):
5269    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5270    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5273class TimeFromParts(Func):
5274    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5275    arg_types = {
5276        "hour": True,
5277        "min": True,
5278        "sec": True,
5279        "nano": False,
5280        "fractions": False,
5281        "precision": False,
5282    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5285class DateStrToDate(Func):
5286    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5289class DateToDateStr(Func):
5290    pass
key = 'datetodatestr'
class DateToDi(Func):
5293class DateToDi(Func):
5294    pass
key = 'datetodi'
class Date(Func):
5298class Date(Func):
5299    arg_types = {"this": False, "zone": False, "expressions": False}
5300    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5303class Day(Func):
5304    pass
key = 'day'
class Decode(Func):
5307class Decode(Func):
5308    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5311class DiToDate(Func):
5312    pass
key = 'ditodate'
class Encode(Func):
5315class Encode(Func):
5316    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5319class Exp(Func):
5320    pass
key = 'exp'
class Explode(Func):
5324class Explode(Func):
5325    arg_types = {"this": True, "expressions": False}
5326    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5329class ExplodeOuter(Explode):
5330    pass
key = 'explodeouter'
class Posexplode(Explode):
5333class Posexplode(Explode):
5334    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5337class PosexplodeOuter(Posexplode, ExplodeOuter):
5338    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5341class Unnest(Func, UDTF):
5342    arg_types = {
5343        "expressions": True,
5344        "alias": False,
5345        "offset": False,
5346    }
5347
5348    @property
5349    def selects(self) -> t.List[Expression]:
5350        columns = super().selects
5351        offset = self.args.get("offset")
5352        if offset:
5353            columns = columns + [to_identifier("offset") if offset is True else offset]
5354        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5348    @property
5349    def selects(self) -> t.List[Expression]:
5350        columns = super().selects
5351        offset = self.args.get("offset")
5352        if offset:
5353            columns = columns + [to_identifier("offset") if offset is True else offset]
5354        return columns
key = 'unnest'
class Floor(Func):
5357class Floor(Func):
5358    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5361class FromBase64(Func):
5362    pass
key = 'frombase64'
class ToBase64(Func):
5365class ToBase64(Func):
5366    pass
key = 'tobase64'
class GapFill(Func):
5369class GapFill(Func):
5370    arg_types = {
5371        "this": True,
5372        "ts_column": True,
5373        "bucket_width": True,
5374        "partitioning_columns": False,
5375        "value_columns": False,
5376        "origin": False,
5377        "ignore_nulls": False,
5378    }
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):
5382class GenerateDateArray(Func):
5383    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5387class GenerateTimestampArray(Func):
5388    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5391class Greatest(Func):
5392    arg_types = {"this": True, "expressions": False}
5393    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5396class GroupConcat(AggFunc):
5397    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5400class Hex(Func):
5401    pass
key = 'hex'
class LowerHex(Hex):
5404class LowerHex(Hex):
5405    pass
key = 'lowerhex'
class Xor(Connector, Func):
5408class Xor(Connector, Func):
5409    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5412class If(Func):
5413    arg_types = {"this": True, "true": True, "false": False}
5414    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5417class Nullif(Func):
5418    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5421class Initcap(Func):
5422    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5425class IsNan(Func):
5426    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5429class IsInf(Func):
5430    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5433class JSONPath(Expression):
5434    arg_types = {"expressions": True}
5435
5436    @property
5437    def output_name(self) -> str:
5438        last_segment = self.expressions[-1].this
5439        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5436    @property
5437    def output_name(self) -> str:
5438        last_segment = self.expressions[-1].this
5439        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):
5442class JSONPathPart(Expression):
5443    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5446class JSONPathFilter(JSONPathPart):
5447    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5450class JSONPathKey(JSONPathPart):
5451    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5454class JSONPathRecursive(JSONPathPart):
5455    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5458class JSONPathRoot(JSONPathPart):
5459    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5462class JSONPathScript(JSONPathPart):
5463    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5466class JSONPathSlice(JSONPathPart):
5467    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5470class JSONPathSelector(JSONPathPart):
5471    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5474class JSONPathSubscript(JSONPathPart):
5475    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5478class JSONPathUnion(JSONPathPart):
5479    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5482class JSONPathWildcard(JSONPathPart):
5483    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5486class FormatJson(Expression):
5487    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5490class JSONKeyValue(Expression):
5491    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5494class JSONObject(Func):
5495    arg_types = {
5496        "expressions": False,
5497        "null_handling": False,
5498        "unique_keys": False,
5499        "return_type": False,
5500        "encoding": False,
5501    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5504class JSONObjectAgg(AggFunc):
5505    arg_types = {
5506        "expressions": False,
5507        "null_handling": False,
5508        "unique_keys": False,
5509        "return_type": False,
5510        "encoding": False,
5511    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5515class JSONArray(Func):
5516    arg_types = {
5517        "expressions": True,
5518        "null_handling": False,
5519        "return_type": False,
5520        "strict": False,
5521    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5525class JSONArrayAgg(Func):
5526    arg_types = {
5527        "this": True,
5528        "order": False,
5529        "null_handling": False,
5530        "return_type": False,
5531        "strict": False,
5532    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5537class JSONColumnDef(Expression):
5538    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):
5541class JSONSchema(Expression):
5542    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5546class JSONTable(Func):
5547    arg_types = {
5548        "this": True,
5549        "schema": True,
5550        "path": False,
5551        "error_handling": False,
5552        "empty_handling": False,
5553    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5557class ObjectInsert(Func):
5558    arg_types = {
5559        "this": True,
5560        "key": True,
5561        "value": True,
5562        "update_flag": False,
5563    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5566class OpenJSONColumnDef(Expression):
5567    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):
5570class OpenJSON(Func):
5571    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5574class JSONBContains(Binary, Func):
5575    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5578class JSONExtract(Binary, Func):
5579    arg_types = {
5580        "this": True,
5581        "expression": True,
5582        "only_json_types": False,
5583        "expressions": False,
5584        "variant_extract": False,
5585    }
5586    _sql_names = ["JSON_EXTRACT"]
5587    is_var_len_args = True
5588
5589    @property
5590    def output_name(self) -> str:
5591        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
5589    @property
5590    def output_name(self) -> str:
5591        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):
5594class JSONExtractScalar(Binary, Func):
5595    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5596    _sql_names = ["JSON_EXTRACT_SCALAR"]
5597    is_var_len_args = True
5598
5599    @property
5600    def output_name(self) -> str:
5601        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
5599    @property
5600    def output_name(self) -> str:
5601        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):
5604class JSONBExtract(Binary, Func):
5605    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5608class JSONBExtractScalar(Binary, Func):
5609    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5612class JSONFormat(Func):
5613    arg_types = {"this": False, "options": False}
5614    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5618class JSONArrayContains(Binary, Predicate, Func):
5619    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5622class ParseJSON(Func):
5623    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5624    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5625    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5626    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5629class Least(Func):
5630    arg_types = {"this": True, "expressions": False}
5631    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5634class Left(Func):
5635    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5642class Length(Func):
5643    arg_types = {"this": True, "binary": False}
5644    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5647class Levenshtein(Func):
5648    arg_types = {
5649        "this": True,
5650        "expression": False,
5651        "ins_cost": False,
5652        "del_cost": False,
5653        "sub_cost": False,
5654    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5657class Ln(Func):
5658    pass
key = 'ln'
class Log(Func):
5661class Log(Func):
5662    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5665class LogicalOr(AggFunc):
5666    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5669class LogicalAnd(AggFunc):
5670    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5673class Lower(Func):
5674    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5677class Map(Func):
5678    arg_types = {"keys": False, "values": False}
5679
5680    @property
5681    def keys(self) -> t.List[Expression]:
5682        keys = self.args.get("keys")
5683        return keys.expressions if keys else []
5684
5685    @property
5686    def values(self) -> t.List[Expression]:
5687        values = self.args.get("values")
5688        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5680    @property
5681    def keys(self) -> t.List[Expression]:
5682        keys = self.args.get("keys")
5683        return keys.expressions if keys else []
values: List[Expression]
5685    @property
5686    def values(self) -> t.List[Expression]:
5687        values = self.args.get("values")
5688        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5692class ToMap(Func):
5693    pass
key = 'tomap'
class MapFromEntries(Func):
5696class MapFromEntries(Func):
5697    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5701class ScopeResolution(Expression):
5702    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
5705class Stream(Expression):
5706    pass
key = 'stream'
class StarMap(Func):
5709class StarMap(Func):
5710    pass
key = 'starmap'
class VarMap(Func):
5713class VarMap(Func):
5714    arg_types = {"keys": True, "values": True}
5715    is_var_len_args = True
5716
5717    @property
5718    def keys(self) -> t.List[Expression]:
5719        return self.args["keys"].expressions
5720
5721    @property
5722    def values(self) -> t.List[Expression]:
5723        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5717    @property
5718    def keys(self) -> t.List[Expression]:
5719        return self.args["keys"].expressions
values: List[Expression]
5721    @property
5722    def values(self) -> t.List[Expression]:
5723        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5727class MatchAgainst(Func):
5728    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5731class Max(AggFunc):
5732    arg_types = {"this": True, "expressions": False}
5733    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5736class MD5(Func):
5737    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5741class MD5Digest(Func):
5742    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5745class Min(AggFunc):
5746    arg_types = {"this": True, "expressions": False}
5747    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5750class Month(Func):
5751    pass
key = 'month'
class AddMonths(Func):
5754class AddMonths(Func):
5755    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5758class Nvl2(Func):
5759    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5763class Predict(Func):
5764    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5767class Pow(Binary, Func):
5768    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5771class PercentileCont(AggFunc):
5772    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5775class PercentileDisc(AggFunc):
5776    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5779class Quantile(AggFunc):
5780    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5783class ApproxQuantile(Quantile):
5784    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):
5787class Quarter(Func):
5788    pass
key = 'quarter'
class Rand(Func):
5793class Rand(Func):
5794    _sql_names = ["RAND", "RANDOM"]
5795    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5798class Randn(Func):
5799    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5802class RangeN(Func):
5803    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5806class ReadCSV(Func):
5807    _sql_names = ["READ_CSV"]
5808    is_var_len_args = True
5809    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5812class Reduce(Func):
5813    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):
5816class RegexpExtract(Func):
5817    arg_types = {
5818        "this": True,
5819        "expression": True,
5820        "position": False,
5821        "occurrence": False,
5822        "parameters": False,
5823        "group": False,
5824    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5827class RegexpReplace(Func):
5828    arg_types = {
5829        "this": True,
5830        "expression": True,
5831        "replacement": False,
5832        "position": False,
5833        "occurrence": False,
5834        "modifiers": False,
5835    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5838class RegexpLike(Binary, Func):
5839    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5842class RegexpILike(Binary, Func):
5843    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5848class RegexpSplit(Func):
5849    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5852class Repeat(Func):
5853    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5858class Round(Func):
5859    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5862class RowNumber(Func):
5863    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5866class SafeDivide(Func):
5867    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5870class SHA(Func):
5871    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5874class SHA2(Func):
5875    _sql_names = ["SHA2"]
5876    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5879class Sign(Func):
5880    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5883class SortArray(Func):
5884    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5887class Split(Func):
5888    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5893class Substring(Func):
5894    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5897class StandardHash(Func):
5898    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5901class StartsWith(Func):
5902    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5903    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5906class StrPosition(Func):
5907    arg_types = {
5908        "this": True,
5909        "substr": True,
5910        "position": False,
5911        "instance": False,
5912    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5915class StrToDate(Func):
5916    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
5919class StrToTime(Func):
5920    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):
5925class StrToUnix(Func):
5926    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5931class StrToMap(Func):
5932    arg_types = {
5933        "this": True,
5934        "pair_delim": False,
5935        "key_value_delim": False,
5936        "duplicate_resolution_callback": False,
5937    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5940class NumberToStr(Func):
5941    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5944class FromBase(Func):
5945    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5948class Struct(Func):
5949    arg_types = {"expressions": False}
5950    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5953class StructExtract(Func):
5954    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5959class Stuff(Func):
5960    _sql_names = ["STUFF", "INSERT"]
5961    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):
5964class Sum(AggFunc):
5965    pass
key = 'sum'
class Sqrt(Func):
5968class Sqrt(Func):
5969    pass
key = 'sqrt'
class Stddev(AggFunc):
5972class Stddev(AggFunc):
5973    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
5976class StddevPop(AggFunc):
5977    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5980class StddevSamp(AggFunc):
5981    pass
key = 'stddevsamp'
class Time(Func):
5985class Time(Func):
5986    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
5989class TimeToStr(Func):
5990    arg_types = {"this": True, "format": True, "culture": False, "timezone": False}
arg_types = {'this': True, 'format': True, 'culture': False, 'timezone': False}
key = 'timetostr'
class TimeToTimeStr(Func):
5993class TimeToTimeStr(Func):
5994    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5997class TimeToUnix(Func):
5998    pass
key = 'timetounix'
class TimeStrToDate(Func):
6001class TimeStrToDate(Func):
6002    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6005class TimeStrToTime(Func):
6006    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
6009class TimeStrToUnix(Func):
6010    pass
key = 'timestrtounix'
class Trim(Func):
6013class Trim(Func):
6014    arg_types = {
6015        "this": True,
6016        "expression": False,
6017        "position": False,
6018        "collation": False,
6019    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6022class TsOrDsAdd(Func, TimeUnit):
6023    # return_type is used to correctly cast the arguments of this expression when transpiling it
6024    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6025
6026    @property
6027    def return_type(self) -> DataType:
6028        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
6026    @property
6027    def return_type(self) -> DataType:
6028        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6031class TsOrDsDiff(Func, TimeUnit):
6032    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6035class TsOrDsToDateStr(Func):
6036    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6039class TsOrDsToDate(Func):
6040    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6043class TsOrDsToTime(Func):
6044    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6047class TsOrDsToTimestamp(Func):
6048    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6051class TsOrDiToDi(Func):
6052    pass
key = 'tsorditodi'
class Unhex(Func):
6055class Unhex(Func):
6056    pass
key = 'unhex'
class UnixDate(Func):
6060class UnixDate(Func):
6061    pass
key = 'unixdate'
class UnixToStr(Func):
6064class UnixToStr(Func):
6065    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6070class UnixToTime(Func):
6071    arg_types = {
6072        "this": True,
6073        "scale": False,
6074        "zone": False,
6075        "hours": False,
6076        "minutes": False,
6077        "format": False,
6078    }
6079
6080    SECONDS = Literal.number(0)
6081    DECIS = Literal.number(1)
6082    CENTIS = Literal.number(2)
6083    MILLIS = Literal.number(3)
6084    DECIMILLIS = Literal.number(4)
6085    CENTIMILLIS = Literal.number(5)
6086    MICROS = Literal.number(6)
6087    DECIMICROS = Literal.number(7)
6088    CENTIMICROS = Literal.number(8)
6089    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):
6092class UnixToTimeStr(Func):
6093    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
6096class TimestampFromParts(Func):
6097    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6098    arg_types = {
6099        "year": True,
6100        "month": True,
6101        "day": True,
6102        "hour": True,
6103        "min": True,
6104        "sec": True,
6105        "nano": False,
6106        "zone": False,
6107        "milli": False,
6108    }
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):
6111class Upper(Func):
6112    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6115class Corr(Binary, AggFunc):
6116    pass
key = 'corr'
class Variance(AggFunc):
6119class Variance(AggFunc):
6120    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6123class VariancePop(AggFunc):
6124    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6127class CovarSamp(Binary, AggFunc):
6128    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6131class CovarPop(Binary, AggFunc):
6132    pass
key = 'covarpop'
class Week(Func):
6135class Week(Func):
6136    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6139class XMLTable(Func):
6140    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):
6143class Year(Func):
6144    pass
key = 'year'
class Use(Expression):
6147class Use(Expression):
6148    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6151class Merge(Expression):
6152    arg_types = {
6153        "this": True,
6154        "using": True,
6155        "on": True,
6156        "expressions": True,
6157        "with": False,
6158    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6161class When(Func):
6162    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):
6167class NextValueFor(Func):
6168    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6173class Semicolon(Expression):
6174    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 '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'>, '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:
6214def maybe_parse(
6215    sql_or_expression: ExpOrStr,
6216    *,
6217    into: t.Optional[IntoType] = None,
6218    dialect: DialectType = None,
6219    prefix: t.Optional[str] = None,
6220    copy: bool = False,
6221    **opts,
6222) -> Expression:
6223    """Gracefully handle a possible string or expression.
6224
6225    Example:
6226        >>> maybe_parse("1")
6227        Literal(this=1, is_string=False)
6228        >>> maybe_parse(to_identifier("x"))
6229        Identifier(this=x, quoted=False)
6230
6231    Args:
6232        sql_or_expression: the SQL code string or an expression
6233        into: the SQLGlot Expression to parse into
6234        dialect: the dialect used to parse the input expressions (in the case that an
6235            input expression is a SQL string).
6236        prefix: a string to prefix the sql with before it gets parsed
6237            (automatically includes a space)
6238        copy: whether to copy the expression.
6239        **opts: other options to use to parse the input expressions (again, in the case
6240            that an input expression is a SQL string).
6241
6242    Returns:
6243        Expression: the parsed or given expression.
6244    """
6245    if isinstance(sql_or_expression, Expression):
6246        if copy:
6247            return sql_or_expression.copy()
6248        return sql_or_expression
6249
6250    if sql_or_expression is None:
6251        raise ParseError("SQL cannot be None")
6252
6253    import sqlglot
6254
6255    sql = str(sql_or_expression)
6256    if prefix:
6257        sql = f"{prefix} {sql}"
6258
6259    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):
6270def maybe_copy(instance, copy=True):
6271    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:
6491def union(
6492    left: ExpOrStr,
6493    right: ExpOrStr,
6494    distinct: bool = True,
6495    dialect: DialectType = None,
6496    copy: bool = True,
6497    **opts,
6498) -> Union:
6499    """
6500    Initializes a syntax tree from one UNION expression.
6501
6502    Example:
6503        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6504        'SELECT * FROM foo UNION SELECT * FROM bla'
6505
6506    Args:
6507        left: the SQL code string corresponding to the left-hand side.
6508            If an `Expression` instance is passed, it will be used as-is.
6509        right: the SQL code string corresponding to the right-hand side.
6510            If an `Expression` instance is passed, it will be used as-is.
6511        distinct: set the DISTINCT flag if and only if this is true.
6512        dialect: the dialect used to parse the input expression.
6513        copy: whether to copy the expression.
6514        opts: other options to use to parse the input expressions.
6515
6516    Returns:
6517        The new Union instance.
6518    """
6519    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6520    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6521
6522    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:
6525def intersect(
6526    left: ExpOrStr,
6527    right: ExpOrStr,
6528    distinct: bool = True,
6529    dialect: DialectType = None,
6530    copy: bool = True,
6531    **opts,
6532) -> Intersect:
6533    """
6534    Initializes a syntax tree from one INTERSECT expression.
6535
6536    Example:
6537        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6538        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6539
6540    Args:
6541        left: the SQL code string corresponding to the left-hand side.
6542            If an `Expression` instance is passed, it will be used as-is.
6543        right: the SQL code string corresponding to the right-hand side.
6544            If an `Expression` instance is passed, it will be used as-is.
6545        distinct: set the DISTINCT flag if and only if this is true.
6546        dialect: the dialect used to parse the input expression.
6547        copy: whether to copy the expression.
6548        opts: other options to use to parse the input expressions.
6549
6550    Returns:
6551        The new Intersect instance.
6552    """
6553    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6554    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6555
6556    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:
6559def except_(
6560    left: ExpOrStr,
6561    right: ExpOrStr,
6562    distinct: bool = True,
6563    dialect: DialectType = None,
6564    copy: bool = True,
6565    **opts,
6566) -> Except:
6567    """
6568    Initializes a syntax tree from one EXCEPT expression.
6569
6570    Example:
6571        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6572        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6573
6574    Args:
6575        left: the SQL code string corresponding to the left-hand side.
6576            If an `Expression` instance is passed, it will be used as-is.
6577        right: the SQL code string corresponding to the right-hand side.
6578            If an `Expression` instance is passed, it will be used as-is.
6579        distinct: set the DISTINCT flag if and only if this is true.
6580        dialect: the dialect used to parse the input expression.
6581        copy: whether to copy the expression.
6582        opts: other options to use to parse the input expressions.
6583
6584    Returns:
6585        The new Except instance.
6586    """
6587    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6588    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6589
6590    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:
6593def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6594    """
6595    Initializes a syntax tree from one or multiple SELECT expressions.
6596
6597    Example:
6598        >>> select("col1", "col2").from_("tbl").sql()
6599        'SELECT col1, col2 FROM tbl'
6600
6601    Args:
6602        *expressions: the SQL code string to parse as the expressions of a
6603            SELECT statement. If an Expression instance is passed, this is used as-is.
6604        dialect: the dialect used to parse the input expressions (in the case that an
6605            input expression is a SQL string).
6606        **opts: other options to use to parse the input expressions (again, in the case
6607            that an input expression is a SQL string).
6608
6609    Returns:
6610        Select: the syntax tree for the SELECT statement.
6611    """
6612    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:
6615def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6616    """
6617    Initializes a syntax tree from a FROM expression.
6618
6619    Example:
6620        >>> from_("tbl").select("col1", "col2").sql()
6621        'SELECT col1, col2 FROM tbl'
6622
6623    Args:
6624        *expression: the SQL code string to parse as the FROM expressions of a
6625            SELECT statement. If an Expression instance is passed, this is used as-is.
6626        dialect: the dialect used to parse the input expression (in the case that the
6627            input expression is a SQL string).
6628        **opts: other options to use to parse the input expressions (again, in the case
6629            that the input expression is a SQL string).
6630
6631    Returns:
6632        Select: the syntax tree for the SELECT statement.
6633    """
6634    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:
6637def update(
6638    table: str | Table,
6639    properties: dict,
6640    where: t.Optional[ExpOrStr] = None,
6641    from_: t.Optional[ExpOrStr] = None,
6642    dialect: DialectType = None,
6643    **opts,
6644) -> Update:
6645    """
6646    Creates an update statement.
6647
6648    Example:
6649        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6650        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6651
6652    Args:
6653        *properties: dictionary of properties to set which are
6654            auto converted to sql objects eg None -> NULL
6655        where: sql conditional parsed into a WHERE statement
6656        from_: sql statement parsed into a FROM statement
6657        dialect: the dialect used to parse the input expressions.
6658        **opts: other options to use to parse the input expressions.
6659
6660    Returns:
6661        Update: the syntax tree for the UPDATE statement.
6662    """
6663    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6664    update_expr.set(
6665        "expressions",
6666        [
6667            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6668            for k, v in properties.items()
6669        ],
6670    )
6671    if from_:
6672        update_expr.set(
6673            "from",
6674            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6675        )
6676    if isinstance(where, Condition):
6677        where = Where(this=where)
6678    if where:
6679        update_expr.set(
6680            "where",
6681            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6682        )
6683    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:
6686def delete(
6687    table: ExpOrStr,
6688    where: t.Optional[ExpOrStr] = None,
6689    returning: t.Optional[ExpOrStr] = None,
6690    dialect: DialectType = None,
6691    **opts,
6692) -> Delete:
6693    """
6694    Builds a delete statement.
6695
6696    Example:
6697        >>> delete("my_table", where="id > 1").sql()
6698        'DELETE FROM my_table WHERE id > 1'
6699
6700    Args:
6701        where: sql conditional parsed into a WHERE statement
6702        returning: sql conditional parsed into a RETURNING statement
6703        dialect: the dialect used to parse the input expressions.
6704        **opts: other options to use to parse the input expressions.
6705
6706    Returns:
6707        Delete: the syntax tree for the DELETE statement.
6708    """
6709    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6710    if where:
6711        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6712    if returning:
6713        delete_expr = t.cast(
6714            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6715        )
6716    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:
6719def insert(
6720    expression: ExpOrStr,
6721    into: ExpOrStr,
6722    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6723    overwrite: t.Optional[bool] = None,
6724    returning: t.Optional[ExpOrStr] = None,
6725    dialect: DialectType = None,
6726    copy: bool = True,
6727    **opts,
6728) -> Insert:
6729    """
6730    Builds an INSERT statement.
6731
6732    Example:
6733        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6734        'INSERT INTO tbl VALUES (1, 2, 3)'
6735
6736    Args:
6737        expression: the sql string or expression of the INSERT statement
6738        into: the tbl to insert data to.
6739        columns: optionally the table's column names.
6740        overwrite: whether to INSERT OVERWRITE or not.
6741        returning: sql conditional parsed into a RETURNING statement
6742        dialect: the dialect used to parse the input expressions.
6743        copy: whether to copy the expression.
6744        **opts: other options to use to parse the input expressions.
6745
6746    Returns:
6747        Insert: the syntax tree for the INSERT statement.
6748    """
6749    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6750    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6751
6752    if columns:
6753        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6754
6755    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6756
6757    if returning:
6758        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6759
6760    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:
6763def condition(
6764    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6765) -> Condition:
6766    """
6767    Initialize a logical condition expression.
6768
6769    Example:
6770        >>> condition("x=1").sql()
6771        'x = 1'
6772
6773        This is helpful for composing larger logical syntax trees:
6774        >>> where = condition("x=1")
6775        >>> where = where.and_("y=1")
6776        >>> Select().from_("tbl").select("*").where(where).sql()
6777        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6778
6779    Args:
6780        *expression: the SQL code string to parse.
6781            If an Expression instance is passed, this is used as-is.
6782        dialect: the dialect used to parse the input expression (in the case that the
6783            input expression is a SQL string).
6784        copy: Whether to copy `expression` (only applies to expressions).
6785        **opts: other options to use to parse the input expressions (again, in the case
6786            that the input expression is a SQL string).
6787
6788    Returns:
6789        The new Condition instance
6790    """
6791    return maybe_parse(
6792        expression,
6793        into=Condition,
6794        dialect=dialect,
6795        copy=copy,
6796        **opts,
6797    )

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:
6800def and_(
6801    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6802) -> Condition:
6803    """
6804    Combine multiple conditions with an AND logical operator.
6805
6806    Example:
6807        >>> and_("x=1", and_("y=1", "z=1")).sql()
6808        'x = 1 AND (y = 1 AND z = 1)'
6809
6810    Args:
6811        *expressions: the SQL code strings to parse.
6812            If an Expression instance is passed, this is used as-is.
6813        dialect: the dialect used to parse the input expression.
6814        copy: whether to copy `expressions` (only applies to Expressions).
6815        **opts: other options to use to parse the input expressions.
6816
6817    Returns:
6818        The new condition
6819    """
6820    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:
6823def or_(
6824    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6825) -> Condition:
6826    """
6827    Combine multiple conditions with an OR logical operator.
6828
6829    Example:
6830        >>> or_("x=1", or_("y=1", "z=1")).sql()
6831        'x = 1 OR (y = 1 OR z = 1)'
6832
6833    Args:
6834        *expressions: the SQL code strings to parse.
6835            If an Expression instance is passed, this is used as-is.
6836        dialect: the dialect used to parse the input expression.
6837        copy: whether to copy `expressions` (only applies to Expressions).
6838        **opts: other options to use to parse the input expressions.
6839
6840    Returns:
6841        The new condition
6842    """
6843    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:
6846def xor(
6847    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6848) -> Condition:
6849    """
6850    Combine multiple conditions with an XOR logical operator.
6851
6852    Example:
6853        >>> xor("x=1", xor("y=1", "z=1")).sql()
6854        'x = 1 XOR (y = 1 XOR z = 1)'
6855
6856    Args:
6857        *expressions: the SQL code strings to parse.
6858            If an Expression instance is passed, this is used as-is.
6859        dialect: the dialect used to parse the input expression.
6860        copy: whether to copy `expressions` (only applies to Expressions).
6861        **opts: other options to use to parse the input expressions.
6862
6863    Returns:
6864        The new condition
6865    """
6866    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:
6869def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6870    """
6871    Wrap a condition with a NOT operator.
6872
6873    Example:
6874        >>> not_("this_suit='black'").sql()
6875        "NOT this_suit = 'black'"
6876
6877    Args:
6878        expression: the SQL code string to parse.
6879            If an Expression instance is passed, this is used as-is.
6880        dialect: the dialect used to parse the input expression.
6881        copy: whether to copy the expression or not.
6882        **opts: other options to use to parse the input expressions.
6883
6884    Returns:
6885        The new condition.
6886    """
6887    this = condition(
6888        expression,
6889        dialect=dialect,
6890        copy=copy,
6891        **opts,
6892    )
6893    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:
6896def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6897    """
6898    Wrap an expression in parentheses.
6899
6900    Example:
6901        >>> paren("5 + 3").sql()
6902        '(5 + 3)'
6903
6904    Args:
6905        expression: the SQL code string to parse.
6906            If an Expression instance is passed, this is used as-is.
6907        copy: whether to copy the expression or not.
6908
6909    Returns:
6910        The wrapped expression.
6911    """
6912    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):
6928def to_identifier(name, quoted=None, copy=True):
6929    """Builds an identifier.
6930
6931    Args:
6932        name: The name to turn into an identifier.
6933        quoted: Whether to force quote the identifier.
6934        copy: Whether to copy name if it's an Identifier.
6935
6936    Returns:
6937        The identifier ast node.
6938    """
6939
6940    if name is None:
6941        return None
6942
6943    if isinstance(name, Identifier):
6944        identifier = maybe_copy(name, copy)
6945    elif isinstance(name, str):
6946        identifier = Identifier(
6947            this=name,
6948            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6949        )
6950    else:
6951        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6952    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:
6955def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6956    """
6957    Parses a given string into an identifier.
6958
6959    Args:
6960        name: The name to parse into an identifier.
6961        dialect: The dialect to parse against.
6962
6963    Returns:
6964        The identifier ast node.
6965    """
6966    try:
6967        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6968    except (ParseError, TokenError):
6969        expression = to_identifier(name)
6970
6971    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:
6977def to_interval(interval: str | Literal) -> Interval:
6978    """Builds an interval expression from a string like '1 day' or '5 months'."""
6979    if isinstance(interval, Literal):
6980        if not interval.is_string:
6981            raise ValueError("Invalid interval string.")
6982
6983        interval = interval.this
6984
6985    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6986
6987    if not interval_parts:
6988        raise ValueError("Invalid interval string.")
6989
6990    return Interval(
6991        this=Literal.string(interval_parts.group(1)),
6992        unit=Var(this=interval_parts.group(2).upper()),
6993    )

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:
6996def to_table(
6997    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6998) -> Table:
6999    """
7000    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7001    If a table is passed in then that table is returned.
7002
7003    Args:
7004        sql_path: a `[catalog].[schema].[table]` string.
7005        dialect: the source dialect according to which the table name will be parsed.
7006        copy: Whether to copy a table if it is passed in.
7007        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7008
7009    Returns:
7010        A table expression.
7011    """
7012    if isinstance(sql_path, Table):
7013        return maybe_copy(sql_path, copy=copy)
7014
7015    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7016
7017    for k, v in kwargs.items():
7018        table.set(k, v)
7019
7020    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:
7023def to_column(
7024    sql_path: str | Column,
7025    quoted: t.Optional[bool] = None,
7026    dialect: DialectType = None,
7027    copy: bool = True,
7028    **kwargs,
7029) -> Column:
7030    """
7031    Create a column from a `[table].[column]` sql path. Table is optional.
7032    If a column is passed in then that column is returned.
7033
7034    Args:
7035        sql_path: a `[table].[column]` string.
7036        quoted: Whether or not to force quote identifiers.
7037        dialect: the source dialect according to which the column name will be parsed.
7038        copy: Whether to copy a column if it is passed in.
7039        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7040
7041    Returns:
7042        A column expression.
7043    """
7044    if isinstance(sql_path, Column):
7045        return maybe_copy(sql_path, copy=copy)
7046
7047    try:
7048        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7049    except ParseError:
7050        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7051
7052    for k, v in kwargs.items():
7053        col.set(k, v)
7054
7055    if quoted:
7056        for i in col.find_all(Identifier):
7057            i.set("quoted", True)
7058
7059    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):
7062def alias_(
7063    expression: ExpOrStr,
7064    alias: t.Optional[str | Identifier],
7065    table: bool | t.Sequence[str | Identifier] = False,
7066    quoted: t.Optional[bool] = None,
7067    dialect: DialectType = None,
7068    copy: bool = True,
7069    **opts,
7070):
7071    """Create an Alias expression.
7072
7073    Example:
7074        >>> alias_('foo', 'bar').sql()
7075        'foo AS bar'
7076
7077        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7078        '(SELECT 1, 2) AS bar(a, b)'
7079
7080    Args:
7081        expression: the SQL code strings to parse.
7082            If an Expression instance is passed, this is used as-is.
7083        alias: the alias name to use. If the name has
7084            special characters it is quoted.
7085        table: Whether to create a table alias, can also be a list of columns.
7086        quoted: whether to quote the alias
7087        dialect: the dialect used to parse the input expression.
7088        copy: Whether to copy the expression.
7089        **opts: other options to use to parse the input expressions.
7090
7091    Returns:
7092        Alias: the aliased expression
7093    """
7094    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7095    alias = to_identifier(alias, quoted=quoted)
7096
7097    if table:
7098        table_alias = TableAlias(this=alias)
7099        exp.set("alias", table_alias)
7100
7101        if not isinstance(table, bool):
7102            for column in table:
7103                table_alias.append("columns", to_identifier(column, quoted=quoted))
7104
7105        return exp
7106
7107    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7108    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7109    # for the complete Window expression.
7110    #
7111    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7112
7113    if "alias" in exp.arg_types and not isinstance(exp, Window):
7114        exp.set("alias", alias)
7115        return exp
7116    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:
7119def subquery(
7120    expression: ExpOrStr,
7121    alias: t.Optional[Identifier | str] = None,
7122    dialect: DialectType = None,
7123    **opts,
7124) -> Select:
7125    """
7126    Build a subquery expression that's selected from.
7127
7128    Example:
7129        >>> subquery('select x from tbl', 'bar').select('x').sql()
7130        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7131
7132    Args:
7133        expression: the SQL code strings to parse.
7134            If an Expression instance is passed, this is used as-is.
7135        alias: the alias name to use.
7136        dialect: the dialect used to parse the input expression.
7137        **opts: other options to use to parse the input expressions.
7138
7139    Returns:
7140        A new Select instance with the subquery expression included.
7141    """
7142
7143    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7144    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):
7175def column(
7176    col,
7177    table=None,
7178    db=None,
7179    catalog=None,
7180    *,
7181    fields=None,
7182    quoted=None,
7183    copy=True,
7184):
7185    """
7186    Build a Column.
7187
7188    Args:
7189        col: Column name.
7190        table: Table name.
7191        db: Database name.
7192        catalog: Catalog name.
7193        fields: Additional fields using dots.
7194        quoted: Whether to force quotes on the column's identifiers.
7195        copy: Whether to copy identifiers if passed in.
7196
7197    Returns:
7198        The new Column instance.
7199    """
7200    this = Column(
7201        this=to_identifier(col, quoted=quoted, copy=copy),
7202        table=to_identifier(table, quoted=quoted, copy=copy),
7203        db=to_identifier(db, quoted=quoted, copy=copy),
7204        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7205    )
7206
7207    if fields:
7208        this = Dot.build(
7209            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7210        )
7211    return this

Build a Column.

Arguments:
  • col: Column name.
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • fields: Additional fields using dots.
  • quoted: Whether to force quotes on the column's identifiers.
  • copy: Whether to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, **opts) -> Cast:
7214def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7215    """Cast an expression to a data type.
7216
7217    Example:
7218        >>> cast('x + 1', 'int').sql()
7219        'CAST(x + 1 AS INT)'
7220
7221    Args:
7222        expression: The expression to cast.
7223        to: The datatype to cast to.
7224        copy: Whether to copy the supplied expressions.
7225
7226    Returns:
7227        The new Cast instance.
7228    """
7229    expr = maybe_parse(expression, copy=copy, **opts)
7230    data_type = DataType.build(to, copy=copy, **opts)
7231
7232    if expr.is_type(data_type):
7233        return expr
7234
7235    expr = Cast(this=expr, to=data_type)
7236    expr.type = data_type
7237
7238    return expr

Cast an expression to a data type.

Example:
>>> cast('x + 1', 'int').sql()
'CAST(x + 1 AS INT)'
Arguments:
  • expression: The expression to cast.
  • to: The datatype to cast to.
  • copy: Whether to copy the supplied expressions.
Returns:

The new Cast instance.

def table_( table: Identifier | str, db: Union[Identifier, str, NoneType] = None, catalog: Union[Identifier, str, NoneType] = None, quoted: Optional[bool] = None, alias: Union[Identifier, str, NoneType] = None) -> Table:
7241def table_(
7242    table: Identifier | str,
7243    db: t.Optional[Identifier | str] = None,
7244    catalog: t.Optional[Identifier | str] = None,
7245    quoted: t.Optional[bool] = None,
7246    alias: t.Optional[Identifier | str] = None,
7247) -> Table:
7248    """Build a Table.
7249
7250    Args:
7251        table: Table name.
7252        db: Database name.
7253        catalog: Catalog name.
7254        quote: Whether to force quotes on the table's identifiers.
7255        alias: Table's alias.
7256
7257    Returns:
7258        The new Table instance.
7259    """
7260    return Table(
7261        this=to_identifier(table, quoted=quoted) if table else None,
7262        db=to_identifier(db, quoted=quoted) if db else None,
7263        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7264        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7265    )

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:
7268def values(
7269    values: t.Iterable[t.Tuple[t.Any, ...]],
7270    alias: t.Optional[str] = None,
7271    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7272) -> Values:
7273    """Build VALUES statement.
7274
7275    Example:
7276        >>> values([(1, '2')]).sql()
7277        "VALUES (1, '2')"
7278
7279    Args:
7280        values: values statements that will be converted to SQL
7281        alias: optional alias
7282        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7283         If either are provided then an alias is also required.
7284
7285    Returns:
7286        Values: the Values expression object
7287    """
7288    if columns and not alias:
7289        raise ValueError("Alias is required when providing columns")
7290
7291    return Values(
7292        expressions=[convert(tup) for tup in values],
7293        alias=(
7294            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7295            if columns
7296            else (TableAlias(this=to_identifier(alias)) if alias else None)
7297        ),
7298    )

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:
7301def var(name: t.Optional[ExpOrStr]) -> Var:
7302    """Build a SQL variable.
7303
7304    Example:
7305        >>> repr(var('x'))
7306        'Var(this=x)'
7307
7308        >>> repr(var(column('x', table='y')))
7309        'Var(this=x)'
7310
7311    Args:
7312        name: The name of the var or an expression who's name will become the var.
7313
7314    Returns:
7315        The new variable node.
7316    """
7317    if not name:
7318        raise ValueError("Cannot convert empty name into var.")
7319
7320    if isinstance(name, Expression):
7321        name = name.name
7322    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:
7325def rename_table(
7326    old_name: str | Table,
7327    new_name: str | Table,
7328    dialect: DialectType = None,
7329) -> Alter:
7330    """Build ALTER TABLE... RENAME... expression
7331
7332    Args:
7333        old_name: The old name of the table
7334        new_name: The new name of the table
7335        dialect: The dialect to parse the table.
7336
7337    Returns:
7338        Alter table expression
7339    """
7340    old_table = to_table(old_name, dialect=dialect)
7341    new_table = to_table(new_name, dialect=dialect)
7342    return Alter(
7343        this=old_table,
7344        kind="TABLE",
7345        actions=[
7346            RenameTable(this=new_table),
7347        ],
7348    )

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:
7351def rename_column(
7352    table_name: str | Table,
7353    old_column_name: str | Column,
7354    new_column_name: str | Column,
7355    exists: t.Optional[bool] = None,
7356    dialect: DialectType = None,
7357) -> Alter:
7358    """Build ALTER TABLE... RENAME COLUMN... expression
7359
7360    Args:
7361        table_name: Name of the table
7362        old_column: The old name of the column
7363        new_column: The new name of the column
7364        exists: Whether to add the `IF EXISTS` clause
7365        dialect: The dialect to parse the table/column.
7366
7367    Returns:
7368        Alter table expression
7369    """
7370    table = to_table(table_name, dialect=dialect)
7371    old_column = to_column(old_column_name, dialect=dialect)
7372    new_column = to_column(new_column_name, dialect=dialect)
7373    return Alter(
7374        this=table,
7375        kind="TABLE",
7376        actions=[
7377            RenameColumn(this=old_column, to=new_column, exists=exists),
7378        ],
7379    )

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:
7382def convert(value: t.Any, copy: bool = False) -> Expression:
7383    """Convert a python value into an expression object.
7384
7385    Raises an error if a conversion is not possible.
7386
7387    Args:
7388        value: A python object.
7389        copy: Whether to copy `value` (only applies to Expressions and collections).
7390
7391    Returns:
7392        The equivalent expression object.
7393    """
7394    if isinstance(value, Expression):
7395        return maybe_copy(value, copy)
7396    if isinstance(value, str):
7397        return Literal.string(value)
7398    if isinstance(value, bool):
7399        return Boolean(this=value)
7400    if value is None or (isinstance(value, float) and math.isnan(value)):
7401        return null()
7402    if isinstance(value, numbers.Number):
7403        return Literal.number(value)
7404    if isinstance(value, bytes):
7405        return HexString(this=value.hex())
7406    if isinstance(value, datetime.datetime):
7407        datetime_literal = Literal.string(
7408            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7409                sep=" "
7410            )
7411        )
7412        return TimeStrToTime(this=datetime_literal)
7413    if isinstance(value, datetime.date):
7414        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7415        return DateStrToDate(this=date_literal)
7416    if isinstance(value, tuple):
7417        if hasattr(value, "_fields"):
7418            return Struct(
7419                expressions=[
7420                    PropertyEQ(
7421                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7422                    )
7423                    for k in value._fields
7424                ]
7425            )
7426        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7427    if isinstance(value, list):
7428        return Array(expressions=[convert(v, copy=copy) for v in value])
7429    if isinstance(value, dict):
7430        return Map(
7431            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7432            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7433        )
7434    if hasattr(value, "__dict__"):
7435        return Struct(
7436            expressions=[
7437                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7438                for k, v in value.__dict__.items()
7439            ]
7440        )
7441    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:
7444def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7445    """
7446    Replace children of an expression with the result of a lambda fun(child) -> exp.
7447    """
7448    for k, v in tuple(expression.args.items()):
7449        is_list_arg = type(v) is list
7450
7451        child_nodes = v if is_list_arg else [v]
7452        new_child_nodes = []
7453
7454        for cn in child_nodes:
7455            if isinstance(cn, Expression):
7456                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7457                    new_child_nodes.append(child_node)
7458            else:
7459                new_child_nodes.append(cn)
7460
7461        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:
7464def replace_tree(
7465    expression: Expression,
7466    fun: t.Callable,
7467    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7468) -> Expression:
7469    """
7470    Replace an entire tree with the result of function calls on each node.
7471
7472    This will be traversed in reverse dfs, so leaves first.
7473    If new nodes are created as a result of function calls, they will also be traversed.
7474    """
7475    stack = list(expression.dfs(prune=prune))
7476
7477    while stack:
7478        node = stack.pop()
7479        new_node = fun(node)
7480
7481        if new_node is not node:
7482            node.replace(new_node)
7483
7484            if isinstance(new_node, Expression):
7485                stack.append(new_node)
7486
7487    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]:
7490def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7491    """
7492    Return all table names referenced through columns in an expression.
7493
7494    Example:
7495        >>> import sqlglot
7496        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7497        ['a', 'c']
7498
7499    Args:
7500        expression: expression to find table names.
7501        exclude: a table name to exclude
7502
7503    Returns:
7504        A list of unique names.
7505    """
7506    return {
7507        table
7508        for table in (column.table for column in expression.find_all(Column))
7509        if table and table != exclude
7510    }

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:
7513def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7514    """Get the full name of a table as a string.
7515
7516    Args:
7517        table: Table expression node or string.
7518        dialect: The dialect to generate the table name for.
7519        identify: Determines when an identifier should be quoted. Possible values are:
7520            False (default): Never quote, except in cases where it's mandatory by the dialect.
7521            True: Always quote.
7522
7523    Examples:
7524        >>> from sqlglot import exp, parse_one
7525        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7526        'a.b.c'
7527
7528    Returns:
7529        The table name.
7530    """
7531
7532    table = maybe_parse(table, into=Table, dialect=dialect)
7533
7534    if not table:
7535        raise ValueError(f"Cannot parse {table}")
7536
7537    return ".".join(
7538        (
7539            part.sql(dialect=dialect, identify=True, copy=False)
7540            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7541            else part.name
7542        )
7543        for part in table.parts
7544    )

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:
7547def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7548    """Returns a case normalized table name without quotes.
7549
7550    Args:
7551        table: the table to normalize
7552        dialect: the dialect to use for normalization rules
7553        copy: whether to copy the expression.
7554
7555    Examples:
7556        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7557        'A-B.c'
7558    """
7559    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7560
7561    return ".".join(
7562        p.name
7563        for p in normalize_identifiers(
7564            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7565        ).parts
7566    )

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:
7569def replace_tables(
7570    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7571) -> E:
7572    """Replace all tables in expression according to the mapping.
7573
7574    Args:
7575        expression: expression node to be transformed and replaced.
7576        mapping: mapping of table names.
7577        dialect: the dialect of the mapping table
7578        copy: whether to copy the expression.
7579
7580    Examples:
7581        >>> from sqlglot import exp, parse_one
7582        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7583        'SELECT * FROM c /* a.b */'
7584
7585    Returns:
7586        The mapped expression.
7587    """
7588
7589    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7590
7591    def _replace_tables(node: Expression) -> Expression:
7592        if isinstance(node, Table):
7593            original = normalize_table_name(node, dialect=dialect)
7594            new_name = mapping.get(original)
7595
7596            if new_name:
7597                table = to_table(
7598                    new_name,
7599                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7600                    dialect=dialect,
7601                )
7602                table.add_comments([original])
7603                return table
7604        return node
7605
7606    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:
7609def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7610    """Replace placeholders in an expression.
7611
7612    Args:
7613        expression: expression node to be transformed and replaced.
7614        args: positional names that will substitute unnamed placeholders in the given order.
7615        kwargs: keyword arguments that will substitute named placeholders.
7616
7617    Examples:
7618        >>> from sqlglot import exp, parse_one
7619        >>> replace_placeholders(
7620        ...     parse_one("select * from :tbl where ? = ?"),
7621        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7622        ... ).sql()
7623        "SELECT * FROM foo WHERE str_col = 'b'"
7624
7625    Returns:
7626        The mapped expression.
7627    """
7628
7629    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7630        if isinstance(node, Placeholder):
7631            if node.this:
7632                new_name = kwargs.get(node.this)
7633                if new_name is not None:
7634                    return convert(new_name)
7635            else:
7636                try:
7637                    return convert(next(args))
7638                except StopIteration:
7639                    pass
7640        return node
7641
7642    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:
7645def expand(
7646    expression: Expression,
7647    sources: t.Dict[str, Query],
7648    dialect: DialectType = None,
7649    copy: bool = True,
7650) -> Expression:
7651    """Transforms an expression by expanding all referenced sources into subqueries.
7652
7653    Examples:
7654        >>> from sqlglot import parse_one
7655        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7656        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7657
7658        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7659        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7660
7661    Args:
7662        expression: The expression to expand.
7663        sources: A dictionary of name to Queries.
7664        dialect: The dialect of the sources dict.
7665        copy: Whether to copy the expression during transformation. Defaults to True.
7666
7667    Returns:
7668        The transformed expression.
7669    """
7670    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7671
7672    def _expand(node: Expression):
7673        if isinstance(node, Table):
7674            name = normalize_table_name(node, dialect=dialect)
7675            source = sources.get(name)
7676            if source:
7677                subquery = source.subquery(node.alias or name)
7678                subquery.comments = [f"source: {name}"]
7679                return subquery.transform(_expand, copy=False)
7680        return node
7681
7682    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:
7685def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7686    """
7687    Returns a Func expression.
7688
7689    Examples:
7690        >>> func("abs", 5).sql()
7691        'ABS(5)'
7692
7693        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7694        'CAST(5 AS DOUBLE)'
7695
7696    Args:
7697        name: the name of the function to build.
7698        args: the args used to instantiate the function of interest.
7699        copy: whether to copy the argument expressions.
7700        dialect: the source dialect.
7701        kwargs: the kwargs used to instantiate the function of interest.
7702
7703    Note:
7704        The arguments `args` and `kwargs` are mutually exclusive.
7705
7706    Returns:
7707        An instance of the function of interest, or an anonymous function, if `name` doesn't
7708        correspond to an existing `sqlglot.expressions.Func` class.
7709    """
7710    if args and kwargs:
7711        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7712
7713    from sqlglot.dialects.dialect import Dialect
7714
7715    dialect = Dialect.get_or_raise(dialect)
7716
7717    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7718    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7719
7720    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7721    if constructor:
7722        if converted:
7723            if "dialect" in constructor.__code__.co_varnames:
7724                function = constructor(converted, dialect=dialect)
7725            else:
7726                function = constructor(converted)
7727        elif constructor.__name__ == "from_arg_list":
7728            function = constructor.__self__(**kwargs)  # type: ignore
7729        else:
7730            constructor = FUNCTION_BY_NAME.get(name.upper())
7731            if constructor:
7732                function = constructor(**kwargs)
7733            else:
7734                raise ValueError(
7735                    f"Unable to convert '{name}' into a Func. Either manually construct "
7736                    "the Func expression of interest or parse the function call."
7737                )
7738    else:
7739        kwargs = kwargs or {"expressions": converted}
7740        function = Anonymous(this=name, **kwargs)
7741
7742    for error_message in function.error_messages(converted):
7743        raise ValueError(error_message)
7744
7745    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:
7748def case(
7749    expression: t.Optional[ExpOrStr] = None,
7750    **opts,
7751) -> Case:
7752    """
7753    Initialize a CASE statement.
7754
7755    Example:
7756        case().when("a = 1", "foo").else_("bar")
7757
7758    Args:
7759        expression: Optionally, the input expression (not all dialects support this)
7760        **opts: Extra keyword arguments for parsing `expression`
7761    """
7762    if expression is not None:
7763        this = maybe_parse(expression, **opts)
7764    else:
7765        this = None
7766    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:
7769def array(
7770    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7771) -> Array:
7772    """
7773    Returns an array.
7774
7775    Examples:
7776        >>> array(1, 'x').sql()
7777        'ARRAY(1, x)'
7778
7779    Args:
7780        expressions: the expressions to add to the array.
7781        copy: whether to copy the argument expressions.
7782        dialect: the source dialect.
7783        kwargs: the kwargs used to instantiate the function of interest.
7784
7785    Returns:
7786        An array expression.
7787    """
7788    return Array(
7789        expressions=[
7790            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7791            for expression in expressions
7792        ]
7793    )

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:
7796def tuple_(
7797    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7798) -> Tuple:
7799    """
7800    Returns an tuple.
7801
7802    Examples:
7803        >>> tuple_(1, 'x').sql()
7804        '(1, x)'
7805
7806    Args:
7807        expressions: the expressions to add to the tuple.
7808        copy: whether to copy the argument expressions.
7809        dialect: the source dialect.
7810        kwargs: the kwargs used to instantiate the function of interest.
7811
7812    Returns:
7813        A tuple expression.
7814    """
7815    return Tuple(
7816        expressions=[
7817            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7818            for expression in expressions
7819        ]
7820    )

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:
7823def true() -> Boolean:
7824    """
7825    Returns a true Boolean expression.
7826    """
7827    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7830def false() -> Boolean:
7831    """
7832    Returns a false Boolean expression.
7833    """
7834    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7837def null() -> Null:
7838    """
7839    Returns a Null expression.
7840    """
7841    return Null()

Returns a Null expression.

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