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

The base class for all expressions in a syntax tree. Each Expression encapsulates any necessary context, such as its child expressions, their names (arg keys), and whether a given child expression is optional or not.

Attributes:
  • key: a unique key for each class in the Expression hierarchy. This is useful for hashing and representing expressions as strings.
  • arg_types: determines the arguments (child nodes) supported by an expression. It maps arg keys to booleans that indicate whether the corresponding args are optional.
  • parent: a reference to the parent expression (or None, in case of root expressions).
  • arg_key: the arg key an expression is associated with, i.e. the name its parent expression uses to refer to it.
  • index: the index of an expression if it is inside of a list argument in its parent.
  • comments: a list of comments that are associated with a given expression. This is used in order to preserve comments when transpiling SQL code.
  • type: the DataType type of an expression. This is inferred by the optimizer, in order to enable some transformations that require type information.
  • meta: a dictionary that can be used to store useful metadata for a given expression.
Example:
>>> class Foo(Expression):
...     arg_types = {"this": True, "expression": False}

The above definition informs us that Foo is an Expression that requires an argument called "this" and may also optionally receive an argument called "expression".

Arguments:
  • args: a mapping used for retrieving the arguments of an expression, given their arg keys.
Expression(**args: Any)
102    def __init__(self, **args: t.Any):
103        self.args: t.Dict[str, t.Any] = args
104        self.parent: t.Optional[Expression] = None
105        self.arg_key: t.Optional[str] = None
106        self.index: t.Optional[int] = None
107        self.comments: t.Optional[t.List[str]] = None
108        self._type: t.Optional[DataType] = None
109        self._meta: t.Optional[t.Dict[str, t.Any]] = None
110        self._hash: t.Optional[int] = None
111
112        for arg_key, value in self.args.items():
113            self._set_parent(arg_key, value)
key = 'expression'
arg_types = {'this': True}
args: Dict[str, Any]
parent: Optional[Expression]
arg_key: Optional[str]
index: Optional[int]
comments: Optional[List[str]]
hashable_args: Any
118    @property
119    def hashable_args(self) -> t.Any:
120        return frozenset(
121            (k, tuple(_norm_arg(a) for a in v) if type(v) is list else _norm_arg(v))
122            for k, v in self.args.items()
123            if not (v is None or v is False or (type(v) is list and not v))
124        )
this: Any
132    @property
133    def this(self) -> t.Any:
134        """
135        Retrieves the argument with key "this".
136        """
137        return self.args.get("this")

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

def text(self, key) -> str:
153    def text(self, key) -> str:
154        """
155        Returns a textual representation of the argument corresponding to "key". This can only be used
156        for args that are strings or leaf Expression instances, such as identifiers and literals.
157        """
158        field = self.args.get(key)
159        if isinstance(field, str):
160            return field
161        if isinstance(field, (Identifier, Literal, Var)):
162            return field.this
163        if isinstance(field, (Star, Null)):
164            return field.name
165        return ""

Returns a textual representation of the argument corresponding to "key". This can only be used for args that are strings or leaf Expression instances, such as identifiers and literals.

is_string: bool
167    @property
168    def is_string(self) -> bool:
169        """
170        Checks whether a Literal expression is a string.
171        """
172        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is an integer.

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

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
210    @property
211    def alias_column_names(self) -> t.List[str]:
212        table_alias = self.args.get("alias")
213        if not table_alias:
214            return []
215        return [c.name for c in table_alias.args.get("columns") or []]
name: str
217    @property
218    def name(self) -> str:
219        return self.text("this")
alias_or_name: str
221    @property
222    def alias_or_name(self) -> str:
223        return self.alias or self.name
output_name: str
225    @property
226    def output_name(self) -> str:
227        """
228        Name of the output column if this expression is a selection.
229
230        If the Expression has no output name, an empty string is returned.
231
232        Example:
233            >>> from sqlglot import parse_one
234            >>> parse_one("SELECT a").expressions[0].output_name
235            'a'
236            >>> parse_one("SELECT b AS c").expressions[0].output_name
237            'c'
238            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
239            ''
240        """
241        return ""

Name of the output column if this expression is a selection.

If the Expression has no output name, an empty string is returned.

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
type: Optional[DataType]
243    @property
244    def type(self) -> t.Optional[DataType]:
245        return self._type
def is_type(self, *dtypes) -> bool:
253    def is_type(self, *dtypes) -> bool:
254        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
256    def is_leaf(self) -> bool:
257        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
259    @property
260    def meta(self) -> t.Dict[str, t.Any]:
261        if self._meta is None:
262            self._meta = {}
263        return self._meta
def copy(self):
299    def copy(self):
300        """
301        Returns a deep copy of the expression.
302        """
303        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments(self, comments: Optional[List[str]] = None) -> None:
305    def add_comments(self, comments: t.Optional[t.List[str]] = None) -> None:
306        if self.comments is None:
307            self.comments = []
308
309        if comments:
310            for comment in comments:
311                _, *meta = comment.split(SQLGLOT_META)
312                if meta:
313                    for kv in "".join(meta).split(","):
314                        k, *v = kv.split("=")
315                        value = v[0].strip() if v else True
316                        self.meta[k.strip()] = value
317                self.comments.append(comment)
def pop_comments(self) -> List[str]:
319    def pop_comments(self) -> t.List[str]:
320        comments = self.comments or []
321        self.comments = None
322        return comments
def append(self, arg_key: str, value: Any) -> None:
324    def append(self, arg_key: str, value: t.Any) -> None:
325        """
326        Appends value to arg_key if it's a list or sets it as a new list.
327
328        Args:
329            arg_key (str): name of the list expression arg
330            value (Any): value to append to the list
331        """
332        if type(self.args.get(arg_key)) is not list:
333            self.args[arg_key] = []
334        self._set_parent(arg_key, value)
335        values = self.args[arg_key]
336        if hasattr(value, "parent"):
337            value.index = len(values)
338        values.append(value)

Appends value to arg_key if it's a list or sets it as a new list.

Arguments:
  • arg_key (str): name of the list expression arg
  • value (Any): value to append to the list
def set(self, arg_key: str, value: Any, index: Optional[int] = None) -> None:
340    def set(self, arg_key: str, value: t.Any, index: t.Optional[int] = None) -> None:
341        """
342        Sets arg_key to value.
343
344        Args:
345            arg_key: name of the expression arg.
346            value: value to set the arg to.
347            index: if the arg is a list, this specifies what position to add the value in it.
348        """
349        if index is not None:
350            expressions = self.args.get(arg_key) or []
351
352            if seq_get(expressions, index) is None:
353                return
354            if value is None:
355                expressions.pop(index)
356                for v in expressions[index:]:
357                    v.index = v.index - 1
358                return
359
360            if isinstance(value, list):
361                expressions.pop(index)
362                expressions[index:index] = value
363            else:
364                expressions[index] = value
365
366            value = expressions
367        elif value is None:
368            self.args.pop(arg_key, None)
369            return
370
371        self.args[arg_key] = value
372        self._set_parent(arg_key, value, index)

Sets arg_key to value.

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

Returns the depth of this tree.

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

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

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
407    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
408        """
409        Returns the first node in this tree which matches at least one of
410        the specified types.
411
412        Args:
413            expression_types: the expression type(s) to match.
414            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
415
416        Returns:
417            The node which matches the criteria or None if no such node was found.
418        """
419        return next(self.find_all(*expression_types, bfs=bfs), None)

Returns the first node in this tree which matches at least one of the specified types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The node which matches the criteria or None if no such node was found.

def find_all(self, *expression_types: Type[~E], bfs: bool = True) -> Iterator[~E]:
421    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
422        """
423        Returns a generator object which visits all nodes in this tree and only
424        yields those that match at least one of the specified expression types.
425
426        Args:
427            expression_types: the expression type(s) to match.
428            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
429
430        Returns:
431            The generator object.
432        """
433        for expression in self.walk(bfs=bfs):
434            if isinstance(expression, expression_types):
435                yield expression

Returns a generator object which visits all nodes in this tree and only yields those that match at least one of the specified expression types.

Arguments:
  • expression_types: the expression type(s) to match.
  • bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
Returns:

The generator object.

def find_ancestor(self, *expression_types: Type[~E]) -> Optional[~E]:
437    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
438        """
439        Returns a nearest parent matching expression_types.
440
441        Args:
442            expression_types: the expression type(s) to match.
443
444        Returns:
445            The parent node.
446        """
447        ancestor = self.parent
448        while ancestor and not isinstance(ancestor, expression_types):
449            ancestor = ancestor.parent
450        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

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

The parent node.

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

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

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

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

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

the generator object.

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

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

Returns:

The generator object.

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

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

Returns:

The generator object.

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

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
562    def flatten(self, unnest=True):
563        """
564        Returns a generator which yields child nodes whose parents are the same class.
565
566        A AND B AND C -> [A, B, C]
567        """
568        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
569            if type(node) is not self.__class__:
570                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

Returns a generator which yields child nodes whose parents are the same class.

A AND B AND C -> [A, B, C]

def to_s(self) -> str:
578    def to_s(self) -> str:
579        """
580        Same as __repr__, but includes additional information which can be useful
581        for debugging, like empty or missing args and the AST nodes' object IDs.
582        """
583        return _to_s(self, verbose=True)

Same as __repr__, but includes additional information which can be useful for debugging, like empty or missing args and the AST nodes' object IDs.

def sql( self, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> str:
585    def sql(self, dialect: DialectType = None, **opts) -> str:
586        """
587        Returns SQL string representation of this tree.
588
589        Args:
590            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
591            opts: other `sqlglot.generator.Generator` options.
592
593        Returns:
594            The SQL string.
595        """
596        from sqlglot.dialects import Dialect
597
598        return Dialect.get_or_raise(dialect).generate(self, **opts)

Returns SQL string representation of this tree.

Arguments:
  • dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
  • opts: other sqlglot.generator.Generator options.
Returns:

The SQL string.

def transform( self, fun: Callable, *args: Any, copy: bool = True, **kwargs) -> Expression:
600    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
601        """
602        Visits all tree nodes (excluding already transformed ones)
603        and applies the given transformation function to each node.
604
605        Args:
606            fun: a function which takes a node as an argument and returns a
607                new transformed node or the same node without modifications. If the function
608                returns None, then the corresponding node will be removed from the syntax tree.
609            copy: if set to True a new tree instance is constructed, otherwise the tree is
610                modified in place.
611
612        Returns:
613            The transformed tree.
614        """
615        root = None
616        new_node = None
617
618        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
619            parent, arg_key, index = node.parent, node.arg_key, node.index
620            new_node = fun(node, *args, **kwargs)
621
622            if not root:
623                root = new_node
624            elif new_node is not node:
625                parent.set(arg_key, new_node, index)
626
627        assert root
628        return root.assert_is(Expression)

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

Arguments:
  • fun: a function which takes a node as an argument and returns a new transformed node or the same node without modifications. If the function returns None, then the corresponding node will be removed from the syntax tree.
  • copy: if set to True a new tree instance is constructed, otherwise the tree is modified in place.
Returns:

The transformed tree.

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

Swap out this expression with a new expression.

For example::

>>> tree = Select()select("x")from_("tbl")
>>> tree.find(Column).replace(column("y"))
Column(
  this=Identifier(this=y, quoted=False))
>>> tree.sql()
'SELECT y FROM tbl'
Arguments:
  • expression: new node
Returns:

The new expression or expressions.

def pop(self: ~E) -> ~E:
677    def pop(self: E) -> E:
678        """
679        Remove this expression from its AST.
680
681        Returns:
682            The popped expression.
683        """
684        self.replace(None)
685        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
687    def assert_is(self, type_: t.Type[E]) -> E:
688        """
689        Assert that this `Expression` is an instance of `type_`.
690
691        If it is NOT an instance of `type_`, this raises an assertion error.
692        Otherwise, this returns this expression.
693
694        Examples:
695            This is useful for type security in chained expressions:
696
697            >>> import sqlglot
698            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
699            'SELECT x, z FROM y'
700        """
701        if not isinstance(self, type_):
702            raise AssertionError(f"{self} is not {type_}.")
703        return self

Assert that this Expression is an instance of type_.

If it is NOT an instance of type_, this raises an assertion error. Otherwise, this returns this expression.

Examples:

This is useful for type security in chained expressions:

>>> import sqlglot
>>> sqlglot.parse_one("SELECT x from y").assert_is(Select)select("z").sql()
'SELECT x, z FROM y'
def error_messages(self, args: Optional[Sequence] = None) -> List[str]:
705    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
706        """
707        Checks if this expression is valid (e.g. all mandatory args are set).
708
709        Args:
710            args: a sequence of values that were used to instantiate a Func expression. This is used
711                to check that the provided arguments don't exceed the function argument limit.
712
713        Returns:
714            A list of error messages for all possible errors that were found.
715        """
716        errors: t.List[str] = []
717
718        for k in self.args:
719            if k not in self.arg_types:
720                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
721        for k, mandatory in self.arg_types.items():
722            v = self.args.get(k)
723            if mandatory and (v is None or (isinstance(v, list) and not v)):
724                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
725
726        if (
727            args
728            and isinstance(self, Func)
729            and len(args) > len(self.arg_types)
730            and not self.is_var_len_args
731        ):
732            errors.append(
733                f"The number of provided arguments ({len(args)}) is greater than "
734                f"the maximum number of supported arguments ({len(self.arg_types)})"
735            )
736
737        return errors

Checks if this expression is valid (e.g. all mandatory args are set).

Arguments:
  • args: a sequence of values that were used to instantiate a Func expression. This is used to check that the provided arguments don't exceed the function argument limit.
Returns:

A list of error messages for all possible errors that were found.

def dump(self):
739    def dump(self):
740        """
741        Dump this Expression to a JSON-serializable dict.
742        """
743        from sqlglot.serde import dump
744
745        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
747    @classmethod
748    def load(cls, obj):
749        """
750        Load a dict (as returned by `Expression.dump`) into an Expression instance.
751        """
752        from sqlglot.serde import load
753
754        return load(obj)

Load a dict (as returned by Expression.dump) into an Expression instance.

def and_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
756    def and_(
757        self,
758        *expressions: t.Optional[ExpOrStr],
759        dialect: DialectType = None,
760        copy: bool = True,
761        **opts,
762    ) -> Condition:
763        """
764        AND this condition with one or multiple expressions.
765
766        Example:
767            >>> condition("x=1").and_("y=1").sql()
768            'x = 1 AND y = 1'
769
770        Args:
771            *expressions: the SQL code strings to parse.
772                If an `Expression` instance is passed, it will be used as-is.
773            dialect: the dialect used to parse the input expression.
774            copy: whether to copy the involved expressions (only applies to Expressions).
775            opts: other options to use to parse the input expressions.
776
777        Returns:
778            The new And condition.
779        """
780        return and_(self, *expressions, dialect=dialect, copy=copy, **opts)

AND this condition with one or multiple expressions.

Example:
>>> condition("x=1")and_("y=1").sql()
'x = 1 AND y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new And condition.

def or_( self, *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
782    def or_(
783        self,
784        *expressions: t.Optional[ExpOrStr],
785        dialect: DialectType = None,
786        copy: bool = True,
787        **opts,
788    ) -> Condition:
789        """
790        OR this condition with one or multiple expressions.
791
792        Example:
793            >>> condition("x=1").or_("y=1").sql()
794            'x = 1 OR y = 1'
795
796        Args:
797            *expressions: the SQL code strings to parse.
798                If an `Expression` instance is passed, it will be used as-is.
799            dialect: the dialect used to parse the input expression.
800            copy: whether to copy the involved expressions (only applies to Expressions).
801            opts: other options to use to parse the input expressions.
802
803        Returns:
804            The new Or condition.
805        """
806        return or_(self, *expressions, dialect=dialect, copy=copy, **opts)

OR this condition with one or multiple expressions.

Example:
>>> condition("x=1")or_("y=1").sql()
'x = 1 OR y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the involved expressions (only applies to Expressions).
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

def not_(self, copy: bool = True):
808    def not_(self, copy: bool = True):
809        """
810        Wrap this condition with NOT.
811
812        Example:
813            >>> condition("x=1").not_().sql()
814            'NOT x = 1'
815
816        Args:
817            copy: whether to copy this object.
818
819        Returns:
820            The new Not instance.
821        """
822        return not_(self, copy=copy)

Wrap this condition with NOT.

Example:
>>> condition("x=1")not_().sql()
'NOT x = 1'
Arguments:
  • copy: whether to copy this object.
Returns:

The new Not instance.

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

Logical conditions like x AND y, or simply x

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

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

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

Returns a Subquery that wraps around this query.

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

Adds a LIMIT clause to this query.

Example:
>>> select("1")union(select("1")).limit(1).sql()
'SELECT 1 UNION SELECT 1 LIMIT 1'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Limit instance is passed, it will be used as-is. If another Expression instance is passed, it will be wrapped in a Limit.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

A limited Select expression.

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

Set the OFFSET expression.

Example:
>>> Select()from_("tbl")select("x").offset(10).sql()
'SELECT x FROM tbl OFFSET 10'
Arguments:
  • expression: the SQL code string to parse. This can also be an integer. If a Offset instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Offset.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

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

Set the ORDER BY expression.

Example:
>>> Select()from_("tbl")select("x").order_by("x DESC").sql()
'SELECT x FROM tbl ORDER BY x DESC'
Arguments:
  • *expressions: the SQL code strings to parse. If a Group instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Order.
  • append: if True, add to any existing expressions. Otherwise, this flattens all the Order expression into a single expression.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

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

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

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

Returns the query's projections.

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

Returns the output names of the query's projections.

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

Append to or set the SELECT expressions.

Example:
>>> Select()select("x", "y").sql()
'SELECT x, y'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Query expression.

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

Append to or set the common table expressions.

Example:
>>> Select().with_("tbl2", as_="SELECT * FROM tbl")select("x")from_("tbl2").sql()
'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
Arguments:
  • alias: the SQL code string to parse as the table name. If an Expression instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expression instance is passed, it will be used as-is.
  • recursive: set the RECURSIVE part of the expression. Defaults to False.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

def union( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Union:
1230    def union(
1231        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1232    ) -> Union:
1233        """
1234        Builds a UNION expression.
1235
1236        Example:
1237            >>> import sqlglot
1238            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1239            'SELECT * FROM foo UNION SELECT * FROM bla'
1240
1241        Args:
1242            expression: the SQL code string.
1243                If an `Expression` instance is passed, it will be used as-is.
1244            distinct: set the DISTINCT flag if and only if this is true.
1245            dialect: the dialect used to parse the input expression.
1246            opts: other options to use to parse the input expressions.
1247
1248        Returns:
1249            The new Union expression.
1250        """
1251        return union(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds a UNION expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo")union("SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expression: the SQL code string. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union expression.

def intersect( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Intersect:
1253    def intersect(
1254        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1255    ) -> Intersect:
1256        """
1257        Builds an INTERSECT expression.
1258
1259        Example:
1260            >>> import sqlglot
1261            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1262            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1263
1264        Args:
1265            expression: the SQL code string.
1266                If an `Expression` instance is passed, it will be used as-is.
1267            distinct: set the DISTINCT flag if and only if this is true.
1268            dialect: the dialect used to parse the input expression.
1269            opts: other options to use to parse the input expressions.
1270
1271        Returns:
1272            The new Intersect expression.
1273        """
1274        return intersect(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds an INTERSECT expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo")intersect("SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expression: the SQL code string. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect expression.

def except_( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Except:
1276    def except_(
1277        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1278    ) -> Except:
1279        """
1280        Builds an EXCEPT expression.
1281
1282        Example:
1283            >>> import sqlglot
1284            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1285            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1286
1287        Args:
1288            expression: the SQL code string.
1289                If an `Expression` instance is passed, it will be used as-is.
1290            distinct: set the DISTINCT flag if and only if this is true.
1291            dialect: the dialect used to parse the input expression.
1292            opts: other options to use to parse the input expressions.
1293
1294        Returns:
1295            The new Except expression.
1296        """
1297        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds an EXCEPT expression.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("SELECT * FROM foo")except_("SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • expression: the SQL code string. If an Expression instance is passed, it will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except expression.

key = 'query'
class UDTF(DerivedTable):
1300class UDTF(DerivedTable):
1301    @property
1302    def selects(self) -> t.List[Expression]:
1303        alias = self.args.get("alias")
1304        return alias.columns if alias else []
selects: List[Expression]
1301    @property
1302    def selects(self) -> t.List[Expression]:
1303        alias = self.args.get("alias")
1304        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1307class Cache(Expression):
1308    arg_types = {
1309        "this": True,
1310        "lazy": False,
1311        "options": False,
1312        "expression": False,
1313    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1316class Uncache(Expression):
1317    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1320class Refresh(Expression):
1321    pass
key = 'refresh'
class DDL(Expression):
1324class DDL(Expression):
1325    @property
1326    def ctes(self) -> t.List[CTE]:
1327        """Returns a list of all the CTEs attached to this statement."""
1328        with_ = self.args.get("with")
1329        return with_.expressions if with_ else []
1330
1331    @property
1332    def selects(self) -> t.List[Expression]:
1333        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1334        return self.expression.selects if isinstance(self.expression, Query) else []
1335
1336    @property
1337    def named_selects(self) -> t.List[str]:
1338        """
1339        If this statement contains a query (e.g. a CTAS), this returns the output
1340        names of the query's projections.
1341        """
1342        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1325    @property
1326    def ctes(self) -> t.List[CTE]:
1327        """Returns a list of all the CTEs attached to this statement."""
1328        with_ = self.args.get("with")
1329        return with_.expressions if with_ else []

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

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

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

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

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

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

Set the RETURNING expression. Not supported by all dialects.

Example:
>>> delete("tbl").returning("*", dialect="postgres").sql()
'DELETE FROM tbl RETURNING *'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

key = 'dml'
class Create(DDL):
1382class Create(DDL):
1383    arg_types = {
1384        "with": False,
1385        "this": True,
1386        "kind": True,
1387        "expression": False,
1388        "exists": False,
1389        "properties": False,
1390        "replace": False,
1391        "unique": False,
1392        "indexes": False,
1393        "no_schema_binding": False,
1394        "begin": False,
1395        "end": False,
1396        "clone": False,
1397        "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()
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False, 'concurrently': False, 'clustered': False}
kind: Optional[str]
1401    @property
1402    def kind(self) -> t.Optional[str]:
1403        kind = self.args.get("kind")
1404        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
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    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
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    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1435class Clone(Expression):
1436    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1439class Describe(Expression):
1440    arg_types = {"this": True, "style": False, "kind": False, "expressions": False}
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False}
key = 'describe'
class Kill(Expression):
1443class Kill(Expression):
1444    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1447class Pragma(Expression):
1448    pass
key = 'pragma'
class Declare(Expression):
1451class Declare(Expression):
1452    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1455class DeclareItem(Expression):
1456    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1459class Set(Expression):
1460    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1463class Heredoc(Expression):
1464    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1467class SetItem(Expression):
1468    arg_types = {
1469        "this": False,
1470        "expressions": False,
1471        "kind": False,
1472        "collate": False,  # MySQL SET NAMES statement
1473        "global": False,
1474    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1477class Show(Expression):
1478    arg_types = {
1479        "this": True,
1480        "history": False,
1481        "terse": False,
1482        "target": False,
1483        "offset": False,
1484        "starts_with": False,
1485        "limit": False,
1486        "from": False,
1487        "like": False,
1488        "where": False,
1489        "db": False,
1490        "scope": False,
1491        "scope_kind": False,
1492        "full": False,
1493        "mutex": False,
1494        "query": False,
1495        "channel": False,
1496        "global": False,
1497        "log": False,
1498        "position": False,
1499        "types": False,
1500    }
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):
1503class UserDefinedFunction(Expression):
1504    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1507class CharacterSet(Expression):
1508    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1511class With(Expression):
1512    arg_types = {"expressions": True, "recursive": False}
1513
1514    @property
1515    def recursive(self) -> bool:
1516        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1514    @property
1515    def recursive(self) -> bool:
1516        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1519class WithinGroup(Expression):
1520    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1525class CTE(DerivedTable):
1526    arg_types = {
1527        "this": True,
1528        "alias": True,
1529        "scalar": False,
1530        "materialized": False,
1531    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1534class ProjectionDef(Expression):
1535    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1538class TableAlias(Expression):
1539    arg_types = {"this": False, "columns": False}
1540
1541    @property
1542    def columns(self):
1543        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1541    @property
1542    def columns(self):
1543        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1546class BitString(Condition):
1547    pass
key = 'bitstring'
class HexString(Condition):
1550class HexString(Condition):
1551    pass
key = 'hexstring'
class ByteString(Condition):
1554class ByteString(Condition):
1555    pass
key = 'bytestring'
class RawString(Condition):
1558class RawString(Condition):
1559    pass
key = 'rawstring'
class UnicodeString(Condition):
1562class UnicodeString(Condition):
1563    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1566class Column(Condition):
1567    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1568
1569    @property
1570    def table(self) -> str:
1571        return self.text("table")
1572
1573    @property
1574    def db(self) -> str:
1575        return self.text("db")
1576
1577    @property
1578    def catalog(self) -> str:
1579        return self.text("catalog")
1580
1581    @property
1582    def output_name(self) -> str:
1583        return self.name
1584
1585    @property
1586    def parts(self) -> t.List[Identifier]:
1587        """Return the parts of a column in order catalog, db, table, name."""
1588        return [
1589            t.cast(Identifier, self.args[part])
1590            for part in ("catalog", "db", "table", "this")
1591            if self.args.get(part)
1592        ]
1593
1594    def to_dot(self) -> Dot | Identifier:
1595        """Converts the column into a dot expression."""
1596        parts = self.parts
1597        parent = self.parent
1598
1599        while parent:
1600            if isinstance(parent, Dot):
1601                parts.append(parent.expression)
1602            parent = parent.parent
1603
1604        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
1569    @property
1570    def table(self) -> str:
1571        return self.text("table")
db: str
1573    @property
1574    def db(self) -> str:
1575        return self.text("db")
catalog: str
1577    @property
1578    def catalog(self) -> str:
1579        return self.text("catalog")
output_name: str
1581    @property
1582    def output_name(self) -> str:
1583        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]
1585    @property
1586    def parts(self) -> t.List[Identifier]:
1587        """Return the parts of a column in order catalog, db, table, name."""
1588        return [
1589            t.cast(Identifier, self.args[part])
1590            for part in ("catalog", "db", "table", "this")
1591            if self.args.get(part)
1592        ]

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

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

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1607class ColumnPosition(Expression):
1608    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1611class ColumnDef(Expression):
1612    arg_types = {
1613        "this": True,
1614        "kind": False,
1615        "constraints": False,
1616        "exists": False,
1617        "position": False,
1618    }
1619
1620    @property
1621    def constraints(self) -> t.List[ColumnConstraint]:
1622        return self.args.get("constraints") or []
1623
1624    @property
1625    def kind(self) -> t.Optional[DataType]:
1626        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1620    @property
1621    def constraints(self) -> t.List[ColumnConstraint]:
1622        return self.args.get("constraints") or []
kind: Optional[DataType]
1624    @property
1625    def kind(self) -> t.Optional[DataType]:
1626        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1629class AlterColumn(Expression):
1630    arg_types = {
1631        "this": True,
1632        "dtype": False,
1633        "collate": False,
1634        "using": False,
1635        "default": False,
1636        "drop": False,
1637        "comment": False,
1638        "allow_null": False,
1639    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1643class AlterDistStyle(Expression):
1644    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1647class AlterSortKey(Expression):
1648    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1651class AlterSet(Expression):
1652    arg_types = {
1653        "expressions": False,
1654        "option": False,
1655        "tablespace": False,
1656        "access_method": False,
1657        "file_format": False,
1658        "copy_options": False,
1659        "tag": False,
1660        "location": False,
1661        "serde": False,
1662    }
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):
1665class RenameColumn(Expression):
1666    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1669class RenameTable(Expression):
1670    pass
key = 'renametable'
class SwapTable(Expression):
1673class SwapTable(Expression):
1674    pass
key = 'swaptable'
class Comment(Expression):
1677class Comment(Expression):
1678    arg_types = {
1679        "this": True,
1680        "kind": True,
1681        "expression": True,
1682        "exists": False,
1683        "materialized": False,
1684    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1687class Comprehension(Expression):
1688    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):
1692class MergeTreeTTLAction(Expression):
1693    arg_types = {
1694        "this": True,
1695        "delete": False,
1696        "recompress": False,
1697        "to_disk": False,
1698        "to_volume": False,
1699    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1703class MergeTreeTTL(Expression):
1704    arg_types = {
1705        "expressions": True,
1706        "where": False,
1707        "group": False,
1708        "aggregates": False,
1709    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1713class IndexConstraintOption(Expression):
1714    arg_types = {
1715        "key_block_size": False,
1716        "using": False,
1717        "parser": False,
1718        "comment": False,
1719        "visible": False,
1720        "engine_attr": False,
1721        "secondary_engine_attr": False,
1722    }
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):
1725class ColumnConstraint(Expression):
1726    arg_types = {"this": False, "kind": True}
1727
1728    @property
1729    def kind(self) -> ColumnConstraintKind:
1730        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1728    @property
1729    def kind(self) -> ColumnConstraintKind:
1730        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1733class ColumnConstraintKind(Expression):
1734    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1737class AutoIncrementColumnConstraint(ColumnConstraintKind):
1738    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1741class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1742    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1745class CaseSpecificColumnConstraint(ColumnConstraintKind):
1746    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1749class CharacterSetColumnConstraint(ColumnConstraintKind):
1750    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1753class CheckColumnConstraint(ColumnConstraintKind):
1754    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1757class ClusteredColumnConstraint(ColumnConstraintKind):
1758    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1761class CollateColumnConstraint(ColumnConstraintKind):
1762    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1765class CommentColumnConstraint(ColumnConstraintKind):
1766    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1769class CompressColumnConstraint(ColumnConstraintKind):
1770    pass
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1773class DateFormatColumnConstraint(ColumnConstraintKind):
1774    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1777class DefaultColumnConstraint(ColumnConstraintKind):
1778    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1781class EncodeColumnConstraint(ColumnConstraintKind):
1782    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1786class ExcludeColumnConstraint(ColumnConstraintKind):
1787    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1790class EphemeralColumnConstraint(ColumnConstraintKind):
1791    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1794class WithOperator(Expression):
1795    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1798class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1799    # this: True -> ALWAYS, this: False -> BY DEFAULT
1800    arg_types = {
1801        "this": False,
1802        "expression": False,
1803        "on_null": False,
1804        "start": False,
1805        "increment": False,
1806        "minvalue": False,
1807        "maxvalue": False,
1808        "cycle": False,
1809    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1812class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1813    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1818class IndexColumnConstraint(ColumnConstraintKind):
1819    arg_types = {
1820        "this": False,
1821        "expressions": False,
1822        "kind": False,
1823        "index_type": False,
1824        "options": False,
1825        "expression": False,  # Clickhouse
1826        "granularity": False,
1827    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1830class InlineLengthColumnConstraint(ColumnConstraintKind):
1831    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1834class NonClusteredColumnConstraint(ColumnConstraintKind):
1835    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1838class NotForReplicationColumnConstraint(ColumnConstraintKind):
1839    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1843class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1844    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1847class NotNullColumnConstraint(ColumnConstraintKind):
1848    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1852class OnUpdateColumnConstraint(ColumnConstraintKind):
1853    pass
key = 'onupdatecolumnconstraint'
class TagColumnConstraint(ColumnConstraintKind):
1857class TagColumnConstraint(ColumnConstraintKind):
1858    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tagcolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1862class TransformColumnConstraint(ColumnConstraintKind):
1863    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1866class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1867    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1870class TitleColumnConstraint(ColumnConstraintKind):
1871    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1874class UniqueColumnConstraint(ColumnConstraintKind):
1875    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):
1878class UppercaseColumnConstraint(ColumnConstraintKind):
1879    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1882class PathColumnConstraint(ColumnConstraintKind):
1883    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1887class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1888    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1893class ComputedColumnConstraint(ColumnConstraintKind):
1894    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1897class Constraint(Expression):
1898    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1901class Delete(DML):
1902    arg_types = {
1903        "with": False,
1904        "this": False,
1905        "using": False,
1906        "where": False,
1907        "returning": False,
1908        "limit": False,
1909        "tables": False,  # Multiple-Table Syntax (MySQL)
1910    }
1911
1912    def delete(
1913        self,
1914        table: ExpOrStr,
1915        dialect: DialectType = None,
1916        copy: bool = True,
1917        **opts,
1918    ) -> Delete:
1919        """
1920        Create a DELETE expression or replace the table on an existing DELETE expression.
1921
1922        Example:
1923            >>> delete("tbl").sql()
1924            'DELETE FROM tbl'
1925
1926        Args:
1927            table: the table from which to delete.
1928            dialect: the dialect used to parse the input expression.
1929            copy: if `False`, modify this expression instance in-place.
1930            opts: other options to use to parse the input expressions.
1931
1932        Returns:
1933            Delete: the modified expression.
1934        """
1935        return _apply_builder(
1936            expression=table,
1937            instance=self,
1938            arg="this",
1939            dialect=dialect,
1940            into=Table,
1941            copy=copy,
1942            **opts,
1943        )
1944
1945    def where(
1946        self,
1947        *expressions: t.Optional[ExpOrStr],
1948        append: bool = True,
1949        dialect: DialectType = None,
1950        copy: bool = True,
1951        **opts,
1952    ) -> Delete:
1953        """
1954        Append to or set the WHERE expressions.
1955
1956        Example:
1957            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1958            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1959
1960        Args:
1961            *expressions: the SQL code strings to parse.
1962                If an `Expression` instance is passed, it will be used as-is.
1963                Multiple expressions are combined with an AND operator.
1964            append: if `True`, AND the new expressions to any existing expression.
1965                Otherwise, this resets the expression.
1966            dialect: the dialect used to parse the input expressions.
1967            copy: if `False`, modify this expression instance in-place.
1968            opts: other options to use to parse the input expressions.
1969
1970        Returns:
1971            Delete: the modified expression.
1972        """
1973        return _apply_conjunction_builder(
1974            *expressions,
1975            instance=self,
1976            arg="where",
1977            append=append,
1978            into=Where,
1979            dialect=dialect,
1980            copy=copy,
1981            **opts,
1982        )
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:
1912    def delete(
1913        self,
1914        table: ExpOrStr,
1915        dialect: DialectType = None,
1916        copy: bool = True,
1917        **opts,
1918    ) -> Delete:
1919        """
1920        Create a DELETE expression or replace the table on an existing DELETE expression.
1921
1922        Example:
1923            >>> delete("tbl").sql()
1924            'DELETE FROM tbl'
1925
1926        Args:
1927            table: the table from which to delete.
1928            dialect: the dialect used to parse the input expression.
1929            copy: if `False`, modify this expression instance in-place.
1930            opts: other options to use to parse the input expressions.
1931
1932        Returns:
1933            Delete: the modified expression.
1934        """
1935        return _apply_builder(
1936            expression=table,
1937            instance=self,
1938            arg="this",
1939            dialect=dialect,
1940            into=Table,
1941            copy=copy,
1942            **opts,
1943        )

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

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):
1985class Drop(Expression):
1986    arg_types = {
1987        "this": False,
1988        "kind": False,
1989        "expressions": False,
1990        "exists": False,
1991        "temporary": False,
1992        "materialized": False,
1993        "cascade": False,
1994        "constraints": False,
1995        "purge": False,
1996        "cluster": False,
1997    }
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False}
key = 'drop'
class Filter(Expression):
2000class Filter(Expression):
2001    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2004class Check(Expression):
2005    pass
key = 'check'
class Changes(Expression):
2008class Changes(Expression):
2009    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2013class Connect(Expression):
2014    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2017class CopyParameter(Expression):
2018    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2021class Copy(DML):
2022    arg_types = {
2023        "this": True,
2024        "kind": True,
2025        "files": True,
2026        "credentials": False,
2027        "format": False,
2028        "params": False,
2029    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2032class Credentials(Expression):
2033    arg_types = {
2034        "credentials": False,
2035        "encryption": False,
2036        "storage": False,
2037        "iam_role": False,
2038        "region": False,
2039    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2042class Prior(Expression):
2043    pass
key = 'prior'
class Directory(Expression):
2046class Directory(Expression):
2047    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2048    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2051class ForeignKey(Expression):
2052    arg_types = {
2053        "expressions": True,
2054        "reference": False,
2055        "delete": False,
2056        "update": False,
2057    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2060class ColumnPrefix(Expression):
2061    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2064class PrimaryKey(Expression):
2065    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2070class Into(Expression):
2071    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2074class From(Expression):
2075    @property
2076    def name(self) -> str:
2077        return self.this.name
2078
2079    @property
2080    def alias_or_name(self) -> str:
2081        return self.this.alias_or_name
name: str
2075    @property
2076    def name(self) -> str:
2077        return self.this.name
alias_or_name: str
2079    @property
2080    def alias_or_name(self) -> str:
2081        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2084class Having(Expression):
2085    pass
key = 'having'
class Hint(Expression):
2088class Hint(Expression):
2089    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2092class JoinHint(Expression):
2093    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2096class Identifier(Expression):
2097    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2098
2099    @property
2100    def quoted(self) -> bool:
2101        return bool(self.args.get("quoted"))
2102
2103    @property
2104    def hashable_args(self) -> t.Any:
2105        return (self.this, self.quoted)
2106
2107    @property
2108    def output_name(self) -> str:
2109        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2099    @property
2100    def quoted(self) -> bool:
2101        return bool(self.args.get("quoted"))
hashable_args: Any
2103    @property
2104    def hashable_args(self) -> t.Any:
2105        return (self.this, self.quoted)
output_name: str
2107    @property
2108    def output_name(self) -> str:
2109        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):
2113class Opclass(Expression):
2114    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2117class Index(Expression):
2118    arg_types = {
2119        "this": False,
2120        "table": False,
2121        "unique": False,
2122        "primary": False,
2123        "amp": False,  # teradata
2124        "params": False,
2125    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2128class IndexParameters(Expression):
2129    arg_types = {
2130        "using": False,
2131        "include": False,
2132        "columns": False,
2133        "with_storage": False,
2134        "partition_by": False,
2135        "tablespace": False,
2136        "where": False,
2137        "on": False,
2138    }
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):
2141class Insert(DDL, DML):
2142    arg_types = {
2143        "hint": False,
2144        "with": False,
2145        "is_function": False,
2146        "this": False,
2147        "expression": False,
2148        "conflict": False,
2149        "returning": False,
2150        "overwrite": False,
2151        "exists": False,
2152        "alternative": False,
2153        "where": False,
2154        "ignore": False,
2155        "by_name": False,
2156        "stored": False,
2157    }
2158
2159    def with_(
2160        self,
2161        alias: ExpOrStr,
2162        as_: ExpOrStr,
2163        recursive: t.Optional[bool] = None,
2164        append: bool = True,
2165        dialect: DialectType = None,
2166        copy: bool = True,
2167        **opts,
2168    ) -> Insert:
2169        """
2170        Append to or set the common table expressions.
2171
2172        Example:
2173            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2174            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2175
2176        Args:
2177            alias: the SQL code string to parse as the table name.
2178                If an `Expression` instance is passed, this is used as-is.
2179            as_: the SQL code string to parse as the table expression.
2180                If an `Expression` instance is passed, it will be used as-is.
2181            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2182            append: if `True`, add to any existing expressions.
2183                Otherwise, this resets the expressions.
2184            dialect: the dialect used to parse the input expression.
2185            copy: if `False`, modify this expression instance in-place.
2186            opts: other options to use to parse the input expressions.
2187
2188        Returns:
2189            The modified expression.
2190        """
2191        return _apply_cte_builder(
2192            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2193        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2159    def with_(
2160        self,
2161        alias: ExpOrStr,
2162        as_: ExpOrStr,
2163        recursive: t.Optional[bool] = None,
2164        append: bool = True,
2165        dialect: DialectType = None,
2166        copy: bool = True,
2167        **opts,
2168    ) -> Insert:
2169        """
2170        Append to or set the common table expressions.
2171
2172        Example:
2173            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2174            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2175
2176        Args:
2177            alias: the SQL code string to parse as the table name.
2178                If an `Expression` instance is passed, this is used as-is.
2179            as_: the SQL code string to parse as the table expression.
2180                If an `Expression` instance is passed, it will be used as-is.
2181            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2182            append: if `True`, add to any existing expressions.
2183                Otherwise, this resets the expressions.
2184            dialect: the dialect used to parse the input expression.
2185            copy: if `False`, modify this expression instance in-place.
2186            opts: other options to use to parse the input expressions.
2187
2188        Returns:
2189            The modified expression.
2190        """
2191        return _apply_cte_builder(
2192            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2193        )

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):
2196class OnConflict(Expression):
2197    arg_types = {
2198        "duplicate": False,
2199        "expressions": False,
2200        "action": False,
2201        "conflict_keys": False,
2202        "constraint": False,
2203    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2206class Returning(Expression):
2207    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2211class Introducer(Expression):
2212    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2216class National(Expression):
2217    pass
key = 'national'
class LoadData(Expression):
2220class LoadData(Expression):
2221    arg_types = {
2222        "this": True,
2223        "local": False,
2224        "overwrite": False,
2225        "inpath": True,
2226        "partition": False,
2227        "input_format": False,
2228        "serde": False,
2229    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2232class Partition(Expression):
2233    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2236class PartitionRange(Expression):
2237    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2241class PartitionId(Expression):
2242    pass
key = 'partitionid'
class Fetch(Expression):
2245class Fetch(Expression):
2246    arg_types = {
2247        "direction": False,
2248        "count": False,
2249        "percent": False,
2250        "with_ties": False,
2251    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2254class Group(Expression):
2255    arg_types = {
2256        "expressions": False,
2257        "grouping_sets": False,
2258        "cube": False,
2259        "rollup": False,
2260        "totals": False,
2261        "all": False,
2262    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2265class Lambda(Expression):
2266    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2269class Limit(Expression):
2270    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):
2273class Literal(Condition):
2274    arg_types = {"this": True, "is_string": True}
2275
2276    @property
2277    def hashable_args(self) -> t.Any:
2278        return (self.this, self.args.get("is_string"))
2279
2280    @classmethod
2281    def number(cls, number) -> Literal:
2282        return cls(this=str(number), is_string=False)
2283
2284    @classmethod
2285    def string(cls, string) -> Literal:
2286        return cls(this=str(string), is_string=True)
2287
2288    @property
2289    def output_name(self) -> str:
2290        return self.name
2291
2292    def to_py(self) -> int | str | Decimal:
2293        if self.is_number:
2294            try:
2295                return int(self.this)
2296            except ValueError:
2297                return Decimal(self.this)
2298        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2276    @property
2277    def hashable_args(self) -> t.Any:
2278        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2280    @classmethod
2281    def number(cls, number) -> Literal:
2282        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2284    @classmethod
2285    def string(cls, string) -> Literal:
2286        return cls(this=str(string), is_string=True)
output_name: str
2288    @property
2289    def output_name(self) -> str:
2290        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:
2292    def to_py(self) -> int | str | Decimal:
2293        if self.is_number:
2294            try:
2295                return int(self.this)
2296            except ValueError:
2297                return Decimal(self.this)
2298        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2301class Join(Expression):
2302    arg_types = {
2303        "this": True,
2304        "on": False,
2305        "side": False,
2306        "kind": False,
2307        "using": False,
2308        "method": False,
2309        "global": False,
2310        "hint": False,
2311        "match_condition": False,  # Snowflake
2312    }
2313
2314    @property
2315    def method(self) -> str:
2316        return self.text("method").upper()
2317
2318    @property
2319    def kind(self) -> str:
2320        return self.text("kind").upper()
2321
2322    @property
2323    def side(self) -> str:
2324        return self.text("side").upper()
2325
2326    @property
2327    def hint(self) -> str:
2328        return self.text("hint").upper()
2329
2330    @property
2331    def alias_or_name(self) -> str:
2332        return self.this.alias_or_name
2333
2334    def on(
2335        self,
2336        *expressions: t.Optional[ExpOrStr],
2337        append: bool = True,
2338        dialect: DialectType = None,
2339        copy: bool = True,
2340        **opts,
2341    ) -> Join:
2342        """
2343        Append to or set the ON expressions.
2344
2345        Example:
2346            >>> import sqlglot
2347            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2348            'JOIN x ON y = 1'
2349
2350        Args:
2351            *expressions: the SQL code strings to parse.
2352                If an `Expression` instance is passed, it will be used as-is.
2353                Multiple expressions are combined with an AND operator.
2354            append: if `True`, AND the new expressions to any existing expression.
2355                Otherwise, this resets the expression.
2356            dialect: the dialect used to parse the input expressions.
2357            copy: if `False`, modify this expression instance in-place.
2358            opts: other options to use to parse the input expressions.
2359
2360        Returns:
2361            The modified Join expression.
2362        """
2363        join = _apply_conjunction_builder(
2364            *expressions,
2365            instance=self,
2366            arg="on",
2367            append=append,
2368            dialect=dialect,
2369            copy=copy,
2370            **opts,
2371        )
2372
2373        if join.kind == "CROSS":
2374            join.set("kind", None)
2375
2376        return join
2377
2378    def using(
2379        self,
2380        *expressions: t.Optional[ExpOrStr],
2381        append: bool = True,
2382        dialect: DialectType = None,
2383        copy: bool = True,
2384        **opts,
2385    ) -> Join:
2386        """
2387        Append to or set the USING expressions.
2388
2389        Example:
2390            >>> import sqlglot
2391            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2392            'JOIN x USING (foo, bla)'
2393
2394        Args:
2395            *expressions: the SQL code strings to parse.
2396                If an `Expression` instance is passed, it will be used as-is.
2397            append: if `True`, concatenate the new expressions to the existing "using" list.
2398                Otherwise, this resets the expression.
2399            dialect: the dialect used to parse the input expressions.
2400            copy: if `False`, modify this expression instance in-place.
2401            opts: other options to use to parse the input expressions.
2402
2403        Returns:
2404            The modified Join expression.
2405        """
2406        join = _apply_list_builder(
2407            *expressions,
2408            instance=self,
2409            arg="using",
2410            append=append,
2411            dialect=dialect,
2412            copy=copy,
2413            **opts,
2414        )
2415
2416        if join.kind == "CROSS":
2417            join.set("kind", None)
2418
2419        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
2314    @property
2315    def method(self) -> str:
2316        return self.text("method").upper()
kind: str
2318    @property
2319    def kind(self) -> str:
2320        return self.text("kind").upper()
side: str
2322    @property
2323    def side(self) -> str:
2324        return self.text("side").upper()
hint: str
2326    @property
2327    def hint(self) -> str:
2328        return self.text("hint").upper()
alias_or_name: str
2330    @property
2331    def alias_or_name(self) -> str:
2332        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:
2334    def on(
2335        self,
2336        *expressions: t.Optional[ExpOrStr],
2337        append: bool = True,
2338        dialect: DialectType = None,
2339        copy: bool = True,
2340        **opts,
2341    ) -> Join:
2342        """
2343        Append to or set the ON expressions.
2344
2345        Example:
2346            >>> import sqlglot
2347            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2348            'JOIN x ON y = 1'
2349
2350        Args:
2351            *expressions: the SQL code strings to parse.
2352                If an `Expression` instance is passed, it will be used as-is.
2353                Multiple expressions are combined with an AND operator.
2354            append: if `True`, AND the new expressions to any existing expression.
2355                Otherwise, this resets the expression.
2356            dialect: the dialect used to parse the input expressions.
2357            copy: if `False`, modify this expression instance in-place.
2358            opts: other options to use to parse the input expressions.
2359
2360        Returns:
2361            The modified Join expression.
2362        """
2363        join = _apply_conjunction_builder(
2364            *expressions,
2365            instance=self,
2366            arg="on",
2367            append=append,
2368            dialect=dialect,
2369            copy=copy,
2370            **opts,
2371        )
2372
2373        if join.kind == "CROSS":
2374            join.set("kind", None)
2375
2376        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:
2378    def using(
2379        self,
2380        *expressions: t.Optional[ExpOrStr],
2381        append: bool = True,
2382        dialect: DialectType = None,
2383        copy: bool = True,
2384        **opts,
2385    ) -> Join:
2386        """
2387        Append to or set the USING expressions.
2388
2389        Example:
2390            >>> import sqlglot
2391            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2392            'JOIN x USING (foo, bla)'
2393
2394        Args:
2395            *expressions: the SQL code strings to parse.
2396                If an `Expression` instance is passed, it will be used as-is.
2397            append: if `True`, concatenate the new expressions to the existing "using" list.
2398                Otherwise, this resets the expression.
2399            dialect: the dialect used to parse the input expressions.
2400            copy: if `False`, modify this expression instance in-place.
2401            opts: other options to use to parse the input expressions.
2402
2403        Returns:
2404            The modified Join expression.
2405        """
2406        join = _apply_list_builder(
2407            *expressions,
2408            instance=self,
2409            arg="using",
2410            append=append,
2411            dialect=dialect,
2412            copy=copy,
2413            **opts,
2414        )
2415
2416        if join.kind == "CROSS":
2417            join.set("kind", None)
2418
2419        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):
2422class Lateral(UDTF):
2423    arg_types = {
2424        "this": True,
2425        "view": False,
2426        "outer": False,
2427        "alias": False,
2428        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2429    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2432class MatchRecognizeMeasure(Expression):
2433    arg_types = {
2434        "this": True,
2435        "window_frame": False,
2436    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2439class MatchRecognize(Expression):
2440    arg_types = {
2441        "partition_by": False,
2442        "order": False,
2443        "measures": False,
2444        "rows": False,
2445        "after": False,
2446        "pattern": False,
2447        "define": False,
2448        "alias": False,
2449    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2454class Final(Expression):
2455    pass
key = 'final'
class Offset(Expression):
2458class Offset(Expression):
2459    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2462class Order(Expression):
2463    arg_types = {
2464        "this": False,
2465        "expressions": True,
2466        "interpolate": False,
2467        "siblings": False,
2468    }
arg_types = {'this': False, 'expressions': True, 'interpolate': False, 'siblings': False}
key = 'order'
class WithFill(Expression):
2472class WithFill(Expression):
2473    arg_types = {"from": False, "to": False, "step": False}
arg_types = {'from': False, 'to': False, 'step': False}
key = 'withfill'
class Cluster(Order):
2478class Cluster(Order):
2479    pass
key = 'cluster'
class Distribute(Order):
2482class Distribute(Order):
2483    pass
key = 'distribute'
class Sort(Order):
2486class Sort(Order):
2487    pass
key = 'sort'
class Ordered(Expression):
2490class Ordered(Expression):
2491    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):
2494class Property(Expression):
2495    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2498class AllowedValuesProperty(Expression):
2499    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2502class AlgorithmProperty(Property):
2503    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2506class AutoIncrementProperty(Property):
2507    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2511class AutoRefreshProperty(Property):
2512    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2515class BackupProperty(Property):
2516    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2519class BlockCompressionProperty(Property):
2520    arg_types = {
2521        "autotemp": False,
2522        "always": False,
2523        "default": False,
2524        "manual": False,
2525        "never": False,
2526    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2529class CharacterSetProperty(Property):
2530    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2533class ChecksumProperty(Property):
2534    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2537class CollateProperty(Property):
2538    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2541class CopyGrantsProperty(Property):
2542    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2545class DataBlocksizeProperty(Property):
2546    arg_types = {
2547        "size": False,
2548        "units": False,
2549        "minimum": False,
2550        "maximum": False,
2551        "default": False,
2552    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2555class DataDeletionProperty(Property):
2556    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):
2559class DefinerProperty(Property):
2560    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2563class DistKeyProperty(Property):
2564    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2567class DistStyleProperty(Property):
2568    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2571class EngineProperty(Property):
2572    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2575class HeapProperty(Property):
2576    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2579class ToTableProperty(Property):
2580    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2583class ExecuteAsProperty(Property):
2584    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2587class ExternalProperty(Property):
2588    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2591class FallbackProperty(Property):
2592    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2595class FileFormatProperty(Property):
2596    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2599class FreespaceProperty(Property):
2600    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2603class GlobalProperty(Property):
2604    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2607class IcebergProperty(Property):
2608    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2611class InheritsProperty(Property):
2612    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2615class InputModelProperty(Property):
2616    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2619class OutputModelProperty(Property):
2620    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2623class IsolatedLoadingProperty(Property):
2624    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2627class JournalProperty(Property):
2628    arg_types = {
2629        "no": False,
2630        "dual": False,
2631        "before": False,
2632        "local": False,
2633        "after": False,
2634    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2637class LanguageProperty(Property):
2638    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2642class ClusteredByProperty(Property):
2643    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2646class DictProperty(Property):
2647    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2650class DictSubProperty(Property):
2651    pass
key = 'dictsubproperty'
class DictRange(Property):
2654class DictRange(Property):
2655    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2658class DynamicProperty(Property):
2659    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2664class OnCluster(Property):
2665    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class LikeProperty(Property):
2668class LikeProperty(Property):
2669    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2672class LocationProperty(Property):
2673    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2676class LockProperty(Property):
2677    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2680class LockingProperty(Property):
2681    arg_types = {
2682        "this": False,
2683        "kind": True,
2684        "for_or_in": False,
2685        "lock_type": True,
2686        "override": False,
2687    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2690class LogProperty(Property):
2691    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2694class MaterializedProperty(Property):
2695    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2698class MergeBlockRatioProperty(Property):
2699    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):
2702class NoPrimaryIndexProperty(Property):
2703    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2706class OnProperty(Property):
2707    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2710class OnCommitProperty(Property):
2711    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2714class PartitionedByProperty(Property):
2715    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2719class PartitionBoundSpec(Expression):
2720    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2721    arg_types = {
2722        "this": False,
2723        "expression": False,
2724        "from_expressions": False,
2725        "to_expressions": False,
2726    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2729class PartitionedOfProperty(Property):
2730    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2731    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class RemoteWithConnectionModelProperty(Property):
2734class RemoteWithConnectionModelProperty(Property):
2735    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2738class ReturnsProperty(Property):
2739    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):
2742class StrictProperty(Property):
2743    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2746class RowFormatProperty(Property):
2747    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2750class RowFormatDelimitedProperty(Property):
2751    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2752    arg_types = {
2753        "fields": False,
2754        "escaped": False,
2755        "collection_items": False,
2756        "map_keys": False,
2757        "lines": False,
2758        "null": False,
2759        "serde": False,
2760    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2763class RowFormatSerdeProperty(Property):
2764    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2768class QueryTransform(Expression):
2769    arg_types = {
2770        "expressions": True,
2771        "command_script": True,
2772        "schema": False,
2773        "row_format_before": False,
2774        "record_writer": False,
2775        "row_format_after": False,
2776        "record_reader": False,
2777    }
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):
2780class SampleProperty(Property):
2781    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2784class SchemaCommentProperty(Property):
2785    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2788class SerdeProperties(Property):
2789    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2792class SetProperty(Property):
2793    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2796class SharingProperty(Property):
2797    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2800class SetConfigProperty(Property):
2801    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2804class SettingsProperty(Property):
2805    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2808class SortKeyProperty(Property):
2809    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2812class SqlReadWriteProperty(Property):
2813    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2816class SqlSecurityProperty(Property):
2817    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2820class StabilityProperty(Property):
2821    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2824class TemporaryProperty(Property):
2825    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2828class SecureProperty(Property):
2829    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2832class TransformModelProperty(Property):
2833    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2836class TransientProperty(Property):
2837    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2840class UnloggedProperty(Property):
2841    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2845class ViewAttributeProperty(Property):
2846    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2849class VolatileProperty(Property):
2850    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2853class WithDataProperty(Property):
2854    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2857class WithJournalTableProperty(Property):
2858    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2861class WithSchemaBindingProperty(Property):
2862    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2865class WithSystemVersioningProperty(Property):
2866    arg_types = {
2867        "on": False,
2868        "this": False,
2869        "data_consistency": False,
2870        "retention_period": False,
2871        "with": True,
2872    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2875class Properties(Expression):
2876    arg_types = {"expressions": True}
2877
2878    NAME_TO_PROPERTY = {
2879        "ALGORITHM": AlgorithmProperty,
2880        "AUTO_INCREMENT": AutoIncrementProperty,
2881        "CHARACTER SET": CharacterSetProperty,
2882        "CLUSTERED_BY": ClusteredByProperty,
2883        "COLLATE": CollateProperty,
2884        "COMMENT": SchemaCommentProperty,
2885        "DEFINER": DefinerProperty,
2886        "DISTKEY": DistKeyProperty,
2887        "DISTSTYLE": DistStyleProperty,
2888        "ENGINE": EngineProperty,
2889        "EXECUTE AS": ExecuteAsProperty,
2890        "FORMAT": FileFormatProperty,
2891        "LANGUAGE": LanguageProperty,
2892        "LOCATION": LocationProperty,
2893        "LOCK": LockProperty,
2894        "PARTITIONED_BY": PartitionedByProperty,
2895        "RETURNS": ReturnsProperty,
2896        "ROW_FORMAT": RowFormatProperty,
2897        "SORTKEY": SortKeyProperty,
2898    }
2899
2900    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2901
2902    # CREATE property locations
2903    # Form: schema specified
2904    #   create [POST_CREATE]
2905    #     table a [POST_NAME]
2906    #     (b int) [POST_SCHEMA]
2907    #     with ([POST_WITH])
2908    #     index (b) [POST_INDEX]
2909    #
2910    # Form: alias selection
2911    #   create [POST_CREATE]
2912    #     table a [POST_NAME]
2913    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2914    #     index (c) [POST_INDEX]
2915    class Location(AutoName):
2916        POST_CREATE = auto()
2917        POST_NAME = auto()
2918        POST_SCHEMA = auto()
2919        POST_WITH = auto()
2920        POST_ALIAS = auto()
2921        POST_EXPRESSION = auto()
2922        POST_INDEX = auto()
2923        UNSUPPORTED = auto()
2924
2925    @classmethod
2926    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2927        expressions = []
2928        for key, value in properties_dict.items():
2929            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2930            if property_cls:
2931                expressions.append(property_cls(this=convert(value)))
2932            else:
2933                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2934
2935        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:
2925    @classmethod
2926    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2927        expressions = []
2928        for key, value in properties_dict.items():
2929            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2930            if property_cls:
2931                expressions.append(property_cls(this=convert(value)))
2932            else:
2933                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2934
2935        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2915    class Location(AutoName):
2916        POST_CREATE = auto()
2917        POST_NAME = auto()
2918        POST_SCHEMA = auto()
2919        POST_WITH = auto()
2920        POST_ALIAS = auto()
2921        POST_EXPRESSION = auto()
2922        POST_INDEX = auto()
2923        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):
2938class Qualify(Expression):
2939    pass
key = 'qualify'
class InputOutputFormat(Expression):
2942class InputOutputFormat(Expression):
2943    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2947class Return(Expression):
2948    pass
key = 'return'
class Reference(Expression):
2951class Reference(Expression):
2952    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2955class Tuple(Expression):
2956    arg_types = {"expressions": False}
2957
2958    def isin(
2959        self,
2960        *expressions: t.Any,
2961        query: t.Optional[ExpOrStr] = None,
2962        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2963        copy: bool = True,
2964        **opts,
2965    ) -> In:
2966        return In(
2967            this=maybe_copy(self, copy),
2968            expressions=[convert(e, copy=copy) for e in expressions],
2969            query=maybe_parse(query, copy=copy, **opts) if query else None,
2970            unnest=(
2971                Unnest(
2972                    expressions=[
2973                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2974                        for e in ensure_list(unnest)
2975                    ]
2976                )
2977                if unnest
2978                else None
2979            ),
2980        )
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:
2958    def isin(
2959        self,
2960        *expressions: t.Any,
2961        query: t.Optional[ExpOrStr] = None,
2962        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2963        copy: bool = True,
2964        **opts,
2965    ) -> In:
2966        return In(
2967            this=maybe_copy(self, copy),
2968            expressions=[convert(e, copy=copy) for e in expressions],
2969            query=maybe_parse(query, copy=copy, **opts) if query else None,
2970            unnest=(
2971                Unnest(
2972                    expressions=[
2973                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
2974                        for e in ensure_list(unnest)
2975                    ]
2976                )
2977                if unnest
2978                else None
2979            ),
2980        )
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):
3011class QueryOption(Expression):
3012    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3016class WithTableHint(Expression):
3017    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3021class IndexTableHint(Expression):
3022    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3026class HistoricalData(Expression):
3027    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3030class Table(Expression):
3031    arg_types = {
3032        "this": False,
3033        "alias": False,
3034        "db": False,
3035        "catalog": False,
3036        "laterals": False,
3037        "joins": False,
3038        "pivots": False,
3039        "hints": False,
3040        "system_time": False,
3041        "version": False,
3042        "format": False,
3043        "pattern": False,
3044        "ordinality": False,
3045        "when": False,
3046        "only": False,
3047        "partition": False,
3048        "changes": False,
3049        "rows_from": False,
3050    }
3051
3052    @property
3053    def name(self) -> str:
3054        if isinstance(self.this, Func):
3055            return ""
3056        return self.this.name
3057
3058    @property
3059    def db(self) -> str:
3060        return self.text("db")
3061
3062    @property
3063    def catalog(self) -> str:
3064        return self.text("catalog")
3065
3066    @property
3067    def selects(self) -> t.List[Expression]:
3068        return []
3069
3070    @property
3071    def named_selects(self) -> t.List[str]:
3072        return []
3073
3074    @property
3075    def parts(self) -> t.List[Expression]:
3076        """Return the parts of a table in order catalog, db, table."""
3077        parts: t.List[Expression] = []
3078
3079        for arg in ("catalog", "db", "this"):
3080            part = self.args.get(arg)
3081
3082            if isinstance(part, Dot):
3083                parts.extend(part.flatten())
3084            elif isinstance(part, Expression):
3085                parts.append(part)
3086
3087        return parts
3088
3089    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3090        parts = self.parts
3091        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3092        alias = self.args.get("alias")
3093        if alias:
3094            col = alias_(col, alias.this, copy=copy)
3095        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
3052    @property
3053    def name(self) -> str:
3054        if isinstance(self.this, Func):
3055            return ""
3056        return self.this.name
db: str
3058    @property
3059    def db(self) -> str:
3060        return self.text("db")
catalog: str
3062    @property
3063    def catalog(self) -> str:
3064        return self.text("catalog")
selects: List[Expression]
3066    @property
3067    def selects(self) -> t.List[Expression]:
3068        return []
named_selects: List[str]
3070    @property
3071    def named_selects(self) -> t.List[str]:
3072        return []
parts: List[Expression]
3074    @property
3075    def parts(self) -> t.List[Expression]:
3076        """Return the parts of a table in order catalog, db, table."""
3077        parts: t.List[Expression] = []
3078
3079        for arg in ("catalog", "db", "this"):
3080            part = self.args.get(arg)
3081
3082            if isinstance(part, Dot):
3083                parts.extend(part.flatten())
3084            elif isinstance(part, Expression):
3085                parts.append(part)
3086
3087        return parts

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

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

Returns the output names of the query's projections.

is_star: bool
3127    @property
3128    def is_star(self) -> bool:
3129        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3131    @property
3132    def selects(self) -> t.List[Expression]:
3133        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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:
3369    def select(
3370        self,
3371        *expressions: t.Optional[ExpOrStr],
3372        append: bool = True,
3373        dialect: DialectType = None,
3374        copy: bool = True,
3375        **opts,
3376    ) -> Select:
3377        return _apply_list_builder(
3378            *expressions,
3379            instance=self,
3380            arg="expressions",
3381            append=append,
3382            dialect=dialect,
3383            into=Expression,
3384            copy=copy,
3385            **opts,
3386        )

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3759    @property
3760    def selects(self) -> t.List[Expression]:
3761        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

def unwrap(self) -> Subquery:
3782    def unwrap(self) -> Subquery:
3783        expression = self
3784        while expression.same_parent and expression.is_wrapper:
3785            expression = t.cast(Subquery, expression.parent)
3786        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:
3788    def select(
3789        self,
3790        *expressions: t.Optional[ExpOrStr],
3791        append: bool = True,
3792        dialect: DialectType = None,
3793        copy: bool = True,
3794        **opts,
3795    ) -> Subquery:
3796        this = maybe_copy(self, copy)
3797        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3798        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
3800    @property
3801    def is_wrapper(self) -> bool:
3802        """
3803        Whether this Subquery acts as a simple wrapper around another expression.
3804
3805        SELECT * FROM (((SELECT * FROM t)))
3806                      ^
3807                      This corresponds to a "wrapper" Subquery node
3808        """
3809        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
3811    @property
3812    def is_star(self) -> bool:
3813        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3815    @property
3816    def output_name(self) -> str:
3817        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):
3820class TableSample(Expression):
3821    arg_types = {
3822        "this": False,
3823        "expressions": False,
3824        "method": False,
3825        "bucket_numerator": False,
3826        "bucket_denominator": False,
3827        "bucket_field": False,
3828        "percent": False,
3829        "rows": False,
3830        "size": False,
3831        "seed": False,
3832    }
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):
3835class Tag(Expression):
3836    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3837
3838    arg_types = {
3839        "this": False,
3840        "prefix": False,
3841        "postfix": False,
3842    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3847class Pivot(Expression):
3848    arg_types = {
3849        "this": False,
3850        "alias": False,
3851        "expressions": False,
3852        "field": False,
3853        "unpivot": False,
3854        "using": False,
3855        "group": False,
3856        "columns": False,
3857        "include_nulls": False,
3858    }
3859
3860    @property
3861    def unpivot(self) -> bool:
3862        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False}
unpivot: bool
3860    @property
3861    def unpivot(self) -> bool:
3862        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3865class Window(Condition):
3866    arg_types = {
3867        "this": True,
3868        "partition_by": False,
3869        "order": False,
3870        "spec": False,
3871        "alias": False,
3872        "over": False,
3873        "first": False,
3874    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3877class WindowSpec(Expression):
3878    arg_types = {
3879        "kind": False,
3880        "start": False,
3881        "start_side": False,
3882        "end": False,
3883        "end_side": False,
3884    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3887class PreWhere(Expression):
3888    pass
key = 'prewhere'
class Where(Expression):
3891class Where(Expression):
3892    pass
key = 'where'
class Star(Expression):
3895class Star(Expression):
3896    arg_types = {"except": False, "replace": False, "rename": False}
3897
3898    @property
3899    def name(self) -> str:
3900        return "*"
3901
3902    @property
3903    def output_name(self) -> str:
3904        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3898    @property
3899    def name(self) -> str:
3900        return "*"
output_name: str
3902    @property
3903    def output_name(self) -> str:
3904        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):
3907class Parameter(Condition):
3908    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3911class SessionParameter(Condition):
3912    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3915class Placeholder(Condition):
3916    arg_types = {"this": False, "kind": False}
3917
3918    @property
3919    def name(self) -> str:
3920        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3918    @property
3919    def name(self) -> str:
3920        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3923class Null(Condition):
3924    arg_types: t.Dict[str, t.Any] = {}
3925
3926    @property
3927    def name(self) -> str:
3928        return "NULL"
3929
3930    def to_py(self) -> Lit[None]:
3931        return None
arg_types: Dict[str, Any] = {}
name: str
3926    @property
3927    def name(self) -> str:
3928        return "NULL"
def to_py(self) -> Literal[None]:
3930    def to_py(self) -> Lit[None]:
3931        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
3934class Boolean(Condition):
3935    def to_py(self) -> bool:
3936        return self.this
def to_py(self) -> bool:
3935    def to_py(self) -> bool:
3936        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
3939class DataTypeParam(Expression):
3940    arg_types = {"this": True, "expression": False}
3941
3942    @property
3943    def name(self) -> str:
3944        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
3942    @property
3943    def name(self) -> str:
3944        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
3947class DataType(Expression):
3948    arg_types = {
3949        "this": True,
3950        "expressions": False,
3951        "nested": False,
3952        "values": False,
3953        "prefix": False,
3954        "kind": False,
3955    }
3956
3957    class Type(AutoName):
3958        ARRAY = auto()
3959        AGGREGATEFUNCTION = auto()
3960        SIMPLEAGGREGATEFUNCTION = auto()
3961        BIGDECIMAL = auto()
3962        BIGINT = auto()
3963        BIGSERIAL = auto()
3964        BINARY = auto()
3965        BIT = auto()
3966        BOOLEAN = auto()
3967        BPCHAR = auto()
3968        CHAR = auto()
3969        DATE = auto()
3970        DATE32 = auto()
3971        DATEMULTIRANGE = auto()
3972        DATERANGE = auto()
3973        DATETIME = auto()
3974        DATETIME64 = auto()
3975        DECIMAL = auto()
3976        DOUBLE = auto()
3977        ENUM = auto()
3978        ENUM8 = auto()
3979        ENUM16 = auto()
3980        FIXEDSTRING = auto()
3981        FLOAT = auto()
3982        GEOGRAPHY = auto()
3983        GEOMETRY = auto()
3984        HLLSKETCH = auto()
3985        HSTORE = auto()
3986        IMAGE = auto()
3987        INET = auto()
3988        INT = auto()
3989        INT128 = auto()
3990        INT256 = auto()
3991        INT4MULTIRANGE = auto()
3992        INT4RANGE = auto()
3993        INT8MULTIRANGE = auto()
3994        INT8RANGE = auto()
3995        INTERVAL = auto()
3996        IPADDRESS = auto()
3997        IPPREFIX = auto()
3998        IPV4 = auto()
3999        IPV6 = auto()
4000        JSON = auto()
4001        JSONB = auto()
4002        LIST = auto()
4003        LONGBLOB = auto()
4004        LONGTEXT = auto()
4005        LOWCARDINALITY = auto()
4006        MAP = auto()
4007        MEDIUMBLOB = auto()
4008        MEDIUMINT = auto()
4009        MEDIUMTEXT = auto()
4010        MONEY = auto()
4011        NAME = auto()
4012        NCHAR = auto()
4013        NESTED = auto()
4014        NULL = auto()
4015        NULLABLE = auto()
4016        NUMMULTIRANGE = auto()
4017        NUMRANGE = auto()
4018        NVARCHAR = auto()
4019        OBJECT = auto()
4020        ROWVERSION = auto()
4021        SERIAL = auto()
4022        SET = auto()
4023        SMALLINT = auto()
4024        SMALLMONEY = auto()
4025        SMALLSERIAL = auto()
4026        STRUCT = auto()
4027        SUPER = auto()
4028        TEXT = auto()
4029        TINYBLOB = auto()
4030        TINYTEXT = auto()
4031        TIME = auto()
4032        TIMETZ = auto()
4033        TIMESTAMP = auto()
4034        TIMESTAMPNTZ = auto()
4035        TIMESTAMPLTZ = auto()
4036        TIMESTAMPTZ = auto()
4037        TIMESTAMP_S = auto()
4038        TIMESTAMP_MS = auto()
4039        TIMESTAMP_NS = auto()
4040        TINYINT = auto()
4041        TSMULTIRANGE = auto()
4042        TSRANGE = auto()
4043        TSTZMULTIRANGE = auto()
4044        TSTZRANGE = auto()
4045        UBIGINT = auto()
4046        UINT = auto()
4047        UINT128 = auto()
4048        UINT256 = auto()
4049        UMEDIUMINT = auto()
4050        UDECIMAL = auto()
4051        UNIQUEIDENTIFIER = auto()
4052        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4053        USERDEFINED = "USER-DEFINED"
4054        USMALLINT = auto()
4055        UTINYINT = auto()
4056        UUID = auto()
4057        VARBINARY = auto()
4058        VARCHAR = auto()
4059        VARIANT = auto()
4060        VECTOR = auto()
4061        XML = auto()
4062        YEAR = auto()
4063        TDIGEST = auto()
4064
4065    STRUCT_TYPES = {
4066        Type.NESTED,
4067        Type.OBJECT,
4068        Type.STRUCT,
4069    }
4070
4071    NESTED_TYPES = {
4072        *STRUCT_TYPES,
4073        Type.ARRAY,
4074        Type.MAP,
4075    }
4076
4077    TEXT_TYPES = {
4078        Type.CHAR,
4079        Type.NCHAR,
4080        Type.NVARCHAR,
4081        Type.TEXT,
4082        Type.VARCHAR,
4083        Type.NAME,
4084    }
4085
4086    SIGNED_INTEGER_TYPES = {
4087        Type.BIGINT,
4088        Type.INT,
4089        Type.INT128,
4090        Type.INT256,
4091        Type.MEDIUMINT,
4092        Type.SMALLINT,
4093        Type.TINYINT,
4094    }
4095
4096    UNSIGNED_INTEGER_TYPES = {
4097        Type.UBIGINT,
4098        Type.UINT,
4099        Type.UINT128,
4100        Type.UINT256,
4101        Type.UMEDIUMINT,
4102        Type.USMALLINT,
4103        Type.UTINYINT,
4104    }
4105
4106    INTEGER_TYPES = {
4107        *SIGNED_INTEGER_TYPES,
4108        *UNSIGNED_INTEGER_TYPES,
4109        Type.BIT,
4110    }
4111
4112    FLOAT_TYPES = {
4113        Type.DOUBLE,
4114        Type.FLOAT,
4115    }
4116
4117    REAL_TYPES = {
4118        *FLOAT_TYPES,
4119        Type.BIGDECIMAL,
4120        Type.DECIMAL,
4121        Type.MONEY,
4122        Type.SMALLMONEY,
4123        Type.UDECIMAL,
4124    }
4125
4126    NUMERIC_TYPES = {
4127        *INTEGER_TYPES,
4128        *REAL_TYPES,
4129    }
4130
4131    TEMPORAL_TYPES = {
4132        Type.DATE,
4133        Type.DATE32,
4134        Type.DATETIME,
4135        Type.DATETIME64,
4136        Type.TIME,
4137        Type.TIMESTAMP,
4138        Type.TIMESTAMPNTZ,
4139        Type.TIMESTAMPLTZ,
4140        Type.TIMESTAMPTZ,
4141        Type.TIMESTAMP_MS,
4142        Type.TIMESTAMP_NS,
4143        Type.TIMESTAMP_S,
4144        Type.TIMETZ,
4145    }
4146
4147    @classmethod
4148    def build(
4149        cls,
4150        dtype: DATA_TYPE,
4151        dialect: DialectType = None,
4152        udt: bool = False,
4153        copy: bool = True,
4154        **kwargs,
4155    ) -> DataType:
4156        """
4157        Constructs a DataType object.
4158
4159        Args:
4160            dtype: the data type of interest.
4161            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4162            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4163                DataType, thus creating a user-defined type.
4164            copy: whether to copy the data type.
4165            kwargs: additional arguments to pass in the constructor of DataType.
4166
4167        Returns:
4168            The constructed DataType object.
4169        """
4170        from sqlglot import parse_one
4171
4172        if isinstance(dtype, str):
4173            if dtype.upper() == "UNKNOWN":
4174                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4175
4176            try:
4177                data_type_exp = parse_one(
4178                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4179                )
4180            except ParseError:
4181                if udt:
4182                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4183                raise
4184        elif isinstance(dtype, DataType.Type):
4185            data_type_exp = DataType(this=dtype)
4186        elif isinstance(dtype, DataType):
4187            return maybe_copy(dtype, copy)
4188        else:
4189            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4190
4191        return DataType(**{**data_type_exp.args, **kwargs})
4192
4193    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4194        """
4195        Checks whether this DataType matches one of the provided data types. Nested types or precision
4196        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4197
4198        Args:
4199            dtypes: the data types to compare this DataType to.
4200
4201        Returns:
4202            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4203        """
4204        for dtype in dtypes:
4205            other = DataType.build(dtype, copy=False, udt=True)
4206
4207            if (
4208                other.expressions
4209                or self.this == DataType.Type.USERDEFINED
4210                or other.this == DataType.Type.USERDEFINED
4211            ):
4212                matches = self == other
4213            else:
4214                matches = self.this == other.this
4215
4216            if matches:
4217                return True
4218        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False}
STRUCT_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>}
NESTED_TYPES = {<Type.MAP: 'MAP'>, <Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>, <Type.ARRAY: 'ARRAY'>}
TEXT_TYPES = {<Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.NAME: 'NAME'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NCHAR: 'NCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.TINYINT: 'TINYINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.USMALLINT: 'USMALLINT'>, <Type.UINT: 'UINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT128: 'UINT128'>, <Type.UTINYINT: 'UTINYINT'>}
INTEGER_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT128: 'UINT128'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT256: 'UINT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UTINYINT: 'UTINYINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.MONEY: 'MONEY'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>}
NUMERIC_TYPES = {<Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT: 'UINT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.BIGINT: 'BIGINT'>, <Type.INT: 'INT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT256: 'INT256'>, <Type.BIT: 'BIT'>, <Type.FLOAT: 'FLOAT'>, <Type.INT128: 'INT128'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.MONEY: 'MONEY'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.UINT256: 'UINT256'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.UINT128: 'UINT128'>}
TEMPORAL_TYPES = {<Type.TIME: 'TIME'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME64: 'DATETIME64'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4147    @classmethod
4148    def build(
4149        cls,
4150        dtype: DATA_TYPE,
4151        dialect: DialectType = None,
4152        udt: bool = False,
4153        copy: bool = True,
4154        **kwargs,
4155    ) -> DataType:
4156        """
4157        Constructs a DataType object.
4158
4159        Args:
4160            dtype: the data type of interest.
4161            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4162            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4163                DataType, thus creating a user-defined type.
4164            copy: whether to copy the data type.
4165            kwargs: additional arguments to pass in the constructor of DataType.
4166
4167        Returns:
4168            The constructed DataType object.
4169        """
4170        from sqlglot import parse_one
4171
4172        if isinstance(dtype, str):
4173            if dtype.upper() == "UNKNOWN":
4174                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4175
4176            try:
4177                data_type_exp = parse_one(
4178                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4179                )
4180            except ParseError:
4181                if udt:
4182                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4183                raise
4184        elif isinstance(dtype, DataType.Type):
4185            data_type_exp = DataType(this=dtype)
4186        elif isinstance(dtype, DataType):
4187            return maybe_copy(dtype, copy)
4188        else:
4189            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4190
4191        return DataType(**{**data_type_exp.args, **kwargs})

Constructs a DataType object.

Arguments:
  • dtype: the data type of interest.
  • dialect: the dialect to use for parsing dtype, in case it's a string.
  • udt: when set to True, dtype will be used as-is if it can't be parsed into a DataType, thus creating a user-defined type.
  • copy: whether to copy the data type.
  • kwargs: additional arguments to pass in the constructor of DataType.
Returns:

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
4193    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4194        """
4195        Checks whether this DataType matches one of the provided data types. Nested types or precision
4196        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4197
4198        Args:
4199            dtypes: the data types to compare this DataType to.
4200
4201        Returns:
4202            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4203        """
4204        for dtype in dtypes:
4205            other = DataType.build(dtype, copy=False, udt=True)
4206
4207            if (
4208                other.expressions
4209                or self.this == DataType.Type.USERDEFINED
4210                or other.this == DataType.Type.USERDEFINED
4211            ):
4212                matches = self == other
4213            else:
4214                matches = self.this == other.this
4215
4216            if matches:
4217                return True
4218        return False

Checks whether this DataType matches one of the provided data types. Nested types or precision will be compared using "structural equivalence" semantics, so e.g. array != array.

Arguments:
  • dtypes: the data types to compare this DataType to.
Returns:

True, if and only if there is a type in dtypes which is equal to this DataType.

key = 'datatype'
class DataType.Type(sqlglot.helper.AutoName):
3957    class Type(AutoName):
3958        ARRAY = auto()
3959        AGGREGATEFUNCTION = auto()
3960        SIMPLEAGGREGATEFUNCTION = auto()
3961        BIGDECIMAL = auto()
3962        BIGINT = auto()
3963        BIGSERIAL = auto()
3964        BINARY = auto()
3965        BIT = auto()
3966        BOOLEAN = auto()
3967        BPCHAR = auto()
3968        CHAR = auto()
3969        DATE = auto()
3970        DATE32 = auto()
3971        DATEMULTIRANGE = auto()
3972        DATERANGE = auto()
3973        DATETIME = auto()
3974        DATETIME64 = auto()
3975        DECIMAL = auto()
3976        DOUBLE = auto()
3977        ENUM = auto()
3978        ENUM8 = auto()
3979        ENUM16 = auto()
3980        FIXEDSTRING = auto()
3981        FLOAT = auto()
3982        GEOGRAPHY = auto()
3983        GEOMETRY = auto()
3984        HLLSKETCH = auto()
3985        HSTORE = auto()
3986        IMAGE = auto()
3987        INET = auto()
3988        INT = auto()
3989        INT128 = auto()
3990        INT256 = auto()
3991        INT4MULTIRANGE = auto()
3992        INT4RANGE = auto()
3993        INT8MULTIRANGE = auto()
3994        INT8RANGE = auto()
3995        INTERVAL = auto()
3996        IPADDRESS = auto()
3997        IPPREFIX = auto()
3998        IPV4 = auto()
3999        IPV6 = auto()
4000        JSON = auto()
4001        JSONB = auto()
4002        LIST = auto()
4003        LONGBLOB = auto()
4004        LONGTEXT = auto()
4005        LOWCARDINALITY = auto()
4006        MAP = auto()
4007        MEDIUMBLOB = auto()
4008        MEDIUMINT = auto()
4009        MEDIUMTEXT = auto()
4010        MONEY = auto()
4011        NAME = auto()
4012        NCHAR = auto()
4013        NESTED = auto()
4014        NULL = auto()
4015        NULLABLE = auto()
4016        NUMMULTIRANGE = auto()
4017        NUMRANGE = auto()
4018        NVARCHAR = auto()
4019        OBJECT = auto()
4020        ROWVERSION = auto()
4021        SERIAL = auto()
4022        SET = auto()
4023        SMALLINT = auto()
4024        SMALLMONEY = auto()
4025        SMALLSERIAL = auto()
4026        STRUCT = auto()
4027        SUPER = auto()
4028        TEXT = auto()
4029        TINYBLOB = auto()
4030        TINYTEXT = auto()
4031        TIME = auto()
4032        TIMETZ = auto()
4033        TIMESTAMP = auto()
4034        TIMESTAMPNTZ = auto()
4035        TIMESTAMPLTZ = auto()
4036        TIMESTAMPTZ = auto()
4037        TIMESTAMP_S = auto()
4038        TIMESTAMP_MS = auto()
4039        TIMESTAMP_NS = auto()
4040        TINYINT = auto()
4041        TSMULTIRANGE = auto()
4042        TSRANGE = auto()
4043        TSTZMULTIRANGE = auto()
4044        TSTZRANGE = auto()
4045        UBIGINT = auto()
4046        UINT = auto()
4047        UINT128 = auto()
4048        UINT256 = auto()
4049        UMEDIUMINT = auto()
4050        UDECIMAL = auto()
4051        UNIQUEIDENTIFIER = auto()
4052        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4053        USERDEFINED = "USER-DEFINED"
4054        USMALLINT = auto()
4055        UTINYINT = auto()
4056        UUID = auto()
4057        VARBINARY = auto()
4058        VARCHAR = auto()
4059        VARIANT = auto()
4060        VECTOR = auto()
4061        XML = auto()
4062        YEAR = auto()
4063        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):
4225class PseudoType(DataType):
4226    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4230class ObjectIdentifier(DataType):
4231    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4235class SubqueryPredicate(Predicate):
4236    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4239class All(SubqueryPredicate):
4240    pass
key = 'all'
class Any(SubqueryPredicate):
4243class Any(SubqueryPredicate):
4244    pass
key = 'any'
class Exists(SubqueryPredicate):
4247class Exists(SubqueryPredicate):
4248    pass
key = 'exists'
class Command(Expression):
4253class Command(Expression):
4254    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4257class Transaction(Expression):
4258    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4261class Commit(Expression):
4262    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4265class Rollback(Expression):
4266    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class AlterTable(Expression):
4269class AlterTable(Expression):
4270    arg_types = {
4271        "this": True,
4272        "actions": True,
4273        "exists": False,
4274        "only": False,
4275        "options": False,
4276        "cluster": False,
4277    }
arg_types = {'this': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False}
key = 'altertable'
class AddConstraint(Expression):
4280class AddConstraint(Expression):
4281    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4284class DropPartition(Expression):
4285    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4289class ReplacePartition(Expression):
4290    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4294class Binary(Condition):
4295    arg_types = {"this": True, "expression": True}
4296
4297    @property
4298    def left(self) -> Expression:
4299        return self.this
4300
4301    @property
4302    def right(self) -> Expression:
4303        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4297    @property
4298    def left(self) -> Expression:
4299        return self.this
right: Expression
4301    @property
4302    def right(self) -> Expression:
4303        return self.expression
key = 'binary'
class Add(Binary):
4306class Add(Binary):
4307    pass
key = 'add'
class Connector(Binary):
4310class Connector(Binary):
4311    pass
key = 'connector'
class And(Connector):
4314class And(Connector):
4315    pass
key = 'and'
class Or(Connector):
4318class Or(Connector):
4319    pass
key = 'or'
class BitwiseAnd(Binary):
4322class BitwiseAnd(Binary):
4323    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4326class BitwiseLeftShift(Binary):
4327    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4330class BitwiseOr(Binary):
4331    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4334class BitwiseRightShift(Binary):
4335    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4338class BitwiseXor(Binary):
4339    pass
key = 'bitwisexor'
class Div(Binary):
4342class Div(Binary):
4343    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):
4346class Overlaps(Binary):
4347    pass
key = 'overlaps'
class Dot(Binary):
4350class Dot(Binary):
4351    @property
4352    def is_star(self) -> bool:
4353        return self.expression.is_star
4354
4355    @property
4356    def name(self) -> str:
4357        return self.expression.name
4358
4359    @property
4360    def output_name(self) -> str:
4361        return self.name
4362
4363    @classmethod
4364    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4365        """Build a Dot object with a sequence of expressions."""
4366        if len(expressions) < 2:
4367            raise ValueError("Dot requires >= 2 expressions.")
4368
4369        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4370
4371    @property
4372    def parts(self) -> t.List[Expression]:
4373        """Return the parts of a table / column in order catalog, db, table."""
4374        this, *parts = self.flatten()
4375
4376        parts.reverse()
4377
4378        for arg in COLUMN_PARTS:
4379            part = this.args.get(arg)
4380
4381            if isinstance(part, Expression):
4382                parts.append(part)
4383
4384        parts.reverse()
4385        return parts
is_star: bool
4351    @property
4352    def is_star(self) -> bool:
4353        return self.expression.is_star

Checks whether an expression is a star.

name: str
4355    @property
4356    def name(self) -> str:
4357        return self.expression.name
output_name: str
4359    @property
4360    def output_name(self) -> str:
4361        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:
4363    @classmethod
4364    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4365        """Build a Dot object with a sequence of expressions."""
4366        if len(expressions) < 2:
4367            raise ValueError("Dot requires >= 2 expressions.")
4368
4369        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]
4371    @property
4372    def parts(self) -> t.List[Expression]:
4373        """Return the parts of a table / column in order catalog, db, table."""
4374        this, *parts = self.flatten()
4375
4376        parts.reverse()
4377
4378        for arg in COLUMN_PARTS:
4379            part = this.args.get(arg)
4380
4381            if isinstance(part, Expression):
4382                parts.append(part)
4383
4384        parts.reverse()
4385        return parts

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

key = 'dot'
class DPipe(Binary):
4388class DPipe(Binary):
4389    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4392class EQ(Binary, Predicate):
4393    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4396class NullSafeEQ(Binary, Predicate):
4397    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4400class NullSafeNEQ(Binary, Predicate):
4401    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4405class PropertyEQ(Binary):
4406    pass
key = 'propertyeq'
class Distance(Binary):
4409class Distance(Binary):
4410    pass
key = 'distance'
class Escape(Binary):
4413class Escape(Binary):
4414    pass
key = 'escape'
class Glob(Binary, Predicate):
4417class Glob(Binary, Predicate):
4418    pass
key = 'glob'
class GT(Binary, Predicate):
4421class GT(Binary, Predicate):
4422    pass
key = 'gt'
class GTE(Binary, Predicate):
4425class GTE(Binary, Predicate):
4426    pass
key = 'gte'
class ILike(Binary, Predicate):
4429class ILike(Binary, Predicate):
4430    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4433class ILikeAny(Binary, Predicate):
4434    pass
key = 'ilikeany'
class IntDiv(Binary):
4437class IntDiv(Binary):
4438    pass
key = 'intdiv'
class Is(Binary, Predicate):
4441class Is(Binary, Predicate):
4442    pass
key = 'is'
class Kwarg(Binary):
4445class Kwarg(Binary):
4446    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4449class Like(Binary, Predicate):
4450    pass
key = 'like'
class LikeAny(Binary, Predicate):
4453class LikeAny(Binary, Predicate):
4454    pass
key = 'likeany'
class LT(Binary, Predicate):
4457class LT(Binary, Predicate):
4458    pass
key = 'lt'
class LTE(Binary, Predicate):
4461class LTE(Binary, Predicate):
4462    pass
key = 'lte'
class Mod(Binary):
4465class Mod(Binary):
4466    pass
key = 'mod'
class Mul(Binary):
4469class Mul(Binary):
4470    pass
key = 'mul'
class NEQ(Binary, Predicate):
4473class NEQ(Binary, Predicate):
4474    pass
key = 'neq'
class Operator(Binary):
4478class Operator(Binary):
4479    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4482class SimilarTo(Binary, Predicate):
4483    pass
key = 'similarto'
class Slice(Binary):
4486class Slice(Binary):
4487    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4490class Sub(Binary):
4491    pass
key = 'sub'
class Unary(Condition):
4496class Unary(Condition):
4497    pass
key = 'unary'
class BitwiseNot(Unary):
4500class BitwiseNot(Unary):
4501    pass
key = 'bitwisenot'
class Not(Unary):
4504class Not(Unary):
4505    pass
key = 'not'
class Paren(Unary):
4508class Paren(Unary):
4509    @property
4510    def output_name(self) -> str:
4511        return self.this.name
output_name: str
4509    @property
4510    def output_name(self) -> str:
4511        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):
4514class Neg(Unary):
4515    def to_py(self) -> int | Decimal:
4516        if self.is_number:
4517            return self.this.to_py() * -1
4518        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4515    def to_py(self) -> int | Decimal:
4516        if self.is_number:
4517            return self.this.to_py() * -1
4518        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4521class Alias(Expression):
4522    arg_types = {"this": True, "alias": False}
4523
4524    @property
4525    def output_name(self) -> str:
4526        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4524    @property
4525    def output_name(self) -> str:
4526        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):
4531class PivotAlias(Alias):
4532    pass
key = 'pivotalias'
class Aliases(Expression):
4535class Aliases(Expression):
4536    arg_types = {"this": True, "expressions": True}
4537
4538    @property
4539    def aliases(self):
4540        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4538    @property
4539    def aliases(self):
4540        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4544class AtIndex(Expression):
4545    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4548class AtTimeZone(Expression):
4549    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4552class FromTimeZone(Expression):
4553    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4556class Between(Predicate):
4557    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4560class Bracket(Condition):
4561    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4562    arg_types = {
4563        "this": True,
4564        "expressions": True,
4565        "offset": False,
4566        "safe": False,
4567        "returns_list_for_maps": False,
4568    }
4569
4570    @property
4571    def output_name(self) -> str:
4572        if len(self.expressions) == 1:
4573            return self.expressions[0].output_name
4574
4575        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4570    @property
4571    def output_name(self) -> str:
4572        if len(self.expressions) == 1:
4573            return self.expressions[0].output_name
4574
4575        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):
4578class Distinct(Expression):
4579    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4582class In(Predicate):
4583    arg_types = {
4584        "this": True,
4585        "expressions": False,
4586        "query": False,
4587        "unnest": False,
4588        "field": False,
4589        "is_global": False,
4590    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4594class ForIn(Expression):
4595    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4598class TimeUnit(Expression):
4599    """Automatically converts unit arg into a var."""
4600
4601    arg_types = {"unit": False}
4602
4603    UNABBREVIATED_UNIT_NAME = {
4604        "D": "DAY",
4605        "H": "HOUR",
4606        "M": "MINUTE",
4607        "MS": "MILLISECOND",
4608        "NS": "NANOSECOND",
4609        "Q": "QUARTER",
4610        "S": "SECOND",
4611        "US": "MICROSECOND",
4612        "W": "WEEK",
4613        "Y": "YEAR",
4614    }
4615
4616    VAR_LIKE = (Column, Literal, Var)
4617
4618    def __init__(self, **args):
4619        unit = args.get("unit")
4620        if isinstance(unit, self.VAR_LIKE):
4621            args["unit"] = Var(
4622                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4623            )
4624        elif isinstance(unit, Week):
4625            unit.set("this", Var(this=unit.this.name.upper()))
4626
4627        super().__init__(**args)
4628
4629    @property
4630    def unit(self) -> t.Optional[Var | IntervalSpan]:
4631        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4618    def __init__(self, **args):
4619        unit = args.get("unit")
4620        if isinstance(unit, self.VAR_LIKE):
4621            args["unit"] = Var(
4622                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4623            )
4624        elif isinstance(unit, Week):
4625            unit.set("this", Var(this=unit.this.name.upper()))
4626
4627        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]
4629    @property
4630    def unit(self) -> t.Optional[Var | IntervalSpan]:
4631        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4634class IntervalOp(TimeUnit):
4635    arg_types = {"unit": True, "expression": True}
4636
4637    def interval(self):
4638        return Interval(
4639            this=self.expression.copy(),
4640            unit=self.unit.copy(),
4641        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4637    def interval(self):
4638        return Interval(
4639            this=self.expression.copy(),
4640            unit=self.unit.copy(),
4641        )
key = 'intervalop'
class IntervalSpan(DataType):
4647class IntervalSpan(DataType):
4648    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4651class Interval(TimeUnit):
4652    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4655class IgnoreNulls(Expression):
4656    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4659class RespectNulls(Expression):
4660    pass
key = 'respectnulls'
class HavingMax(Expression):
4664class HavingMax(Expression):
4665    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4669class Func(Condition):
4670    """
4671    The base class for all function expressions.
4672
4673    Attributes:
4674        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4675            treated as a variable length argument and the argument's value will be stored as a list.
4676        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4677            function expression. These values are used to map this node to a name during parsing as
4678            well as to provide the function's name during SQL string generation. By default the SQL
4679            name is set to the expression's class name transformed to snake case.
4680    """
4681
4682    is_var_len_args = False
4683
4684    @classmethod
4685    def from_arg_list(cls, args):
4686        if cls.is_var_len_args:
4687            all_arg_keys = list(cls.arg_types)
4688            # If this function supports variable length argument treat the last argument as such.
4689            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4690            num_non_var = len(non_var_len_arg_keys)
4691
4692            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4693            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4694        else:
4695            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4696
4697        return cls(**args_dict)
4698
4699    @classmethod
4700    def sql_names(cls):
4701        if cls is Func:
4702            raise NotImplementedError(
4703                "SQL name is only supported by concrete function implementations"
4704            )
4705        if "_sql_names" not in cls.__dict__:
4706            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4707        return cls._sql_names
4708
4709    @classmethod
4710    def sql_name(cls):
4711        return cls.sql_names()[0]
4712
4713    @classmethod
4714    def default_parser_mappings(cls):
4715        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):
4684    @classmethod
4685    def from_arg_list(cls, args):
4686        if cls.is_var_len_args:
4687            all_arg_keys = list(cls.arg_types)
4688            # If this function supports variable length argument treat the last argument as such.
4689            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4690            num_non_var = len(non_var_len_arg_keys)
4691
4692            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4693            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4694        else:
4695            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4696
4697        return cls(**args_dict)
@classmethod
def sql_names(cls):
4699    @classmethod
4700    def sql_names(cls):
4701        if cls is Func:
4702            raise NotImplementedError(
4703                "SQL name is only supported by concrete function implementations"
4704            )
4705        if "_sql_names" not in cls.__dict__:
4706            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4707        return cls._sql_names
@classmethod
def sql_name(cls):
4709    @classmethod
4710    def sql_name(cls):
4711        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4713    @classmethod
4714    def default_parser_mappings(cls):
4715        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4718class AggFunc(Func):
4719    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4722class ParameterizedAgg(AggFunc):
4723    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4726class Abs(Func):
4727    pass
key = 'abs'
class ArgMax(AggFunc):
4730class ArgMax(AggFunc):
4731    arg_types = {"this": True, "expression": True, "count": False}
4732    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4735class ArgMin(AggFunc):
4736    arg_types = {"this": True, "expression": True, "count": False}
4737    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4740class ApproxTopK(AggFunc):
4741    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4744class Flatten(Func):
4745    pass
key = 'flatten'
class Transform(Func):
4749class Transform(Func):
4750    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4753class Anonymous(Func):
4754    arg_types = {"this": True, "expressions": False}
4755    is_var_len_args = True
4756
4757    @property
4758    def name(self) -> str:
4759        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
4757    @property
4758    def name(self) -> str:
4759        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4762class AnonymousAggFunc(AggFunc):
4763    arg_types = {"this": True, "expressions": False}
4764    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4768class CombinedAggFunc(AnonymousAggFunc):
4769    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4772class CombinedParameterizedAgg(ParameterizedAgg):
4773    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):
4778class Hll(AggFunc):
4779    arg_types = {"this": True, "expressions": False}
4780    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4783class ApproxDistinct(AggFunc):
4784    arg_types = {"this": True, "accuracy": False}
4785    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4788class Array(Func):
4789    arg_types = {"expressions": False}
4790    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4794class ToArray(Func):
4795    pass
key = 'toarray'
class List(Func):
4799class List(Func):
4800    arg_types = {"expressions": False}
4801    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4805class Pad(Func):
4806    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):
4811class ToChar(Func):
4812    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4817class ToNumber(Func):
4818    arg_types = {
4819        "this": True,
4820        "format": False,
4821        "nlsparam": False,
4822        "precision": False,
4823        "scale": False,
4824    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4828class Convert(Func):
4829    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class GenerateSeries(Func):
4832class GenerateSeries(Func):
4833    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
arg_types = {'start': True, 'end': True, 'step': False, 'is_end_exclusive': False}
key = 'generateseries'
class ArrayAgg(AggFunc):
4836class ArrayAgg(AggFunc):
4837    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4840class ArrayUniqueAgg(AggFunc):
4841    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4844class ArrayAll(Func):
4845    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4849class ArrayAny(Func):
4850    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4853class ArrayConcat(Func):
4854    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4855    arg_types = {"this": True, "expressions": False}
4856    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4859class ArrayConstructCompact(Func):
4860    arg_types = {"expressions": True}
4861    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4864class ArrayContains(Binary, Func):
4865    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4868class ArrayContainsAll(Binary, Func):
4869    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4872class ArrayFilter(Func):
4873    arg_types = {"this": True, "expression": True}
4874    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4877class ArrayToString(Func):
4878    arg_types = {"this": True, "expression": True, "null": False}
4879    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4882class StringToArray(Func):
4883    arg_types = {"this": True, "expression": True, "null": False}
4884    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4887class ArrayOverlaps(Binary, Func):
4888    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4891class ArraySize(Func):
4892    arg_types = {"this": True, "expression": False}
4893    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4896class ArraySort(Func):
4897    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4900class ArraySum(Func):
4901    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4904class ArrayUnionAgg(AggFunc):
4905    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4908class Avg(AggFunc):
4909    pass
key = 'avg'
class AnyValue(AggFunc):
4912class AnyValue(AggFunc):
4913    pass
key = 'anyvalue'
class Lag(AggFunc):
4916class Lag(AggFunc):
4917    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4920class Lead(AggFunc):
4921    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4926class First(AggFunc):
4927    pass
key = 'first'
class Last(AggFunc):
4930class Last(AggFunc):
4931    pass
key = 'last'
class FirstValue(AggFunc):
4934class FirstValue(AggFunc):
4935    pass
key = 'firstvalue'
class LastValue(AggFunc):
4938class LastValue(AggFunc):
4939    pass
key = 'lastvalue'
class NthValue(AggFunc):
4942class NthValue(AggFunc):
4943    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
4946class Case(Func):
4947    arg_types = {"this": False, "ifs": True, "default": False}
4948
4949    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4950        instance = maybe_copy(self, copy)
4951        instance.append(
4952            "ifs",
4953            If(
4954                this=maybe_parse(condition, copy=copy, **opts),
4955                true=maybe_parse(then, copy=copy, **opts),
4956            ),
4957        )
4958        return instance
4959
4960    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4961        instance = maybe_copy(self, copy)
4962        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4963        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:
4949    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
4950        instance = maybe_copy(self, copy)
4951        instance.append(
4952            "ifs",
4953            If(
4954                this=maybe_parse(condition, copy=copy, **opts),
4955                true=maybe_parse(then, copy=copy, **opts),
4956            ),
4957        )
4958        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
4960    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
4961        instance = maybe_copy(self, copy)
4962        instance.set("default", maybe_parse(condition, copy=copy, **opts))
4963        return instance
key = 'case'
class Cast(Func):
4966class Cast(Func):
4967    arg_types = {
4968        "this": True,
4969        "to": True,
4970        "format": False,
4971        "safe": False,
4972        "action": False,
4973    }
4974
4975    @property
4976    def name(self) -> str:
4977        return self.this.name
4978
4979    @property
4980    def to(self) -> DataType:
4981        return self.args["to"]
4982
4983    @property
4984    def output_name(self) -> str:
4985        return self.name
4986
4987    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4988        """
4989        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4990        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4991        array<int> != array<float>.
4992
4993        Args:
4994            dtypes: the data types to compare this Cast's DataType to.
4995
4996        Returns:
4997            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4998        """
4999        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
4975    @property
4976    def name(self) -> str:
4977        return self.this.name
to: DataType
4979    @property
4980    def to(self) -> DataType:
4981        return self.args["to"]
output_name: str
4983    @property
4984    def output_name(self) -> str:
4985        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:
4987    def is_type(self, *dtypes: DATA_TYPE) -> bool:
4988        """
4989        Checks whether this Cast's DataType matches one of the provided data types. Nested types
4990        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
4991        array<int> != array<float>.
4992
4993        Args:
4994            dtypes: the data types to compare this Cast's DataType to.
4995
4996        Returns:
4997            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
4998        """
4999        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):
5002class TryCast(Cast):
5003    pass
key = 'trycast'
class Try(Func):
5006class Try(Func):
5007    pass
key = 'try'
class CastToStrType(Func):
5010class CastToStrType(Func):
5011    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5014class Collate(Binary, Func):
5015    pass
key = 'collate'
class Ceil(Func):
5018class Ceil(Func):
5019    arg_types = {"this": True, "decimals": False}
5020    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5023class Coalesce(Func):
5024    arg_types = {"this": True, "expressions": False}
5025    is_var_len_args = True
5026    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5029class Chr(Func):
5030    arg_types = {"this": True, "charset": False, "expressions": False}
5031    is_var_len_args = True
5032    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5035class Concat(Func):
5036    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5037    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5040class ConcatWs(Concat):
5041    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5045class ConnectByRoot(Func):
5046    pass
key = 'connectbyroot'
class Count(AggFunc):
5049class Count(AggFunc):
5050    arg_types = {"this": False, "expressions": False}
5051    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5054class CountIf(AggFunc):
5055    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5059class Cbrt(Func):
5060    pass
key = 'cbrt'
class CurrentDate(Func):
5063class CurrentDate(Func):
5064    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5067class CurrentDatetime(Func):
5068    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5071class CurrentTime(Func):
5072    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5075class CurrentTimestamp(Func):
5076    arg_types = {"this": False, "transaction": False}
arg_types = {'this': False, 'transaction': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5079class CurrentUser(Func):
5080    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5083class DateAdd(Func, IntervalOp):
5084    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5087class DateSub(Func, IntervalOp):
5088    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5091class DateDiff(Func, TimeUnit):
5092    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5093    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5096class DateTrunc(Func):
5097    arg_types = {"unit": True, "this": True, "zone": False}
5098
5099    def __init__(self, **args):
5100        unit = args.get("unit")
5101        if isinstance(unit, TimeUnit.VAR_LIKE):
5102            args["unit"] = Literal.string(
5103                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5104            )
5105        elif isinstance(unit, Week):
5106            unit.set("this", Literal.string(unit.this.name.upper()))
5107
5108        super().__init__(**args)
5109
5110    @property
5111    def unit(self) -> Expression:
5112        return self.args["unit"]
DateTrunc(**args)
5099    def __init__(self, **args):
5100        unit = args.get("unit")
5101        if isinstance(unit, TimeUnit.VAR_LIKE):
5102            args["unit"] = Literal.string(
5103                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5104            )
5105        elif isinstance(unit, Week):
5106            unit.set("this", Literal.string(unit.this.name.upper()))
5107
5108        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5110    @property
5111    def unit(self) -> Expression:
5112        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5117class Datetime(Func):
5118    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5121class DatetimeAdd(Func, IntervalOp):
5122    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5125class DatetimeSub(Func, IntervalOp):
5126    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5129class DatetimeDiff(Func, TimeUnit):
5130    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5133class DatetimeTrunc(Func, TimeUnit):
5134    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5137class DayOfWeek(Func):
5138    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5141class DayOfMonth(Func):
5142    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5145class DayOfYear(Func):
5146    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5149class ToDays(Func):
5150    pass
key = 'todays'
class WeekOfYear(Func):
5153class WeekOfYear(Func):
5154    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5157class MonthsBetween(Func):
5158    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5161class LastDay(Func, TimeUnit):
5162    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5163    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5166class Extract(Func):
5167    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5170class Timestamp(Func):
5171    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5174class TimestampAdd(Func, TimeUnit):
5175    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5178class TimestampSub(Func, TimeUnit):
5179    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5182class TimestampDiff(Func, TimeUnit):
5183    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5184    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5187class TimestampTrunc(Func, TimeUnit):
5188    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5191class TimeAdd(Func, TimeUnit):
5192    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5195class TimeSub(Func, TimeUnit):
5196    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5199class TimeDiff(Func, TimeUnit):
5200    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5203class TimeTrunc(Func, TimeUnit):
5204    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5207class DateFromParts(Func):
5208    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5209    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5212class TimeFromParts(Func):
5213    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5214    arg_types = {
5215        "hour": True,
5216        "min": True,
5217        "sec": True,
5218        "nano": False,
5219        "fractions": False,
5220        "precision": False,
5221    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5224class DateStrToDate(Func):
5225    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5228class DateToDateStr(Func):
5229    pass
key = 'datetodatestr'
class DateToDi(Func):
5232class DateToDi(Func):
5233    pass
key = 'datetodi'
class Date(Func):
5237class Date(Func):
5238    arg_types = {"this": False, "zone": False, "expressions": False}
5239    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5242class Day(Func):
5243    pass
key = 'day'
class Decode(Func):
5246class Decode(Func):
5247    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5250class DiToDate(Func):
5251    pass
key = 'ditodate'
class Encode(Func):
5254class Encode(Func):
5255    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5258class Exp(Func):
5259    pass
key = 'exp'
class Explode(Func):
5263class Explode(Func):
5264    arg_types = {"this": True, "expressions": False}
5265    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5268class ExplodeOuter(Explode):
5269    pass
key = 'explodeouter'
class Posexplode(Explode):
5272class Posexplode(Explode):
5273    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5276class PosexplodeOuter(Posexplode, ExplodeOuter):
5277    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5280class Unnest(Func, UDTF):
5281    arg_types = {
5282        "expressions": True,
5283        "alias": False,
5284        "offset": False,
5285    }
5286
5287    @property
5288    def selects(self) -> t.List[Expression]:
5289        columns = super().selects
5290        offset = self.args.get("offset")
5291        if offset:
5292            columns = columns + [to_identifier("offset") if offset is True else offset]
5293        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False}
selects: List[Expression]
5287    @property
5288    def selects(self) -> t.List[Expression]:
5289        columns = super().selects
5290        offset = self.args.get("offset")
5291        if offset:
5292            columns = columns + [to_identifier("offset") if offset is True else offset]
5293        return columns
key = 'unnest'
class Floor(Func):
5296class Floor(Func):
5297    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5300class FromBase64(Func):
5301    pass
key = 'frombase64'
class ToBase64(Func):
5304class ToBase64(Func):
5305    pass
key = 'tobase64'
class GapFill(Func):
5308class GapFill(Func):
5309    arg_types = {
5310        "this": True,
5311        "ts_column": True,
5312        "bucket_width": True,
5313        "partitioning_columns": False,
5314        "value_columns": False,
5315        "origin": False,
5316        "ignore_nulls": False,
5317    }
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):
5320class GenerateDateArray(Func):
5321    arg_types = {"start": True, "end": True, "interval": False}
arg_types = {'start': True, 'end': True, 'interval': False}
key = 'generatedatearray'
class Greatest(Func):
5324class Greatest(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 = 'greatest'
class GroupConcat(AggFunc):
5329class GroupConcat(AggFunc):
5330    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5333class Hex(Func):
5334    pass
key = 'hex'
class LowerHex(Hex):
5337class LowerHex(Hex):
5338    pass
key = 'lowerhex'
class Xor(Connector, Func):
5341class Xor(Connector, Func):
5342    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5345class If(Func):
5346    arg_types = {"this": True, "true": True, "false": False}
5347    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5350class Nullif(Func):
5351    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5354class Initcap(Func):
5355    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5358class IsNan(Func):
5359    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5362class IsInf(Func):
5363    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5366class JSONPath(Expression):
5367    arg_types = {"expressions": True}
5368
5369    @property
5370    def output_name(self) -> str:
5371        last_segment = self.expressions[-1].this
5372        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5369    @property
5370    def output_name(self) -> str:
5371        last_segment = self.expressions[-1].this
5372        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):
5375class JSONPathPart(Expression):
5376    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5379class JSONPathFilter(JSONPathPart):
5380    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5383class JSONPathKey(JSONPathPart):
5384    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5387class JSONPathRecursive(JSONPathPart):
5388    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5391class JSONPathRoot(JSONPathPart):
5392    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5395class JSONPathScript(JSONPathPart):
5396    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5399class JSONPathSlice(JSONPathPart):
5400    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5403class JSONPathSelector(JSONPathPart):
5404    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5407class JSONPathSubscript(JSONPathPart):
5408    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5411class JSONPathUnion(JSONPathPart):
5412    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5415class JSONPathWildcard(JSONPathPart):
5416    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5419class FormatJson(Expression):
5420    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5423class JSONKeyValue(Expression):
5424    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5427class JSONObject(Func):
5428    arg_types = {
5429        "expressions": False,
5430        "null_handling": False,
5431        "unique_keys": False,
5432        "return_type": False,
5433        "encoding": False,
5434    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5437class JSONObjectAgg(AggFunc):
5438    arg_types = {
5439        "expressions": False,
5440        "null_handling": False,
5441        "unique_keys": False,
5442        "return_type": False,
5443        "encoding": False,
5444    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5448class JSONArray(Func):
5449    arg_types = {
5450        "expressions": True,
5451        "null_handling": False,
5452        "return_type": False,
5453        "strict": False,
5454    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5458class JSONArrayAgg(Func):
5459    arg_types = {
5460        "this": True,
5461        "order": False,
5462        "null_handling": False,
5463        "return_type": False,
5464        "strict": False,
5465    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5470class JSONColumnDef(Expression):
5471    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):
5474class JSONSchema(Expression):
5475    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5479class JSONTable(Func):
5480    arg_types = {
5481        "this": True,
5482        "schema": True,
5483        "path": False,
5484        "error_handling": False,
5485        "empty_handling": False,
5486    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5490class ObjectInsert(Func):
5491    arg_types = {
5492        "this": True,
5493        "key": True,
5494        "value": True,
5495        "update_flag": False,
5496    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5499class OpenJSONColumnDef(Expression):
5500    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):
5503class OpenJSON(Func):
5504    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5507class JSONBContains(Binary, Func):
5508    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5511class JSONExtract(Binary, Func):
5512    arg_types = {
5513        "this": True,
5514        "expression": True,
5515        "only_json_types": False,
5516        "expressions": False,
5517        "variant_extract": False,
5518    }
5519    _sql_names = ["JSON_EXTRACT"]
5520    is_var_len_args = True
5521
5522    @property
5523    def output_name(self) -> str:
5524        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
5522    @property
5523    def output_name(self) -> str:
5524        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):
5527class JSONExtractScalar(Binary, Func):
5528    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5529    _sql_names = ["JSON_EXTRACT_SCALAR"]
5530    is_var_len_args = True
5531
5532    @property
5533    def output_name(self) -> str:
5534        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
5532    @property
5533    def output_name(self) -> str:
5534        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):
5537class JSONBExtract(Binary, Func):
5538    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5541class JSONBExtractScalar(Binary, Func):
5542    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5545class JSONFormat(Func):
5546    arg_types = {"this": False, "options": False}
5547    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5551class JSONArrayContains(Binary, Predicate, Func):
5552    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5555class ParseJSON(Func):
5556    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5557    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5558    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5559    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5562class Least(Func):
5563    arg_types = {"this": True, "expressions": False}
5564    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5567class Left(Func):
5568    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5575class Length(Func):
5576    arg_types = {"this": True, "binary": False}
5577    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5580class Levenshtein(Func):
5581    arg_types = {
5582        "this": True,
5583        "expression": False,
5584        "ins_cost": False,
5585        "del_cost": False,
5586        "sub_cost": False,
5587    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5590class Ln(Func):
5591    pass
key = 'ln'
class Log(Func):
5594class Log(Func):
5595    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5598class LogicalOr(AggFunc):
5599    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5602class LogicalAnd(AggFunc):
5603    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5606class Lower(Func):
5607    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5610class Map(Func):
5611    arg_types = {"keys": False, "values": False}
5612
5613    @property
5614    def keys(self) -> t.List[Expression]:
5615        keys = self.args.get("keys")
5616        return keys.expressions if keys else []
5617
5618    @property
5619    def values(self) -> t.List[Expression]:
5620        values = self.args.get("values")
5621        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5613    @property
5614    def keys(self) -> t.List[Expression]:
5615        keys = self.args.get("keys")
5616        return keys.expressions if keys else []
values: List[Expression]
5618    @property
5619    def values(self) -> t.List[Expression]:
5620        values = self.args.get("values")
5621        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5625class ToMap(Func):
5626    pass
key = 'tomap'
class MapFromEntries(Func):
5629class MapFromEntries(Func):
5630    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5634class ScopeResolution(Expression):
5635    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class StarMap(Func):
5638class StarMap(Func):
5639    pass
key = 'starmap'
class VarMap(Func):
5642class VarMap(Func):
5643    arg_types = {"keys": True, "values": True}
5644    is_var_len_args = True
5645
5646    @property
5647    def keys(self) -> t.List[Expression]:
5648        return self.args["keys"].expressions
5649
5650    @property
5651    def values(self) -> t.List[Expression]:
5652        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5646    @property
5647    def keys(self) -> t.List[Expression]:
5648        return self.args["keys"].expressions
values: List[Expression]
5650    @property
5651    def values(self) -> t.List[Expression]:
5652        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5656class MatchAgainst(Func):
5657    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5660class Max(AggFunc):
5661    arg_types = {"this": True, "expressions": False}
5662    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5665class MD5(Func):
5666    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5670class MD5Digest(Func):
5671    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5674class Min(AggFunc):
5675    arg_types = {"this": True, "expressions": False}
5676    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5679class Month(Func):
5680    pass
key = 'month'
class AddMonths(Func):
5683class AddMonths(Func):
5684    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5687class Nvl2(Func):
5688    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5692class Predict(Func):
5693    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5696class Pow(Binary, Func):
5697    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5700class PercentileCont(AggFunc):
5701    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5704class PercentileDisc(AggFunc):
5705    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5708class Quantile(AggFunc):
5709    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5712class ApproxQuantile(Quantile):
5713    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):
5716class Quarter(Func):
5717    pass
key = 'quarter'
class Rand(Func):
5722class Rand(Func):
5723    _sql_names = ["RAND", "RANDOM"]
5724    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5727class Randn(Func):
5728    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5731class RangeN(Func):
5732    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5735class ReadCSV(Func):
5736    _sql_names = ["READ_CSV"]
5737    is_var_len_args = True
5738    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5741class Reduce(Func):
5742    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):
5745class RegexpExtract(Func):
5746    arg_types = {
5747        "this": True,
5748        "expression": True,
5749        "position": False,
5750        "occurrence": False,
5751        "parameters": False,
5752        "group": False,
5753    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5756class RegexpReplace(Func):
5757    arg_types = {
5758        "this": True,
5759        "expression": True,
5760        "replacement": False,
5761        "position": False,
5762        "occurrence": False,
5763        "modifiers": False,
5764    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5767class RegexpLike(Binary, Func):
5768    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5771class RegexpILike(Binary, Func):
5772    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5777class RegexpSplit(Func):
5778    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5781class Repeat(Func):
5782    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5787class Round(Func):
5788    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5791class RowNumber(Func):
5792    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5795class SafeDivide(Func):
5796    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5799class SHA(Func):
5800    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5803class SHA2(Func):
5804    _sql_names = ["SHA2"]
5805    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5808class Sign(Func):
5809    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5812class SortArray(Func):
5813    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5816class Split(Func):
5817    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5822class Substring(Func):
5823    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5826class StandardHash(Func):
5827    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5830class StartsWith(Func):
5831    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5832    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5835class StrPosition(Func):
5836    arg_types = {
5837        "this": True,
5838        "substr": True,
5839        "position": False,
5840        "instance": False,
5841    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5844class StrToDate(Func):
5845    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
5848class StrToTime(Func):
5849    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):
5854class StrToUnix(Func):
5855    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5860class StrToMap(Func):
5861    arg_types = {
5862        "this": True,
5863        "pair_delim": False,
5864        "key_value_delim": False,
5865        "duplicate_resolution_callback": False,
5866    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5869class NumberToStr(Func):
5870    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5873class FromBase(Func):
5874    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5877class Struct(Func):
5878    arg_types = {"expressions": False}
5879    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5882class StructExtract(Func):
5883    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5888class Stuff(Func):
5889    _sql_names = ["STUFF", "INSERT"]
5890    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):
5893class Sum(AggFunc):
5894    pass
key = 'sum'
class Sqrt(Func):
5897class Sqrt(Func):
5898    pass
key = 'sqrt'
class Stddev(AggFunc):
5901class Stddev(AggFunc):
5902    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
5905class StddevPop(AggFunc):
5906    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5909class StddevSamp(AggFunc):
5910    pass
key = 'stddevsamp'
class Time(Func):
5914class Time(Func):
5915    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
5918class TimeToStr(Func):
5919    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):
5922class TimeToTimeStr(Func):
5923    pass
key = 'timetotimestr'
class TimeToUnix(Func):
5926class TimeToUnix(Func):
5927    pass
key = 'timetounix'
class TimeStrToDate(Func):
5930class TimeStrToDate(Func):
5931    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
5934class TimeStrToTime(Func):
5935    pass
key = 'timestrtotime'
class TimeStrToUnix(Func):
5938class TimeStrToUnix(Func):
5939    pass
key = 'timestrtounix'
class Trim(Func):
5942class Trim(Func):
5943    arg_types = {
5944        "this": True,
5945        "expression": False,
5946        "position": False,
5947        "collation": False,
5948    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
5951class TsOrDsAdd(Func, TimeUnit):
5952    # return_type is used to correctly cast the arguments of this expression when transpiling it
5953    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
5954
5955    @property
5956    def return_type(self) -> DataType:
5957        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
5955    @property
5956    def return_type(self) -> DataType:
5957        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
5960class TsOrDsDiff(Func, TimeUnit):
5961    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
5964class TsOrDsToDateStr(Func):
5965    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
5968class TsOrDsToDate(Func):
5969    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
5972class TsOrDsToTime(Func):
5973    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
5976class TsOrDsToTimestamp(Func):
5977    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
5980class TsOrDiToDi(Func):
5981    pass
key = 'tsorditodi'
class Unhex(Func):
5984class Unhex(Func):
5985    pass
key = 'unhex'
class UnixDate(Func):
5989class UnixDate(Func):
5990    pass
key = 'unixdate'
class UnixToStr(Func):
5993class UnixToStr(Func):
5994    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
5999class UnixToTime(Func):
6000    arg_types = {
6001        "this": True,
6002        "scale": False,
6003        "zone": False,
6004        "hours": False,
6005        "minutes": False,
6006        "format": False,
6007    }
6008
6009    SECONDS = Literal.number(0)
6010    DECIS = Literal.number(1)
6011    CENTIS = Literal.number(2)
6012    MILLIS = Literal.number(3)
6013    DECIMILLIS = Literal.number(4)
6014    CENTIMILLIS = Literal.number(5)
6015    MICROS = Literal.number(6)
6016    DECIMICROS = Literal.number(7)
6017    CENTIMICROS = Literal.number(8)
6018    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):
6021class UnixToTimeStr(Func):
6022    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
6025class TimestampFromParts(Func):
6026    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6027    arg_types = {
6028        "year": True,
6029        "month": True,
6030        "day": True,
6031        "hour": True,
6032        "min": True,
6033        "sec": True,
6034        "nano": False,
6035        "zone": False,
6036        "milli": False,
6037    }
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):
6040class Upper(Func):
6041    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6044class Corr(Binary, AggFunc):
6045    pass
key = 'corr'
class Variance(AggFunc):
6048class Variance(AggFunc):
6049    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6052class VariancePop(AggFunc):
6053    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6056class CovarSamp(Binary, AggFunc):
6057    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6060class CovarPop(Binary, AggFunc):
6061    pass
key = 'covarpop'
class Week(Func):
6064class Week(Func):
6065    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6068class XMLTable(Func):
6069    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):
6072class Year(Func):
6073    pass
key = 'year'
class Use(Expression):
6076class Use(Expression):
6077    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6080class Merge(Expression):
6081    arg_types = {
6082        "this": True,
6083        "using": True,
6084        "on": True,
6085        "expressions": True,
6086        "with": False,
6087    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6090class When(Func):
6091    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):
6096class NextValueFor(Func):
6097    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6102class Semicolon(Expression):
6103    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class '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'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, '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:
6143def maybe_parse(
6144    sql_or_expression: ExpOrStr,
6145    *,
6146    into: t.Optional[IntoType] = None,
6147    dialect: DialectType = None,
6148    prefix: t.Optional[str] = None,
6149    copy: bool = False,
6150    **opts,
6151) -> Expression:
6152    """Gracefully handle a possible string or expression.
6153
6154    Example:
6155        >>> maybe_parse("1")
6156        Literal(this=1, is_string=False)
6157        >>> maybe_parse(to_identifier("x"))
6158        Identifier(this=x, quoted=False)
6159
6160    Args:
6161        sql_or_expression: the SQL code string or an expression
6162        into: the SQLGlot Expression to parse into
6163        dialect: the dialect used to parse the input expressions (in the case that an
6164            input expression is a SQL string).
6165        prefix: a string to prefix the sql with before it gets parsed
6166            (automatically includes a space)
6167        copy: whether to copy the expression.
6168        **opts: other options to use to parse the input expressions (again, in the case
6169            that an input expression is a SQL string).
6170
6171    Returns:
6172        Expression: the parsed or given expression.
6173    """
6174    if isinstance(sql_or_expression, Expression):
6175        if copy:
6176            return sql_or_expression.copy()
6177        return sql_or_expression
6178
6179    if sql_or_expression is None:
6180        raise ParseError("SQL cannot be None")
6181
6182    import sqlglot
6183
6184    sql = str(sql_or_expression)
6185    if prefix:
6186        sql = f"{prefix} {sql}"
6187
6188    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):
6199def maybe_copy(instance, copy=True):
6200    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:
6420def union(
6421    left: ExpOrStr,
6422    right: ExpOrStr,
6423    distinct: bool = True,
6424    dialect: DialectType = None,
6425    copy: bool = True,
6426    **opts,
6427) -> Union:
6428    """
6429    Initializes a syntax tree from one UNION expression.
6430
6431    Example:
6432        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6433        'SELECT * FROM foo UNION SELECT * FROM bla'
6434
6435    Args:
6436        left: the SQL code string corresponding to the left-hand side.
6437            If an `Expression` instance is passed, it will be used as-is.
6438        right: the SQL code string corresponding to the right-hand side.
6439            If an `Expression` instance is passed, it will be used as-is.
6440        distinct: set the DISTINCT flag if and only if this is true.
6441        dialect: the dialect used to parse the input expression.
6442        copy: whether to copy the expression.
6443        opts: other options to use to parse the input expressions.
6444
6445    Returns:
6446        The new Union instance.
6447    """
6448    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6449    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6450
6451    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:
6454def intersect(
6455    left: ExpOrStr,
6456    right: ExpOrStr,
6457    distinct: bool = True,
6458    dialect: DialectType = None,
6459    copy: bool = True,
6460    **opts,
6461) -> Intersect:
6462    """
6463    Initializes a syntax tree from one INTERSECT expression.
6464
6465    Example:
6466        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6467        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6468
6469    Args:
6470        left: the SQL code string corresponding to the left-hand side.
6471            If an `Expression` instance is passed, it will be used as-is.
6472        right: the SQL code string corresponding to the right-hand side.
6473            If an `Expression` instance is passed, it will be used as-is.
6474        distinct: set the DISTINCT flag if and only if this is true.
6475        dialect: the dialect used to parse the input expression.
6476        copy: whether to copy the expression.
6477        opts: other options to use to parse the input expressions.
6478
6479    Returns:
6480        The new Intersect instance.
6481    """
6482    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6483    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6484
6485    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:
6488def except_(
6489    left: ExpOrStr,
6490    right: ExpOrStr,
6491    distinct: bool = True,
6492    dialect: DialectType = None,
6493    copy: bool = True,
6494    **opts,
6495) -> Except:
6496    """
6497    Initializes a syntax tree from one EXCEPT expression.
6498
6499    Example:
6500        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6501        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6502
6503    Args:
6504        left: the SQL code string corresponding to the left-hand side.
6505            If an `Expression` instance is passed, it will be used as-is.
6506        right: the SQL code string corresponding to the right-hand side.
6507            If an `Expression` instance is passed, it will be used as-is.
6508        distinct: set the DISTINCT flag if and only if this is true.
6509        dialect: the dialect used to parse the input expression.
6510        copy: whether to copy the expression.
6511        opts: other options to use to parse the input expressions.
6512
6513    Returns:
6514        The new Except instance.
6515    """
6516    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6517    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6518
6519    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:
6522def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6523    """
6524    Initializes a syntax tree from one or multiple SELECT expressions.
6525
6526    Example:
6527        >>> select("col1", "col2").from_("tbl").sql()
6528        'SELECT col1, col2 FROM tbl'
6529
6530    Args:
6531        *expressions: the SQL code string to parse as the expressions of a
6532            SELECT statement. If an Expression instance is passed, this is used as-is.
6533        dialect: the dialect used to parse the input expressions (in the case that an
6534            input expression is a SQL string).
6535        **opts: other options to use to parse the input expressions (again, in the case
6536            that an input expression is a SQL string).
6537
6538    Returns:
6539        Select: the syntax tree for the SELECT statement.
6540    """
6541    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:
6544def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6545    """
6546    Initializes a syntax tree from a FROM expression.
6547
6548    Example:
6549        >>> from_("tbl").select("col1", "col2").sql()
6550        'SELECT col1, col2 FROM tbl'
6551
6552    Args:
6553        *expression: the SQL code string to parse as the FROM expressions of a
6554            SELECT statement. If an Expression instance is passed, this is used as-is.
6555        dialect: the dialect used to parse the input expression (in the case that the
6556            input expression is a SQL string).
6557        **opts: other options to use to parse the input expressions (again, in the case
6558            that the input expression is a SQL string).
6559
6560    Returns:
6561        Select: the syntax tree for the SELECT statement.
6562    """
6563    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:
6566def update(
6567    table: str | Table,
6568    properties: dict,
6569    where: t.Optional[ExpOrStr] = None,
6570    from_: t.Optional[ExpOrStr] = None,
6571    dialect: DialectType = None,
6572    **opts,
6573) -> Update:
6574    """
6575    Creates an update statement.
6576
6577    Example:
6578        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6579        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6580
6581    Args:
6582        *properties: dictionary of properties to set which are
6583            auto converted to sql objects eg None -> NULL
6584        where: sql conditional parsed into a WHERE statement
6585        from_: sql statement parsed into a FROM statement
6586        dialect: the dialect used to parse the input expressions.
6587        **opts: other options to use to parse the input expressions.
6588
6589    Returns:
6590        Update: the syntax tree for the UPDATE statement.
6591    """
6592    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6593    update_expr.set(
6594        "expressions",
6595        [
6596            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6597            for k, v in properties.items()
6598        ],
6599    )
6600    if from_:
6601        update_expr.set(
6602            "from",
6603            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6604        )
6605    if isinstance(where, Condition):
6606        where = Where(this=where)
6607    if where:
6608        update_expr.set(
6609            "where",
6610            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6611        )
6612    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:
6615def delete(
6616    table: ExpOrStr,
6617    where: t.Optional[ExpOrStr] = None,
6618    returning: t.Optional[ExpOrStr] = None,
6619    dialect: DialectType = None,
6620    **opts,
6621) -> Delete:
6622    """
6623    Builds a delete statement.
6624
6625    Example:
6626        >>> delete("my_table", where="id > 1").sql()
6627        'DELETE FROM my_table WHERE id > 1'
6628
6629    Args:
6630        where: sql conditional parsed into a WHERE statement
6631        returning: sql conditional parsed into a RETURNING statement
6632        dialect: the dialect used to parse the input expressions.
6633        **opts: other options to use to parse the input expressions.
6634
6635    Returns:
6636        Delete: the syntax tree for the DELETE statement.
6637    """
6638    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6639    if where:
6640        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6641    if returning:
6642        delete_expr = t.cast(
6643            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6644        )
6645    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:
6648def insert(
6649    expression: ExpOrStr,
6650    into: ExpOrStr,
6651    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6652    overwrite: t.Optional[bool] = None,
6653    returning: t.Optional[ExpOrStr] = None,
6654    dialect: DialectType = None,
6655    copy: bool = True,
6656    **opts,
6657) -> Insert:
6658    """
6659    Builds an INSERT statement.
6660
6661    Example:
6662        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6663        'INSERT INTO tbl VALUES (1, 2, 3)'
6664
6665    Args:
6666        expression: the sql string or expression of the INSERT statement
6667        into: the tbl to insert data to.
6668        columns: optionally the table's column names.
6669        overwrite: whether to INSERT OVERWRITE or not.
6670        returning: sql conditional parsed into a RETURNING statement
6671        dialect: the dialect used to parse the input expressions.
6672        copy: whether to copy the expression.
6673        **opts: other options to use to parse the input expressions.
6674
6675    Returns:
6676        Insert: the syntax tree for the INSERT statement.
6677    """
6678    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6679    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6680
6681    if columns:
6682        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6683
6684    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6685
6686    if returning:
6687        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6688
6689    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:
6692def condition(
6693    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6694) -> Condition:
6695    """
6696    Initialize a logical condition expression.
6697
6698    Example:
6699        >>> condition("x=1").sql()
6700        'x = 1'
6701
6702        This is helpful for composing larger logical syntax trees:
6703        >>> where = condition("x=1")
6704        >>> where = where.and_("y=1")
6705        >>> Select().from_("tbl").select("*").where(where).sql()
6706        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6707
6708    Args:
6709        *expression: the SQL code string to parse.
6710            If an Expression instance is passed, this is used as-is.
6711        dialect: the dialect used to parse the input expression (in the case that the
6712            input expression is a SQL string).
6713        copy: Whether to copy `expression` (only applies to expressions).
6714        **opts: other options to use to parse the input expressions (again, in the case
6715            that the input expression is a SQL string).
6716
6717    Returns:
6718        The new Condition instance
6719    """
6720    return maybe_parse(
6721        expression,
6722        into=Condition,
6723        dialect=dialect,
6724        copy=copy,
6725        **opts,
6726    )

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:
6729def and_(
6730    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6731) -> Condition:
6732    """
6733    Combine multiple conditions with an AND logical operator.
6734
6735    Example:
6736        >>> and_("x=1", and_("y=1", "z=1")).sql()
6737        'x = 1 AND (y = 1 AND z = 1)'
6738
6739    Args:
6740        *expressions: the SQL code strings to parse.
6741            If an Expression instance is passed, this is used as-is.
6742        dialect: the dialect used to parse the input expression.
6743        copy: whether to copy `expressions` (only applies to Expressions).
6744        **opts: other options to use to parse the input expressions.
6745
6746    Returns:
6747        The new condition
6748    """
6749    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:
6752def or_(
6753    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6754) -> Condition:
6755    """
6756    Combine multiple conditions with an OR logical operator.
6757
6758    Example:
6759        >>> or_("x=1", or_("y=1", "z=1")).sql()
6760        'x = 1 OR (y = 1 OR z = 1)'
6761
6762    Args:
6763        *expressions: the SQL code strings to parse.
6764            If an Expression instance is passed, this is used as-is.
6765        dialect: the dialect used to parse the input expression.
6766        copy: whether to copy `expressions` (only applies to Expressions).
6767        **opts: other options to use to parse the input expressions.
6768
6769    Returns:
6770        The new condition
6771    """
6772    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:
6775def xor(
6776    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6777) -> Condition:
6778    """
6779    Combine multiple conditions with an XOR logical operator.
6780
6781    Example:
6782        >>> xor("x=1", xor("y=1", "z=1")).sql()
6783        'x = 1 XOR (y = 1 XOR z = 1)'
6784
6785    Args:
6786        *expressions: the SQL code strings to parse.
6787            If an Expression instance is passed, this is used as-is.
6788        dialect: the dialect used to parse the input expression.
6789        copy: whether to copy `expressions` (only applies to Expressions).
6790        **opts: other options to use to parse the input expressions.
6791
6792    Returns:
6793        The new condition
6794    """
6795    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:
6798def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6799    """
6800    Wrap a condition with a NOT operator.
6801
6802    Example:
6803        >>> not_("this_suit='black'").sql()
6804        "NOT this_suit = 'black'"
6805
6806    Args:
6807        expression: the SQL code string to parse.
6808            If an Expression instance is passed, this is used as-is.
6809        dialect: the dialect used to parse the input expression.
6810        copy: whether to copy the expression or not.
6811        **opts: other options to use to parse the input expressions.
6812
6813    Returns:
6814        The new condition.
6815    """
6816    this = condition(
6817        expression,
6818        dialect=dialect,
6819        copy=copy,
6820        **opts,
6821    )
6822    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:
6825def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6826    """
6827    Wrap an expression in parentheses.
6828
6829    Example:
6830        >>> paren("5 + 3").sql()
6831        '(5 + 3)'
6832
6833    Args:
6834        expression: the SQL code string to parse.
6835            If an Expression instance is passed, this is used as-is.
6836        copy: whether to copy the expression or not.
6837
6838    Returns:
6839        The wrapped expression.
6840    """
6841    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):
6857def to_identifier(name, quoted=None, copy=True):
6858    """Builds an identifier.
6859
6860    Args:
6861        name: The name to turn into an identifier.
6862        quoted: Whether to force quote the identifier.
6863        copy: Whether to copy name if it's an Identifier.
6864
6865    Returns:
6866        The identifier ast node.
6867    """
6868
6869    if name is None:
6870        return None
6871
6872    if isinstance(name, Identifier):
6873        identifier = maybe_copy(name, copy)
6874    elif isinstance(name, str):
6875        identifier = Identifier(
6876            this=name,
6877            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6878        )
6879    else:
6880        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6881    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:
6884def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6885    """
6886    Parses a given string into an identifier.
6887
6888    Args:
6889        name: The name to parse into an identifier.
6890        dialect: The dialect to parse against.
6891
6892    Returns:
6893        The identifier ast node.
6894    """
6895    try:
6896        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6897    except (ParseError, TokenError):
6898        expression = to_identifier(name)
6899
6900    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:
6906def to_interval(interval: str | Literal) -> Interval:
6907    """Builds an interval expression from a string like '1 day' or '5 months'."""
6908    if isinstance(interval, Literal):
6909        if not interval.is_string:
6910            raise ValueError("Invalid interval string.")
6911
6912        interval = interval.this
6913
6914    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6915
6916    if not interval_parts:
6917        raise ValueError("Invalid interval string.")
6918
6919    return Interval(
6920        this=Literal.string(interval_parts.group(1)),
6921        unit=Var(this=interval_parts.group(2).upper()),
6922    )

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:
6925def to_table(
6926    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
6927) -> Table:
6928    """
6929    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
6930    If a table is passed in then that table is returned.
6931
6932    Args:
6933        sql_path: a `[catalog].[schema].[table]` string.
6934        dialect: the source dialect according to which the table name will be parsed.
6935        copy: Whether to copy a table if it is passed in.
6936        kwargs: the kwargs to instantiate the resulting `Table` expression with.
6937
6938    Returns:
6939        A table expression.
6940    """
6941    if isinstance(sql_path, Table):
6942        return maybe_copy(sql_path, copy=copy)
6943
6944    table = maybe_parse(sql_path, into=Table, dialect=dialect)
6945
6946    for k, v in kwargs.items():
6947        table.set(k, v)
6948
6949    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:
6952def to_column(
6953    sql_path: str | Column,
6954    quoted: t.Optional[bool] = None,
6955    dialect: DialectType = None,
6956    copy: bool = True,
6957    **kwargs,
6958) -> Column:
6959    """
6960    Create a column from a `[table].[column]` sql path. Table is optional.
6961    If a column is passed in then that column is returned.
6962
6963    Args:
6964        sql_path: a `[table].[column]` string.
6965        quoted: Whether or not to force quote identifiers.
6966        dialect: the source dialect according to which the column name will be parsed.
6967        copy: Whether to copy a column if it is passed in.
6968        kwargs: the kwargs to instantiate the resulting `Column` expression with.
6969
6970    Returns:
6971        A column expression.
6972    """
6973    if isinstance(sql_path, Column):
6974        return maybe_copy(sql_path, copy=copy)
6975
6976    try:
6977        col = maybe_parse(sql_path, into=Column, dialect=dialect)
6978    except ParseError:
6979        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
6980
6981    for k, v in kwargs.items():
6982        col.set(k, v)
6983
6984    if quoted:
6985        for i in col.find_all(Identifier):
6986            i.set("quoted", True)
6987
6988    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):
6991def alias_(
6992    expression: ExpOrStr,
6993    alias: t.Optional[str | Identifier],
6994    table: bool | t.Sequence[str | Identifier] = False,
6995    quoted: t.Optional[bool] = None,
6996    dialect: DialectType = None,
6997    copy: bool = True,
6998    **opts,
6999):
7000    """Create an Alias expression.
7001
7002    Example:
7003        >>> alias_('foo', 'bar').sql()
7004        'foo AS bar'
7005
7006        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7007        '(SELECT 1, 2) AS bar(a, b)'
7008
7009    Args:
7010        expression: the SQL code strings to parse.
7011            If an Expression instance is passed, this is used as-is.
7012        alias: the alias name to use. If the name has
7013            special characters it is quoted.
7014        table: Whether to create a table alias, can also be a list of columns.
7015        quoted: whether to quote the alias
7016        dialect: the dialect used to parse the input expression.
7017        copy: Whether to copy the expression.
7018        **opts: other options to use to parse the input expressions.
7019
7020    Returns:
7021        Alias: the aliased expression
7022    """
7023    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7024    alias = to_identifier(alias, quoted=quoted)
7025
7026    if table:
7027        table_alias = TableAlias(this=alias)
7028        exp.set("alias", table_alias)
7029
7030        if not isinstance(table, bool):
7031            for column in table:
7032                table_alias.append("columns", to_identifier(column, quoted=quoted))
7033
7034        return exp
7035
7036    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7037    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7038    # for the complete Window expression.
7039    #
7040    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7041
7042    if "alias" in exp.arg_types and not isinstance(exp, Window):
7043        exp.set("alias", alias)
7044        return exp
7045    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:
7048def subquery(
7049    expression: ExpOrStr,
7050    alias: t.Optional[Identifier | str] = None,
7051    dialect: DialectType = None,
7052    **opts,
7053) -> Select:
7054    """
7055    Build a subquery expression that's selected from.
7056
7057    Example:
7058        >>> subquery('select x from tbl', 'bar').select('x').sql()
7059        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7060
7061    Args:
7062        expression: the SQL code strings to parse.
7063            If an Expression instance is passed, this is used as-is.
7064        alias: the alias name to use.
7065        dialect: the dialect used to parse the input expression.
7066        **opts: other options to use to parse the input expressions.
7067
7068    Returns:
7069        A new Select instance with the subquery expression included.
7070    """
7071
7072    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7073    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):
7104def column(
7105    col,
7106    table=None,
7107    db=None,
7108    catalog=None,
7109    *,
7110    fields=None,
7111    quoted=None,
7112    copy=True,
7113):
7114    """
7115    Build a Column.
7116
7117    Args:
7118        col: Column name.
7119        table: Table name.
7120        db: Database name.
7121        catalog: Catalog name.
7122        fields: Additional fields using dots.
7123        quoted: Whether to force quotes on the column's identifiers.
7124        copy: Whether to copy identifiers if passed in.
7125
7126    Returns:
7127        The new Column instance.
7128    """
7129    this = Column(
7130        this=to_identifier(col, quoted=quoted, copy=copy),
7131        table=to_identifier(table, quoted=quoted, copy=copy),
7132        db=to_identifier(db, quoted=quoted, copy=copy),
7133        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7134    )
7135
7136    if fields:
7137        this = Dot.build(
7138            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7139        )
7140    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:
7143def cast(expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, **opts) -> Cast:
7144    """Cast an expression to a data type.
7145
7146    Example:
7147        >>> cast('x + 1', 'int').sql()
7148        'CAST(x + 1 AS INT)'
7149
7150    Args:
7151        expression: The expression to cast.
7152        to: The datatype to cast to.
7153        copy: Whether to copy the supplied expressions.
7154
7155    Returns:
7156        The new Cast instance.
7157    """
7158    expr = maybe_parse(expression, copy=copy, **opts)
7159    data_type = DataType.build(to, copy=copy, **opts)
7160
7161    if expr.is_type(data_type):
7162        return expr
7163
7164    expr = Cast(this=expr, to=data_type)
7165    expr.type = data_type
7166
7167    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:
7170def table_(
7171    table: Identifier | str,
7172    db: t.Optional[Identifier | str] = None,
7173    catalog: t.Optional[Identifier | str] = None,
7174    quoted: t.Optional[bool] = None,
7175    alias: t.Optional[Identifier | str] = None,
7176) -> Table:
7177    """Build a Table.
7178
7179    Args:
7180        table: Table name.
7181        db: Database name.
7182        catalog: Catalog name.
7183        quote: Whether to force quotes on the table's identifiers.
7184        alias: Table's alias.
7185
7186    Returns:
7187        The new Table instance.
7188    """
7189    return Table(
7190        this=to_identifier(table, quoted=quoted) if table else None,
7191        db=to_identifier(db, quoted=quoted) if db else None,
7192        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7193        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7194    )

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:
7197def values(
7198    values: t.Iterable[t.Tuple[t.Any, ...]],
7199    alias: t.Optional[str] = None,
7200    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7201) -> Values:
7202    """Build VALUES statement.
7203
7204    Example:
7205        >>> values([(1, '2')]).sql()
7206        "VALUES (1, '2')"
7207
7208    Args:
7209        values: values statements that will be converted to SQL
7210        alias: optional alias
7211        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7212         If either are provided then an alias is also required.
7213
7214    Returns:
7215        Values: the Values expression object
7216    """
7217    if columns and not alias:
7218        raise ValueError("Alias is required when providing columns")
7219
7220    return Values(
7221        expressions=[convert(tup) for tup in values],
7222        alias=(
7223            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7224            if columns
7225            else (TableAlias(this=to_identifier(alias)) if alias else None)
7226        ),
7227    )

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:
7230def var(name: t.Optional[ExpOrStr]) -> Var:
7231    """Build a SQL variable.
7232
7233    Example:
7234        >>> repr(var('x'))
7235        'Var(this=x)'
7236
7237        >>> repr(var(column('x', table='y')))
7238        'Var(this=x)'
7239
7240    Args:
7241        name: The name of the var or an expression who's name will become the var.
7242
7243    Returns:
7244        The new variable node.
7245    """
7246    if not name:
7247        raise ValueError("Cannot convert empty name into var.")
7248
7249    if isinstance(name, Expression):
7250        name = name.name
7251    return Var(this=name)

Build a SQL variable.

Example:
>>> repr(var('x'))
'Var(this=x)'
>>> repr(var(column('x', table='y')))
'Var(this=x)'
Arguments:
  • name: The name of the var or an expression who's name will become the var.
Returns:

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
7254def rename_table(
7255    old_name: str | Table,
7256    new_name: str | Table,
7257    dialect: DialectType = None,
7258) -> AlterTable:
7259    """Build ALTER TABLE... RENAME... expression
7260
7261    Args:
7262        old_name: The old name of the table
7263        new_name: The new name of the table
7264        dialect: The dialect to parse the table.
7265
7266    Returns:
7267        Alter table expression
7268    """
7269    old_table = to_table(old_name, dialect=dialect)
7270    new_table = to_table(new_name, dialect=dialect)
7271    return AlterTable(
7272        this=old_table,
7273        actions=[
7274            RenameTable(this=new_table),
7275        ],
7276    )

Build ALTER TABLE... RENAME... expression

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

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> AlterTable:
7279def rename_column(
7280    table_name: str | Table,
7281    old_column_name: str | Column,
7282    new_column_name: str | Column,
7283    exists: t.Optional[bool] = None,
7284    dialect: DialectType = None,
7285) -> AlterTable:
7286    """Build ALTER TABLE... RENAME COLUMN... expression
7287
7288    Args:
7289        table_name: Name of the table
7290        old_column: The old name of the column
7291        new_column: The new name of the column
7292        exists: Whether to add the `IF EXISTS` clause
7293        dialect: The dialect to parse the table/column.
7294
7295    Returns:
7296        Alter table expression
7297    """
7298    table = to_table(table_name, dialect=dialect)
7299    old_column = to_column(old_column_name, dialect=dialect)
7300    new_column = to_column(new_column_name, dialect=dialect)
7301    return AlterTable(
7302        this=table,
7303        actions=[
7304            RenameColumn(this=old_column, to=new_column, exists=exists),
7305        ],
7306    )

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:
7309def convert(value: t.Any, copy: bool = False) -> Expression:
7310    """Convert a python value into an expression object.
7311
7312    Raises an error if a conversion is not possible.
7313
7314    Args:
7315        value: A python object.
7316        copy: Whether to copy `value` (only applies to Expressions and collections).
7317
7318    Returns:
7319        The equivalent expression object.
7320    """
7321    if isinstance(value, Expression):
7322        return maybe_copy(value, copy)
7323    if isinstance(value, str):
7324        return Literal.string(value)
7325    if isinstance(value, bool):
7326        return Boolean(this=value)
7327    if value is None or (isinstance(value, float) and math.isnan(value)):
7328        return null()
7329    if isinstance(value, numbers.Number):
7330        return Literal.number(value)
7331    if isinstance(value, bytes):
7332        return HexString(this=value.hex())
7333    if isinstance(value, datetime.datetime):
7334        datetime_literal = Literal.string(
7335            (value if value.tzinfo else value.replace(tzinfo=datetime.timezone.utc)).isoformat(
7336                sep=" "
7337            )
7338        )
7339        return TimeStrToTime(this=datetime_literal)
7340    if isinstance(value, datetime.date):
7341        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7342        return DateStrToDate(this=date_literal)
7343    if isinstance(value, tuple):
7344        if hasattr(value, "_fields"):
7345            return Struct(
7346                expressions=[
7347                    PropertyEQ(
7348                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7349                    )
7350                    for k in value._fields
7351                ]
7352            )
7353        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7354    if isinstance(value, list):
7355        return Array(expressions=[convert(v, copy=copy) for v in value])
7356    if isinstance(value, dict):
7357        return Map(
7358            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7359            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7360        )
7361    if hasattr(value, "__dict__"):
7362        return Struct(
7363            expressions=[
7364                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7365                for k, v in value.__dict__.items()
7366            ]
7367        )
7368    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:
7371def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7372    """
7373    Replace children of an expression with the result of a lambda fun(child) -> exp.
7374    """
7375    for k, v in tuple(expression.args.items()):
7376        is_list_arg = type(v) is list
7377
7378        child_nodes = v if is_list_arg else [v]
7379        new_child_nodes = []
7380
7381        for cn in child_nodes:
7382            if isinstance(cn, Expression):
7383                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7384                    new_child_nodes.append(child_node)
7385            else:
7386                new_child_nodes.append(cn)
7387
7388        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:
7391def replace_tree(
7392    expression: Expression,
7393    fun: t.Callable,
7394    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7395) -> Expression:
7396    """
7397    Replace an entire tree with the result of function calls on each node.
7398
7399    This will be traversed in reverse dfs, so leaves first.
7400    If new nodes are created as a result of function calls, they will also be traversed.
7401    """
7402    stack = list(expression.dfs(prune=prune))
7403
7404    while stack:
7405        node = stack.pop()
7406        new_node = fun(node)
7407
7408        if new_node is not node:
7409            node.replace(new_node)
7410
7411            if isinstance(new_node, Expression):
7412                stack.append(new_node)
7413
7414    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]:
7417def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7418    """
7419    Return all table names referenced through columns in an expression.
7420
7421    Example:
7422        >>> import sqlglot
7423        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7424        ['a', 'c']
7425
7426    Args:
7427        expression: expression to find table names.
7428        exclude: a table name to exclude
7429
7430    Returns:
7431        A list of unique names.
7432    """
7433    return {
7434        table
7435        for table in (column.table for column in expression.find_all(Column))
7436        if table and table != exclude
7437    }

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:
7440def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7441    """Get the full name of a table as a string.
7442
7443    Args:
7444        table: Table expression node or string.
7445        dialect: The dialect to generate the table name for.
7446        identify: Determines when an identifier should be quoted. Possible values are:
7447            False (default): Never quote, except in cases where it's mandatory by the dialect.
7448            True: Always quote.
7449
7450    Examples:
7451        >>> from sqlglot import exp, parse_one
7452        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7453        'a.b.c'
7454
7455    Returns:
7456        The table name.
7457    """
7458
7459    table = maybe_parse(table, into=Table, dialect=dialect)
7460
7461    if not table:
7462        raise ValueError(f"Cannot parse {table}")
7463
7464    return ".".join(
7465        (
7466            part.sql(dialect=dialect, identify=True, copy=False)
7467            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7468            else part.name
7469        )
7470        for part in table.parts
7471    )

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:
7474def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7475    """Returns a case normalized table name without quotes.
7476
7477    Args:
7478        table: the table to normalize
7479        dialect: the dialect to use for normalization rules
7480        copy: whether to copy the expression.
7481
7482    Examples:
7483        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7484        'A-B.c'
7485    """
7486    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7487
7488    return ".".join(
7489        p.name
7490        for p in normalize_identifiers(
7491            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7492        ).parts
7493    )

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

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:
7723def tuple_(
7724    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7725) -> Tuple:
7726    """
7727    Returns an tuple.
7728
7729    Examples:
7730        >>> tuple_(1, 'x').sql()
7731        '(1, x)'
7732
7733    Args:
7734        expressions: the expressions to add to the tuple.
7735        copy: whether to copy the argument expressions.
7736        dialect: the source dialect.
7737        kwargs: the kwargs used to instantiate the function of interest.
7738
7739    Returns:
7740        A tuple expression.
7741    """
7742    return Tuple(
7743        expressions=[
7744            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7745            for expression in expressions
7746        ]
7747    )

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:
7750def true() -> Boolean:
7751    """
7752    Returns a true Boolean expression.
7753    """
7754    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7757def false() -> Boolean:
7758    """
7759    Returns a false Boolean expression.
7760    """
7761    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7764def null() -> Null:
7765    """
7766    Returns a Null expression.
7767    """
7768    return Null()

Returns a Null expression.

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