Edit on GitHub

Expressions

Every AST node in SQLGlot is represented by a subclass of Expression.

This module contains the implementation of all supported Expression types. Additionally, it exposes a number of helper functions, which are mainly used to programmatically build SQL expressions, such as select.


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

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

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

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

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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

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

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

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

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is an integer.

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

Checks whether an expression is a star.

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

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

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

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

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

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

Returns a deep copy of the expression.

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

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

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

Sets arg_key to value.

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

Returns the depth of this tree.

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

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

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

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

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

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

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

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

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

The generator object.

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

Returns a nearest parent matching expression_types.

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

The parent node.

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

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

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

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

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

the generator object.

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

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

Returns:

The generator object.

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

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

Returns:

The generator object.

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

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

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

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

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

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

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

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

Returns SQL string representation of this tree.

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

The SQL string.

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

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

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

The transformed tree.

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

Swap out this expression with a new expression.

For example::

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

The new expression or expressions.

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Assert that this Expression is an instance of type_.

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

Examples:

This is useful for type security in chained expressions:

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

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

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

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

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

Dump this Expression to a JSON-serializable dict.

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

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

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

AND this condition with one or multiple expressions.

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

The new And condition.

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

OR this condition with one or multiple expressions.

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

The new Or condition.

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

Wrap this condition with NOT.

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

The new Not instance.

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

Logical conditions like x AND y, or simply x

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

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

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

Returns a Subquery that wraps around this query.

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

Adds a LIMIT clause to this query.

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

A limited Select expression.

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

Set the OFFSET expression.

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

The modified Select expression.

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

Set the ORDER BY expression.

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

The modified Select expression.

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

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

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

Returns the query's projections.

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

Returns the output names of the query's projections.

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

Append to or set the SELECT expressions.

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

The modified Query expression.

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

Append to or set the common table expressions.

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

The modified expression.

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

Builds a UNION expression.

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

The new Union expression.

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

Builds an INTERSECT expression.

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

The new Intersect expression.

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

Builds an EXCEPT expression.

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

The new Except expression.

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

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

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

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

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

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

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

Set the RETURNING expression. Not supported by all dialects.

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

Delete: the modified expression.

key = 'dml'
class Create(DDL):
1382class Create(DDL):
1383    arg_types = {
1384        "with": False,
1385        "this": True,
1386        "kind": True,
1387        "expression": False,
1388        "exists": False,
1389        "properties": False,
1390        "replace": False,
1391        "refresh": False,
1392        "unique": False,
1393        "indexes": False,
1394        "no_schema_binding": False,
1395        "begin": False,
1396        "end": False,
1397        "clone": False,
1398        "concurrently": False,
1399        "clustered": False,
1400    }
1401
1402    @property
1403    def kind(self) -> t.Optional[str]:
1404        kind = self.args.get("kind")
1405        return kind and kind.upper()
arg_types = {'with': False, 'this': True, 'kind': True, 'expression': False, 'exists': False, 'properties': False, 'replace': False, 'refresh': False, 'unique': False, 'indexes': False, 'no_schema_binding': False, 'begin': False, 'end': False, 'clone': False, 'concurrently': False, 'clustered': False}
kind: Optional[str]
1402    @property
1403    def kind(self) -> t.Optional[str]:
1404        kind = self.args.get("kind")
1405        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1408class SequenceProperties(Expression):
1409    arg_types = {
1410        "increment": False,
1411        "minvalue": False,
1412        "maxvalue": False,
1413        "cache": False,
1414        "start": False,
1415        "owned": False,
1416        "options": False,
1417    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1420class TruncateTable(Expression):
1421    arg_types = {
1422        "expressions": True,
1423        "is_database": False,
1424        "exists": False,
1425        "only": False,
1426        "cluster": False,
1427        "identity": False,
1428        "option": False,
1429        "partition": False,
1430    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1436class Clone(Expression):
1437    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1440class Describe(Expression):
1441    arg_types = {
1442        "this": True,
1443        "style": False,
1444        "kind": False,
1445        "expressions": False,
1446        "partition": False,
1447    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False}
key = 'describe'
class Summarize(Expression):
1451class Summarize(Expression):
1452    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1455class Kill(Expression):
1456    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1459class Pragma(Expression):
1460    pass
key = 'pragma'
class Declare(Expression):
1463class Declare(Expression):
1464    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1467class DeclareItem(Expression):
1468    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1471class Set(Expression):
1472    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1475class Heredoc(Expression):
1476    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1479class SetItem(Expression):
1480    arg_types = {
1481        "this": False,
1482        "expressions": False,
1483        "kind": False,
1484        "collate": False,  # MySQL SET NAMES statement
1485        "global": False,
1486    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1489class Show(Expression):
1490    arg_types = {
1491        "this": True,
1492        "history": False,
1493        "terse": False,
1494        "target": False,
1495        "offset": False,
1496        "starts_with": False,
1497        "limit": False,
1498        "from": False,
1499        "like": False,
1500        "where": False,
1501        "db": False,
1502        "scope": False,
1503        "scope_kind": False,
1504        "full": False,
1505        "mutex": False,
1506        "query": False,
1507        "channel": False,
1508        "global": False,
1509        "log": False,
1510        "position": False,
1511        "types": False,
1512    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global': False, 'log': False, 'position': False, 'types': False}
key = 'show'
class UserDefinedFunction(Expression):
1515class UserDefinedFunction(Expression):
1516    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1519class CharacterSet(Expression):
1520    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1523class With(Expression):
1524    arg_types = {"expressions": True, "recursive": False}
1525
1526    @property
1527    def recursive(self) -> bool:
1528        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1526    @property
1527    def recursive(self) -> bool:
1528        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1531class WithinGroup(Expression):
1532    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1537class CTE(DerivedTable):
1538    arg_types = {
1539        "this": True,
1540        "alias": True,
1541        "scalar": False,
1542        "materialized": False,
1543    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1546class ProjectionDef(Expression):
1547    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1550class TableAlias(Expression):
1551    arg_types = {"this": False, "columns": False}
1552
1553    @property
1554    def columns(self):
1555        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1553    @property
1554    def columns(self):
1555        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1558class BitString(Condition):
1559    pass
key = 'bitstring'
class HexString(Condition):
1562class HexString(Condition):
1563    pass
key = 'hexstring'
class ByteString(Condition):
1566class ByteString(Condition):
1567    pass
key = 'bytestring'
class RawString(Condition):
1570class RawString(Condition):
1571    pass
key = 'rawstring'
class UnicodeString(Condition):
1574class UnicodeString(Condition):
1575    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1578class Column(Condition):
1579    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1580
1581    @property
1582    def table(self) -> str:
1583        return self.text("table")
1584
1585    @property
1586    def db(self) -> str:
1587        return self.text("db")
1588
1589    @property
1590    def catalog(self) -> str:
1591        return self.text("catalog")
1592
1593    @property
1594    def output_name(self) -> str:
1595        return self.name
1596
1597    @property
1598    def parts(self) -> t.List[Identifier]:
1599        """Return the parts of a column in order catalog, db, table, name."""
1600        return [
1601            t.cast(Identifier, self.args[part])
1602            for part in ("catalog", "db", "table", "this")
1603            if self.args.get(part)
1604        ]
1605
1606    def to_dot(self) -> Dot | Identifier:
1607        """Converts the column into a dot expression."""
1608        parts = self.parts
1609        parent = self.parent
1610
1611        while parent:
1612            if isinstance(parent, Dot):
1613                parts.append(parent.expression)
1614            parent = parent.parent
1615
1616        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]
arg_types = {'this': True, 'table': False, 'db': False, 'catalog': False, 'join_mark': False}
table: str
1581    @property
1582    def table(self) -> str:
1583        return self.text("table")
db: str
1585    @property
1586    def db(self) -> str:
1587        return self.text("db")
catalog: str
1589    @property
1590    def catalog(self) -> str:
1591        return self.text("catalog")
output_name: str
1593    @property
1594    def output_name(self) -> str:
1595        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
parts: List[Identifier]
1597    @property
1598    def parts(self) -> t.List[Identifier]:
1599        """Return the parts of a column in order catalog, db, table, name."""
1600        return [
1601            t.cast(Identifier, self.args[part])
1602            for part in ("catalog", "db", "table", "this")
1603            if self.args.get(part)
1604        ]

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

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

Converts the column into a dot expression.

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

Create a DELETE expression or replace the table on an existing DELETE expression.

Example:
>>> delete("tbl").sql()
'DELETE FROM tbl'
Arguments:
  • table: the table from which to delete.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

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

Append to or set the WHERE expressions.

Example:
>>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
"DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Delete: the modified expression.

key = 'delete'
class Drop(Expression):
1997class Drop(Expression):
1998    arg_types = {
1999        "this": False,
2000        "kind": False,
2001        "expressions": False,
2002        "exists": False,
2003        "temporary": False,
2004        "materialized": False,
2005        "cascade": False,
2006        "constraints": False,
2007        "purge": False,
2008        "cluster": False,
2009    }
2010
2011    @property
2012    def kind(self) -> t.Optional[str]:
2013        kind = self.args.get("kind")
2014        return kind and kind.upper()
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False}
kind: Optional[str]
2011    @property
2012    def kind(self) -> t.Optional[str]:
2013        kind = self.args.get("kind")
2014        return kind and kind.upper()
key = 'drop'
class Filter(Expression):
2017class Filter(Expression):
2018    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2021class Check(Expression):
2022    pass
key = 'check'
class Changes(Expression):
2025class Changes(Expression):
2026    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2030class Connect(Expression):
2031    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2034class CopyParameter(Expression):
2035    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2038class Copy(DML):
2039    arg_types = {
2040        "this": True,
2041        "kind": True,
2042        "files": True,
2043        "credentials": False,
2044        "format": False,
2045        "params": False,
2046    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2049class Credentials(Expression):
2050    arg_types = {
2051        "credentials": False,
2052        "encryption": False,
2053        "storage": False,
2054        "iam_role": False,
2055        "region": False,
2056    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2059class Prior(Expression):
2060    pass
key = 'prior'
class Directory(Expression):
2063class Directory(Expression):
2064    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2065    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2068class ForeignKey(Expression):
2069    arg_types = {
2070        "expressions": True,
2071        "reference": False,
2072        "delete": False,
2073        "update": False,
2074    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2077class ColumnPrefix(Expression):
2078    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2081class PrimaryKey(Expression):
2082    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2087class Into(Expression):
2088    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2091class From(Expression):
2092    @property
2093    def name(self) -> str:
2094        return self.this.name
2095
2096    @property
2097    def alias_or_name(self) -> str:
2098        return self.this.alias_or_name
name: str
2092    @property
2093    def name(self) -> str:
2094        return self.this.name
alias_or_name: str
2096    @property
2097    def alias_or_name(self) -> str:
2098        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2101class Having(Expression):
2102    pass
key = 'having'
class Hint(Expression):
2105class Hint(Expression):
2106    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2109class JoinHint(Expression):
2110    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2113class Identifier(Expression):
2114    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2115
2116    @property
2117    def quoted(self) -> bool:
2118        return bool(self.args.get("quoted"))
2119
2120    @property
2121    def hashable_args(self) -> t.Any:
2122        return (self.this, self.quoted)
2123
2124    @property
2125    def output_name(self) -> str:
2126        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2116    @property
2117    def quoted(self) -> bool:
2118        return bool(self.args.get("quoted"))
hashable_args: Any
2120    @property
2121    def hashable_args(self) -> t.Any:
2122        return (self.this, self.quoted)
output_name: str
2124    @property
2125    def output_name(self) -> str:
2126        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'identifier'
class Opclass(Expression):
2130class Opclass(Expression):
2131    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2134class Index(Expression):
2135    arg_types = {
2136        "this": False,
2137        "table": False,
2138        "unique": False,
2139        "primary": False,
2140        "amp": False,  # teradata
2141        "params": False,
2142    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2145class IndexParameters(Expression):
2146    arg_types = {
2147        "using": False,
2148        "include": False,
2149        "columns": False,
2150        "with_storage": False,
2151        "partition_by": False,
2152        "tablespace": False,
2153        "where": False,
2154        "on": False,
2155    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False, 'on': False}
key = 'indexparameters'
class Insert(DDL, DML):
2158class Insert(DDL, DML):
2159    arg_types = {
2160        "hint": False,
2161        "with": False,
2162        "is_function": False,
2163        "this": False,
2164        "expression": False,
2165        "conflict": False,
2166        "returning": False,
2167        "overwrite": False,
2168        "exists": False,
2169        "alternative": False,
2170        "where": False,
2171        "ignore": False,
2172        "by_name": False,
2173        "stored": False,
2174        "partition": False,
2175        "settings": False,
2176    }
2177
2178    def with_(
2179        self,
2180        alias: ExpOrStr,
2181        as_: ExpOrStr,
2182        recursive: t.Optional[bool] = None,
2183        append: bool = True,
2184        dialect: DialectType = None,
2185        copy: bool = True,
2186        **opts,
2187    ) -> Insert:
2188        """
2189        Append to or set the common table expressions.
2190
2191        Example:
2192            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2193            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2194
2195        Args:
2196            alias: the SQL code string to parse as the table name.
2197                If an `Expression` instance is passed, this is used as-is.
2198            as_: the SQL code string to parse as the table expression.
2199                If an `Expression` instance is passed, it will be used as-is.
2200            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2201            append: if `True`, add to any existing expressions.
2202                Otherwise, this resets the expressions.
2203            dialect: the dialect used to parse the input expression.
2204            copy: if `False`, modify this expression instance in-place.
2205            opts: other options to use to parse the input expressions.
2206
2207        Returns:
2208            The modified expression.
2209        """
2210        return _apply_cte_builder(
2211            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2212        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False, 'partition': False, 'settings': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2178    def with_(
2179        self,
2180        alias: ExpOrStr,
2181        as_: ExpOrStr,
2182        recursive: t.Optional[bool] = None,
2183        append: bool = True,
2184        dialect: DialectType = None,
2185        copy: bool = True,
2186        **opts,
2187    ) -> Insert:
2188        """
2189        Append to or set the common table expressions.
2190
2191        Example:
2192            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2193            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2194
2195        Args:
2196            alias: the SQL code string to parse as the table name.
2197                If an `Expression` instance is passed, this is used as-is.
2198            as_: the SQL code string to parse as the table expression.
2199                If an `Expression` instance is passed, it will be used as-is.
2200            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2201            append: if `True`, add to any existing expressions.
2202                Otherwise, this resets the expressions.
2203            dialect: the dialect used to parse the input expression.
2204            copy: if `False`, modify this expression instance in-place.
2205            opts: other options to use to parse the input expressions.
2206
2207        Returns:
2208            The modified expression.
2209        """
2210        return _apply_cte_builder(
2211            self, alias, as_, recursive=recursive, append=append, dialect=dialect, copy=copy, **opts
2212        )

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):
2215class OnConflict(Expression):
2216    arg_types = {
2217        "duplicate": False,
2218        "expressions": False,
2219        "action": False,
2220        "conflict_keys": False,
2221        "constraint": False,
2222    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class Returning(Expression):
2225class Returning(Expression):
2226    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2230class Introducer(Expression):
2231    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2235class National(Expression):
2236    pass
key = 'national'
class LoadData(Expression):
2239class LoadData(Expression):
2240    arg_types = {
2241        "this": True,
2242        "local": False,
2243        "overwrite": False,
2244        "inpath": True,
2245        "partition": False,
2246        "input_format": False,
2247        "serde": False,
2248    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2251class Partition(Expression):
2252    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2255class PartitionRange(Expression):
2256    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2260class PartitionId(Expression):
2261    pass
key = 'partitionid'
class Fetch(Expression):
2264class Fetch(Expression):
2265    arg_types = {
2266        "direction": False,
2267        "count": False,
2268        "percent": False,
2269        "with_ties": False,
2270    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2273class Group(Expression):
2274    arg_types = {
2275        "expressions": False,
2276        "grouping_sets": False,
2277        "cube": False,
2278        "rollup": False,
2279        "totals": False,
2280        "all": False,
2281    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Lambda(Expression):
2284class Lambda(Expression):
2285    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2288class Limit(Expression):
2289    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):
2292class Literal(Condition):
2293    arg_types = {"this": True, "is_string": True}
2294
2295    @property
2296    def hashable_args(self) -> t.Any:
2297        return (self.this, self.args.get("is_string"))
2298
2299    @classmethod
2300    def number(cls, number) -> Literal:
2301        return cls(this=str(number), is_string=False)
2302
2303    @classmethod
2304    def string(cls, string) -> Literal:
2305        return cls(this=str(string), is_string=True)
2306
2307    @property
2308    def output_name(self) -> str:
2309        return self.name
2310
2311    def to_py(self) -> int | str | Decimal:
2312        if self.is_number:
2313            try:
2314                return int(self.this)
2315            except ValueError:
2316                return Decimal(self.this)
2317        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2295    @property
2296    def hashable_args(self) -> t.Any:
2297        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2299    @classmethod
2300    def number(cls, number) -> Literal:
2301        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2303    @classmethod
2304    def string(cls, string) -> Literal:
2305        return cls(this=str(string), is_string=True)
output_name: str
2307    @property
2308    def output_name(self) -> str:
2309        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:
2311    def to_py(self) -> int | str | Decimal:
2312        if self.is_number:
2313            try:
2314                return int(self.this)
2315            except ValueError:
2316                return Decimal(self.this)
2317        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2320class Join(Expression):
2321    arg_types = {
2322        "this": True,
2323        "on": False,
2324        "side": False,
2325        "kind": False,
2326        "using": False,
2327        "method": False,
2328        "global": False,
2329        "hint": False,
2330        "match_condition": False,  # Snowflake
2331    }
2332
2333    @property
2334    def method(self) -> str:
2335        return self.text("method").upper()
2336
2337    @property
2338    def kind(self) -> str:
2339        return self.text("kind").upper()
2340
2341    @property
2342    def side(self) -> str:
2343        return self.text("side").upper()
2344
2345    @property
2346    def hint(self) -> str:
2347        return self.text("hint").upper()
2348
2349    @property
2350    def alias_or_name(self) -> str:
2351        return self.this.alias_or_name
2352
2353    def on(
2354        self,
2355        *expressions: t.Optional[ExpOrStr],
2356        append: bool = True,
2357        dialect: DialectType = None,
2358        copy: bool = True,
2359        **opts,
2360    ) -> Join:
2361        """
2362        Append to or set the ON expressions.
2363
2364        Example:
2365            >>> import sqlglot
2366            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2367            'JOIN x ON y = 1'
2368
2369        Args:
2370            *expressions: the SQL code strings to parse.
2371                If an `Expression` instance is passed, it will be used as-is.
2372                Multiple expressions are combined with an AND operator.
2373            append: if `True`, AND the new expressions to any existing expression.
2374                Otherwise, this resets the expression.
2375            dialect: the dialect used to parse the input expressions.
2376            copy: if `False`, modify this expression instance in-place.
2377            opts: other options to use to parse the input expressions.
2378
2379        Returns:
2380            The modified Join expression.
2381        """
2382        join = _apply_conjunction_builder(
2383            *expressions,
2384            instance=self,
2385            arg="on",
2386            append=append,
2387            dialect=dialect,
2388            copy=copy,
2389            **opts,
2390        )
2391
2392        if join.kind == "CROSS":
2393            join.set("kind", None)
2394
2395        return join
2396
2397    def using(
2398        self,
2399        *expressions: t.Optional[ExpOrStr],
2400        append: bool = True,
2401        dialect: DialectType = None,
2402        copy: bool = True,
2403        **opts,
2404    ) -> Join:
2405        """
2406        Append to or set the USING expressions.
2407
2408        Example:
2409            >>> import sqlglot
2410            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2411            'JOIN x USING (foo, bla)'
2412
2413        Args:
2414            *expressions: the SQL code strings to parse.
2415                If an `Expression` instance is passed, it will be used as-is.
2416            append: if `True`, concatenate the new expressions to the existing "using" list.
2417                Otherwise, this resets the expression.
2418            dialect: the dialect used to parse the input expressions.
2419            copy: if `False`, modify this expression instance in-place.
2420            opts: other options to use to parse the input expressions.
2421
2422        Returns:
2423            The modified Join expression.
2424        """
2425        join = _apply_list_builder(
2426            *expressions,
2427            instance=self,
2428            arg="using",
2429            append=append,
2430            dialect=dialect,
2431            copy=copy,
2432            **opts,
2433        )
2434
2435        if join.kind == "CROSS":
2436            join.set("kind", None)
2437
2438        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
2333    @property
2334    def method(self) -> str:
2335        return self.text("method").upper()
kind: str
2337    @property
2338    def kind(self) -> str:
2339        return self.text("kind").upper()
side: str
2341    @property
2342    def side(self) -> str:
2343        return self.text("side").upper()
hint: str
2345    @property
2346    def hint(self) -> str:
2347        return self.text("hint").upper()
alias_or_name: str
2349    @property
2350    def alias_or_name(self) -> str:
2351        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:
2353    def on(
2354        self,
2355        *expressions: t.Optional[ExpOrStr],
2356        append: bool = True,
2357        dialect: DialectType = None,
2358        copy: bool = True,
2359        **opts,
2360    ) -> Join:
2361        """
2362        Append to or set the ON expressions.
2363
2364        Example:
2365            >>> import sqlglot
2366            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2367            'JOIN x ON y = 1'
2368
2369        Args:
2370            *expressions: the SQL code strings to parse.
2371                If an `Expression` instance is passed, it will be used as-is.
2372                Multiple expressions are combined with an AND operator.
2373            append: if `True`, AND the new expressions to any existing expression.
2374                Otherwise, this resets the expression.
2375            dialect: the dialect used to parse the input expressions.
2376            copy: if `False`, modify this expression instance in-place.
2377            opts: other options to use to parse the input expressions.
2378
2379        Returns:
2380            The modified Join expression.
2381        """
2382        join = _apply_conjunction_builder(
2383            *expressions,
2384            instance=self,
2385            arg="on",
2386            append=append,
2387            dialect=dialect,
2388            copy=copy,
2389            **opts,
2390        )
2391
2392        if join.kind == "CROSS":
2393            join.set("kind", None)
2394
2395        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:
2397    def using(
2398        self,
2399        *expressions: t.Optional[ExpOrStr],
2400        append: bool = True,
2401        dialect: DialectType = None,
2402        copy: bool = True,
2403        **opts,
2404    ) -> Join:
2405        """
2406        Append to or set the USING expressions.
2407
2408        Example:
2409            >>> import sqlglot
2410            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2411            'JOIN x USING (foo, bla)'
2412
2413        Args:
2414            *expressions: the SQL code strings to parse.
2415                If an `Expression` instance is passed, it will be used as-is.
2416            append: if `True`, concatenate the new expressions to the existing "using" list.
2417                Otherwise, this resets the expression.
2418            dialect: the dialect used to parse the input expressions.
2419            copy: if `False`, modify this expression instance in-place.
2420            opts: other options to use to parse the input expressions.
2421
2422        Returns:
2423            The modified Join expression.
2424        """
2425        join = _apply_list_builder(
2426            *expressions,
2427            instance=self,
2428            arg="using",
2429            append=append,
2430            dialect=dialect,
2431            copy=copy,
2432            **opts,
2433        )
2434
2435        if join.kind == "CROSS":
2436            join.set("kind", None)
2437
2438        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):
2441class Lateral(UDTF):
2442    arg_types = {
2443        "this": True,
2444        "view": False,
2445        "outer": False,
2446        "alias": False,
2447        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2448    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2451class MatchRecognizeMeasure(Expression):
2452    arg_types = {
2453        "this": True,
2454        "window_frame": False,
2455    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2458class MatchRecognize(Expression):
2459    arg_types = {
2460        "partition_by": False,
2461        "order": False,
2462        "measures": False,
2463        "rows": False,
2464        "after": False,
2465        "pattern": False,
2466        "define": False,
2467        "alias": False,
2468    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2473class Final(Expression):
2474    pass
key = 'final'
class Offset(Expression):
2477class Offset(Expression):
2478    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2481class Order(Expression):
2482    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2486class WithFill(Expression):
2487    arg_types = {
2488        "from": False,
2489        "to": False,
2490        "step": False,
2491        "interpolate": False,
2492    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2497class Cluster(Order):
2498    pass
key = 'cluster'
class Distribute(Order):
2501class Distribute(Order):
2502    pass
key = 'distribute'
class Sort(Order):
2505class Sort(Order):
2506    pass
key = 'sort'
class Ordered(Expression):
2509class Ordered(Expression):
2510    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):
2513class Property(Expression):
2514    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2517class AllowedValuesProperty(Expression):
2518    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2521class AlgorithmProperty(Property):
2522    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2525class AutoIncrementProperty(Property):
2526    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2530class AutoRefreshProperty(Property):
2531    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2534class BackupProperty(Property):
2535    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2538class BlockCompressionProperty(Property):
2539    arg_types = {
2540        "autotemp": False,
2541        "always": False,
2542        "default": False,
2543        "manual": False,
2544        "never": False,
2545    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2548class CharacterSetProperty(Property):
2549    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2552class ChecksumProperty(Property):
2553    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2556class CollateProperty(Property):
2557    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2560class CopyGrantsProperty(Property):
2561    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2564class DataBlocksizeProperty(Property):
2565    arg_types = {
2566        "size": False,
2567        "units": False,
2568        "minimum": False,
2569        "maximum": False,
2570        "default": False,
2571    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2574class DataDeletionProperty(Property):
2575    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):
2578class DefinerProperty(Property):
2579    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2582class DistKeyProperty(Property):
2583    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistStyleProperty(Property):
2586class DistStyleProperty(Property):
2587    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class EngineProperty(Property):
2590class EngineProperty(Property):
2591    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2594class HeapProperty(Property):
2595    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2598class ToTableProperty(Property):
2599    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2602class ExecuteAsProperty(Property):
2603    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2606class ExternalProperty(Property):
2607    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2610class FallbackProperty(Property):
2611    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2614class FileFormatProperty(Property):
2615    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2618class FreespaceProperty(Property):
2619    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2622class GlobalProperty(Property):
2623    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2626class IcebergProperty(Property):
2627    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2630class InheritsProperty(Property):
2631    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2634class InputModelProperty(Property):
2635    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2638class OutputModelProperty(Property):
2639    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2642class IsolatedLoadingProperty(Property):
2643    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2646class JournalProperty(Property):
2647    arg_types = {
2648        "no": False,
2649        "dual": False,
2650        "before": False,
2651        "local": False,
2652        "after": False,
2653    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2656class LanguageProperty(Property):
2657    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2661class ClusteredByProperty(Property):
2662    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2665class DictProperty(Property):
2666    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2669class DictSubProperty(Property):
2670    pass
key = 'dictsubproperty'
class DictRange(Property):
2673class DictRange(Property):
2674    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2677class DynamicProperty(Property):
2678    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2683class OnCluster(Property):
2684    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2688class EmptyProperty(Property):
2689    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2692class LikeProperty(Property):
2693    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2696class LocationProperty(Property):
2697    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2700class LockProperty(Property):
2701    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2704class LockingProperty(Property):
2705    arg_types = {
2706        "this": False,
2707        "kind": True,
2708        "for_or_in": False,
2709        "lock_type": True,
2710        "override": False,
2711    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2714class LogProperty(Property):
2715    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2718class MaterializedProperty(Property):
2719    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2722class MergeBlockRatioProperty(Property):
2723    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):
2726class NoPrimaryIndexProperty(Property):
2727    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2730class OnProperty(Property):
2731    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2734class OnCommitProperty(Property):
2735    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2738class PartitionedByProperty(Property):
2739    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2743class PartitionBoundSpec(Expression):
2744    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2745    arg_types = {
2746        "this": False,
2747        "expression": False,
2748        "from_expressions": False,
2749        "to_expressions": False,
2750    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2753class PartitionedOfProperty(Property):
2754    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2755    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2758class StreamingTableProperty(Property):
2759    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2762class RemoteWithConnectionModelProperty(Property):
2763    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2766class ReturnsProperty(Property):
2767    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):
2770class StrictProperty(Property):
2771    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2774class RowFormatProperty(Property):
2775    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2778class RowFormatDelimitedProperty(Property):
2779    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2780    arg_types = {
2781        "fields": False,
2782        "escaped": False,
2783        "collection_items": False,
2784        "map_keys": False,
2785        "lines": False,
2786        "null": False,
2787        "serde": False,
2788    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2791class RowFormatSerdeProperty(Property):
2792    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2796class QueryTransform(Expression):
2797    arg_types = {
2798        "expressions": True,
2799        "command_script": True,
2800        "schema": False,
2801        "row_format_before": False,
2802        "record_writer": False,
2803        "row_format_after": False,
2804        "record_reader": False,
2805    }
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):
2808class SampleProperty(Property):
2809    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SchemaCommentProperty(Property):
2812class SchemaCommentProperty(Property):
2813    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2816class SerdeProperties(Property):
2817    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2820class SetProperty(Property):
2821    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2824class SharingProperty(Property):
2825    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2828class SetConfigProperty(Property):
2829    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2832class SettingsProperty(Property):
2833    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2836class SortKeyProperty(Property):
2837    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2840class SqlReadWriteProperty(Property):
2841    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2844class SqlSecurityProperty(Property):
2845    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2848class StabilityProperty(Property):
2849    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2852class TemporaryProperty(Property):
2853    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2856class SecureProperty(Property):
2857    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2860class TransformModelProperty(Property):
2861    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2864class TransientProperty(Property):
2865    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2868class UnloggedProperty(Property):
2869    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2873class ViewAttributeProperty(Property):
2874    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2877class VolatileProperty(Property):
2878    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2881class WithDataProperty(Property):
2882    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2885class WithJournalTableProperty(Property):
2886    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2889class WithSchemaBindingProperty(Property):
2890    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2893class WithSystemVersioningProperty(Property):
2894    arg_types = {
2895        "on": False,
2896        "this": False,
2897        "data_consistency": False,
2898        "retention_period": False,
2899        "with": True,
2900    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2903class Properties(Expression):
2904    arg_types = {"expressions": True}
2905
2906    NAME_TO_PROPERTY = {
2907        "ALGORITHM": AlgorithmProperty,
2908        "AUTO_INCREMENT": AutoIncrementProperty,
2909        "CHARACTER SET": CharacterSetProperty,
2910        "CLUSTERED_BY": ClusteredByProperty,
2911        "COLLATE": CollateProperty,
2912        "COMMENT": SchemaCommentProperty,
2913        "DEFINER": DefinerProperty,
2914        "DISTKEY": DistKeyProperty,
2915        "DISTSTYLE": DistStyleProperty,
2916        "ENGINE": EngineProperty,
2917        "EXECUTE AS": ExecuteAsProperty,
2918        "FORMAT": FileFormatProperty,
2919        "LANGUAGE": LanguageProperty,
2920        "LOCATION": LocationProperty,
2921        "LOCK": LockProperty,
2922        "PARTITIONED_BY": PartitionedByProperty,
2923        "RETURNS": ReturnsProperty,
2924        "ROW_FORMAT": RowFormatProperty,
2925        "SORTKEY": SortKeyProperty,
2926    }
2927
2928    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
2929
2930    # CREATE property locations
2931    # Form: schema specified
2932    #   create [POST_CREATE]
2933    #     table a [POST_NAME]
2934    #     (b int) [POST_SCHEMA]
2935    #     with ([POST_WITH])
2936    #     index (b) [POST_INDEX]
2937    #
2938    # Form: alias selection
2939    #   create [POST_CREATE]
2940    #     table a [POST_NAME]
2941    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
2942    #     index (c) [POST_INDEX]
2943    class Location(AutoName):
2944        POST_CREATE = auto()
2945        POST_NAME = auto()
2946        POST_SCHEMA = auto()
2947        POST_WITH = auto()
2948        POST_ALIAS = auto()
2949        POST_EXPRESSION = auto()
2950        POST_INDEX = auto()
2951        UNSUPPORTED = auto()
2952
2953    @classmethod
2954    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2955        expressions = []
2956        for key, value in properties_dict.items():
2957            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2958            if property_cls:
2959                expressions.append(property_cls(this=convert(value)))
2960            else:
2961                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2962
2963        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:
2953    @classmethod
2954    def from_dict(cls, properties_dict: t.Dict) -> Properties:
2955        expressions = []
2956        for key, value in properties_dict.items():
2957            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
2958            if property_cls:
2959                expressions.append(property_cls(this=convert(value)))
2960            else:
2961                expressions.append(Property(this=Literal.string(key), value=convert(value)))
2962
2963        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
2943    class Location(AutoName):
2944        POST_CREATE = auto()
2945        POST_NAME = auto()
2946        POST_SCHEMA = auto()
2947        POST_WITH = auto()
2948        POST_ALIAS = auto()
2949        POST_EXPRESSION = auto()
2950        POST_INDEX = auto()
2951        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):
2966class Qualify(Expression):
2967    pass
key = 'qualify'
class InputOutputFormat(Expression):
2970class InputOutputFormat(Expression):
2971    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
2975class Return(Expression):
2976    pass
key = 'return'
class Reference(Expression):
2979class Reference(Expression):
2980    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
2983class Tuple(Expression):
2984    arg_types = {"expressions": False}
2985
2986    def isin(
2987        self,
2988        *expressions: t.Any,
2989        query: t.Optional[ExpOrStr] = None,
2990        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2991        copy: bool = True,
2992        **opts,
2993    ) -> In:
2994        return In(
2995            this=maybe_copy(self, copy),
2996            expressions=[convert(e, copy=copy) for e in expressions],
2997            query=maybe_parse(query, copy=copy, **opts) if query else None,
2998            unnest=(
2999                Unnest(
3000                    expressions=[
3001                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3002                        for e in ensure_list(unnest)
3003                    ]
3004                )
3005                if unnest
3006                else None
3007            ),
3008        )
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:
2986    def isin(
2987        self,
2988        *expressions: t.Any,
2989        query: t.Optional[ExpOrStr] = None,
2990        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
2991        copy: bool = True,
2992        **opts,
2993    ) -> In:
2994        return In(
2995            this=maybe_copy(self, copy),
2996            expressions=[convert(e, copy=copy) for e in expressions],
2997            query=maybe_parse(query, copy=copy, **opts) if query else None,
2998            unnest=(
2999                Unnest(
3000                    expressions=[
3001                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3002                        for e in ensure_list(unnest)
3003                    ]
3004                )
3005                if unnest
3006                else None
3007            ),
3008        )
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):
3039class QueryOption(Expression):
3040    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3044class WithTableHint(Expression):
3045    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3049class IndexTableHint(Expression):
3050    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3054class HistoricalData(Expression):
3055    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3058class Table(Expression):
3059    arg_types = {
3060        "this": False,
3061        "alias": False,
3062        "db": False,
3063        "catalog": False,
3064        "laterals": False,
3065        "joins": False,
3066        "pivots": False,
3067        "hints": False,
3068        "system_time": False,
3069        "version": False,
3070        "format": False,
3071        "pattern": False,
3072        "ordinality": False,
3073        "when": False,
3074        "only": False,
3075        "partition": False,
3076        "changes": False,
3077        "rows_from": False,
3078    }
3079
3080    @property
3081    def name(self) -> str:
3082        if isinstance(self.this, Func):
3083            return ""
3084        return self.this.name
3085
3086    @property
3087    def db(self) -> str:
3088        return self.text("db")
3089
3090    @property
3091    def catalog(self) -> str:
3092        return self.text("catalog")
3093
3094    @property
3095    def selects(self) -> t.List[Expression]:
3096        return []
3097
3098    @property
3099    def named_selects(self) -> t.List[str]:
3100        return []
3101
3102    @property
3103    def parts(self) -> t.List[Expression]:
3104        """Return the parts of a table in order catalog, db, table."""
3105        parts: t.List[Expression] = []
3106
3107        for arg in ("catalog", "db", "this"):
3108            part = self.args.get(arg)
3109
3110            if isinstance(part, Dot):
3111                parts.extend(part.flatten())
3112            elif isinstance(part, Expression):
3113                parts.append(part)
3114
3115        return parts
3116
3117    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3118        parts = self.parts
3119        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3120        alias = self.args.get("alias")
3121        if alias:
3122            col = alias_(col, alias.this, copy=copy)
3123        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
3080    @property
3081    def name(self) -> str:
3082        if isinstance(self.this, Func):
3083            return ""
3084        return self.this.name
db: str
3086    @property
3087    def db(self) -> str:
3088        return self.text("db")
catalog: str
3090    @property
3091    def catalog(self) -> str:
3092        return self.text("catalog")
selects: List[Expression]
3094    @property
3095    def selects(self) -> t.List[Expression]:
3096        return []
named_selects: List[str]
3098    @property
3099    def named_selects(self) -> t.List[str]:
3100        return []
parts: List[Expression]
3102    @property
3103    def parts(self) -> t.List[Expression]:
3104        """Return the parts of a table in order catalog, db, table."""
3105        parts: t.List[Expression] = []
3106
3107        for arg in ("catalog", "db", "this"):
3108            part = self.args.get(arg)
3109
3110            if isinstance(part, Dot):
3111                parts.extend(part.flatten())
3112            elif isinstance(part, Expression):
3113                parts.append(part)
3114
3115        return parts

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

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

Returns the output names of the query's projections.

is_star: bool
3155    @property
3156    def is_star(self) -> bool:
3157        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3159    @property
3160    def selects(self) -> t.List[Expression]:
3161        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3787    @property
3788    def selects(self) -> t.List[Expression]:
3789        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

output_name: str
3843    @property
3844    def output_name(self) -> str:
3845        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):
3848class TableSample(Expression):
3849    arg_types = {
3850        "this": False,
3851        "expressions": False,
3852        "method": False,
3853        "bucket_numerator": False,
3854        "bucket_denominator": False,
3855        "bucket_field": False,
3856        "percent": False,
3857        "rows": False,
3858        "size": False,
3859        "seed": False,
3860    }
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):
3863class Tag(Expression):
3864    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3865
3866    arg_types = {
3867        "this": False,
3868        "prefix": False,
3869        "postfix": False,
3870    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3875class Pivot(Expression):
3876    arg_types = {
3877        "this": False,
3878        "alias": False,
3879        "expressions": False,
3880        "field": False,
3881        "unpivot": False,
3882        "using": False,
3883        "group": False,
3884        "columns": False,
3885        "include_nulls": False,
3886        "default_on_null": False,
3887    }
3888
3889    @property
3890    def unpivot(self) -> bool:
3891        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False}
unpivot: bool
3889    @property
3890    def unpivot(self) -> bool:
3891        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3894class Window(Condition):
3895    arg_types = {
3896        "this": True,
3897        "partition_by": False,
3898        "order": False,
3899        "spec": False,
3900        "alias": False,
3901        "over": False,
3902        "first": False,
3903    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3906class WindowSpec(Expression):
3907    arg_types = {
3908        "kind": False,
3909        "start": False,
3910        "start_side": False,
3911        "end": False,
3912        "end_side": False,
3913    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3916class PreWhere(Expression):
3917    pass
key = 'prewhere'
class Where(Expression):
3920class Where(Expression):
3921    pass
key = 'where'
class Star(Expression):
3924class Star(Expression):
3925    arg_types = {"except": False, "replace": False, "rename": False}
3926
3927    @property
3928    def name(self) -> str:
3929        return "*"
3930
3931    @property
3932    def output_name(self) -> str:
3933        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3927    @property
3928    def name(self) -> str:
3929        return "*"
output_name: str
3931    @property
3932    def output_name(self) -> str:
3933        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):
3936class Parameter(Condition):
3937    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
3940class SessionParameter(Condition):
3941    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
3944class Placeholder(Condition):
3945    arg_types = {"this": False, "kind": False}
3946
3947    @property
3948    def name(self) -> str:
3949        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
3947    @property
3948    def name(self) -> str:
3949        return self.this or "?"
key = 'placeholder'
class Null(Condition):
3952class Null(Condition):
3953    arg_types: t.Dict[str, t.Any] = {}
3954
3955    @property
3956    def name(self) -> str:
3957        return "NULL"
3958
3959    def to_py(self) -> Lit[None]:
3960        return None
arg_types: Dict[str, Any] = {}
name: str
3955    @property
3956    def name(self) -> str:
3957        return "NULL"
def to_py(self) -> Literal[None]:
3959    def to_py(self) -> Lit[None]:
3960        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
3963class Boolean(Condition):
3964    def to_py(self) -> bool:
3965        return self.this
def to_py(self) -> bool:
3964    def to_py(self) -> bool:
3965        return self.this

Returns a Python object equivalent of the SQL node.

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

Constructs a DataType object.

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

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type], check_nullable: bool = False) -> bool:
4225    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4226        """
4227        Checks whether this DataType matches one of the provided data types. Nested types or precision
4228        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4229
4230        Args:
4231            dtypes: the data types to compare this DataType to.
4232            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4233                If false, it means that NULLABLE<INT> is equivalent to INT.
4234
4235        Returns:
4236            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4237        """
4238        if (
4239            not check_nullable
4240            and self.this == DataType.Type.NULLABLE
4241            and len(self.expressions) == 1
4242        ):
4243            this_type = self.expressions[0]
4244        else:
4245            this_type = self
4246
4247        for dtype in dtypes:
4248            other_type = DataType.build(dtype, copy=False, udt=True)
4249            if (
4250                not check_nullable
4251                and other_type.this == DataType.Type.NULLABLE
4252                and len(other_type.expressions) == 1
4253            ):
4254                other_type = other_type.expressions[0]
4255
4256            if (
4257                other_type.expressions
4258                or this_type.this == DataType.Type.USERDEFINED
4259                or other_type.this == DataType.Type.USERDEFINED
4260            ):
4261                matches = this_type == other_type
4262            else:
4263                matches = this_type.this == other_type.this
4264
4265            if matches:
4266                return True
4267        return False

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

Arguments:
  • dtypes: the data types to compare this DataType to.
  • check_nullable: whether to take the NULLABLE type constructor into account for the comparison. If false, it means that NULLABLE is equivalent to INT.
Returns:

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

key = 'datatype'
class DataType.Type(sqlglot.helper.AutoName):
3989    class Type(AutoName):
3990        ARRAY = auto()
3991        AGGREGATEFUNCTION = auto()
3992        SIMPLEAGGREGATEFUNCTION = auto()
3993        BIGDECIMAL = auto()
3994        BIGINT = auto()
3995        BIGSERIAL = auto()
3996        BINARY = auto()
3997        BIT = auto()
3998        BOOLEAN = auto()
3999        BPCHAR = auto()
4000        CHAR = auto()
4001        DATE = auto()
4002        DATE32 = auto()
4003        DATEMULTIRANGE = auto()
4004        DATERANGE = auto()
4005        DATETIME = auto()
4006        DATETIME64 = auto()
4007        DECIMAL = auto()
4008        DOUBLE = auto()
4009        ENUM = auto()
4010        ENUM8 = auto()
4011        ENUM16 = auto()
4012        FIXEDSTRING = auto()
4013        FLOAT = auto()
4014        GEOGRAPHY = auto()
4015        GEOMETRY = auto()
4016        HLLSKETCH = auto()
4017        HSTORE = auto()
4018        IMAGE = auto()
4019        INET = auto()
4020        INT = auto()
4021        INT128 = auto()
4022        INT256 = auto()
4023        INT4MULTIRANGE = auto()
4024        INT4RANGE = auto()
4025        INT8MULTIRANGE = auto()
4026        INT8RANGE = auto()
4027        INTERVAL = auto()
4028        IPADDRESS = auto()
4029        IPPREFIX = auto()
4030        IPV4 = auto()
4031        IPV6 = auto()
4032        JSON = auto()
4033        JSONB = auto()
4034        LIST = auto()
4035        LONGBLOB = auto()
4036        LONGTEXT = auto()
4037        LOWCARDINALITY = auto()
4038        MAP = auto()
4039        MEDIUMBLOB = auto()
4040        MEDIUMINT = auto()
4041        MEDIUMTEXT = auto()
4042        MONEY = auto()
4043        NAME = auto()
4044        NCHAR = auto()
4045        NESTED = auto()
4046        NULL = auto()
4047        NULLABLE = auto()
4048        NUMMULTIRANGE = auto()
4049        NUMRANGE = auto()
4050        NVARCHAR = auto()
4051        OBJECT = auto()
4052        ROWVERSION = auto()
4053        SERIAL = auto()
4054        SET = auto()
4055        SMALLINT = auto()
4056        SMALLMONEY = auto()
4057        SMALLSERIAL = auto()
4058        STRUCT = auto()
4059        SUPER = auto()
4060        TEXT = auto()
4061        TINYBLOB = auto()
4062        TINYTEXT = auto()
4063        TIME = auto()
4064        TIMETZ = auto()
4065        TIMESTAMP = auto()
4066        TIMESTAMPNTZ = auto()
4067        TIMESTAMPLTZ = auto()
4068        TIMESTAMPTZ = auto()
4069        TIMESTAMP_S = auto()
4070        TIMESTAMP_MS = auto()
4071        TIMESTAMP_NS = auto()
4072        TINYINT = auto()
4073        TSMULTIRANGE = auto()
4074        TSRANGE = auto()
4075        TSTZMULTIRANGE = auto()
4076        TSTZRANGE = auto()
4077        UBIGINT = auto()
4078        UINT = auto()
4079        UINT128 = auto()
4080        UINT256 = auto()
4081        UMEDIUMINT = auto()
4082        UDECIMAL = auto()
4083        UNIQUEIDENTIFIER = auto()
4084        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4085        USERDEFINED = "USER-DEFINED"
4086        USMALLINT = auto()
4087        UTINYINT = auto()
4088        UUID = auto()
4089        VARBINARY = auto()
4090        VARCHAR = auto()
4091        VARIANT = auto()
4092        VECTOR = auto()
4093        XML = auto()
4094        YEAR = auto()
4095        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):
4274class PseudoType(DataType):
4275    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4279class ObjectIdentifier(DataType):
4280    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4284class SubqueryPredicate(Predicate):
4285    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4288class All(SubqueryPredicate):
4289    pass
key = 'all'
class Any(SubqueryPredicate):
4292class Any(SubqueryPredicate):
4293    pass
key = 'any'
class Exists(SubqueryPredicate):
4296class Exists(SubqueryPredicate):
4297    pass
key = 'exists'
class Command(Expression):
4302class Command(Expression):
4303    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4306class Transaction(Expression):
4307    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4310class Commit(Expression):
4311    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4314class Rollback(Expression):
4315    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4318class Alter(Expression):
4319    arg_types = {
4320        "this": True,
4321        "kind": True,
4322        "actions": True,
4323        "exists": False,
4324        "only": False,
4325        "options": False,
4326        "cluster": False,
4327    }
arg_types = {'this': True, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False}
key = 'alter'
class AddConstraint(Expression):
4330class AddConstraint(Expression):
4331    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4334class DropPartition(Expression):
4335    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4339class ReplacePartition(Expression):
4340    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4344class Binary(Condition):
4345    arg_types = {"this": True, "expression": True}
4346
4347    @property
4348    def left(self) -> Expression:
4349        return self.this
4350
4351    @property
4352    def right(self) -> Expression:
4353        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4347    @property
4348    def left(self) -> Expression:
4349        return self.this
right: Expression
4351    @property
4352    def right(self) -> Expression:
4353        return self.expression
key = 'binary'
class Add(Binary):
4356class Add(Binary):
4357    pass
key = 'add'
class Connector(Binary):
4360class Connector(Binary):
4361    pass
key = 'connector'
class And(Connector):
4364class And(Connector):
4365    pass
key = 'and'
class Or(Connector):
4368class Or(Connector):
4369    pass
key = 'or'
class BitwiseAnd(Binary):
4372class BitwiseAnd(Binary):
4373    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4376class BitwiseLeftShift(Binary):
4377    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4380class BitwiseOr(Binary):
4381    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4384class BitwiseRightShift(Binary):
4385    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4388class BitwiseXor(Binary):
4389    pass
key = 'bitwisexor'
class Div(Binary):
4392class Div(Binary):
4393    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):
4396class Overlaps(Binary):
4397    pass
key = 'overlaps'
class Dot(Binary):
4400class Dot(Binary):
4401    @property
4402    def is_star(self) -> bool:
4403        return self.expression.is_star
4404
4405    @property
4406    def name(self) -> str:
4407        return self.expression.name
4408
4409    @property
4410    def output_name(self) -> str:
4411        return self.name
4412
4413    @classmethod
4414    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4415        """Build a Dot object with a sequence of expressions."""
4416        if len(expressions) < 2:
4417            raise ValueError("Dot requires >= 2 expressions.")
4418
4419        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4420
4421    @property
4422    def parts(self) -> t.List[Expression]:
4423        """Return the parts of a table / column in order catalog, db, table."""
4424        this, *parts = self.flatten()
4425
4426        parts.reverse()
4427
4428        for arg in COLUMN_PARTS:
4429            part = this.args.get(arg)
4430
4431            if isinstance(part, Expression):
4432                parts.append(part)
4433
4434        parts.reverse()
4435        return parts
is_star: bool
4401    @property
4402    def is_star(self) -> bool:
4403        return self.expression.is_star

Checks whether an expression is a star.

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

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

key = 'dot'
class DPipe(Binary):
4438class DPipe(Binary):
4439    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4442class EQ(Binary, Predicate):
4443    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4446class NullSafeEQ(Binary, Predicate):
4447    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4450class NullSafeNEQ(Binary, Predicate):
4451    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4455class PropertyEQ(Binary):
4456    pass
key = 'propertyeq'
class Distance(Binary):
4459class Distance(Binary):
4460    pass
key = 'distance'
class Escape(Binary):
4463class Escape(Binary):
4464    pass
key = 'escape'
class Glob(Binary, Predicate):
4467class Glob(Binary, Predicate):
4468    pass
key = 'glob'
class GT(Binary, Predicate):
4471class GT(Binary, Predicate):
4472    pass
key = 'gt'
class GTE(Binary, Predicate):
4475class GTE(Binary, Predicate):
4476    pass
key = 'gte'
class ILike(Binary, Predicate):
4479class ILike(Binary, Predicate):
4480    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4483class ILikeAny(Binary, Predicate):
4484    pass
key = 'ilikeany'
class IntDiv(Binary):
4487class IntDiv(Binary):
4488    pass
key = 'intdiv'
class Is(Binary, Predicate):
4491class Is(Binary, Predicate):
4492    pass
key = 'is'
class Kwarg(Binary):
4495class Kwarg(Binary):
4496    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4499class Like(Binary, Predicate):
4500    pass
key = 'like'
class LikeAny(Binary, Predicate):
4503class LikeAny(Binary, Predicate):
4504    pass
key = 'likeany'
class LT(Binary, Predicate):
4507class LT(Binary, Predicate):
4508    pass
key = 'lt'
class LTE(Binary, Predicate):
4511class LTE(Binary, Predicate):
4512    pass
key = 'lte'
class Mod(Binary):
4515class Mod(Binary):
4516    pass
key = 'mod'
class Mul(Binary):
4519class Mul(Binary):
4520    pass
key = 'mul'
class NEQ(Binary, Predicate):
4523class NEQ(Binary, Predicate):
4524    pass
key = 'neq'
class Operator(Binary):
4528class Operator(Binary):
4529    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4532class SimilarTo(Binary, Predicate):
4533    pass
key = 'similarto'
class Slice(Binary):
4536class Slice(Binary):
4537    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4540class Sub(Binary):
4541    pass
key = 'sub'
class Unary(Condition):
4546class Unary(Condition):
4547    pass
key = 'unary'
class BitwiseNot(Unary):
4550class BitwiseNot(Unary):
4551    pass
key = 'bitwisenot'
class Not(Unary):
4554class Not(Unary):
4555    pass
key = 'not'
class Paren(Unary):
4558class Paren(Unary):
4559    @property
4560    def output_name(self) -> str:
4561        return self.this.name
output_name: str
4559    @property
4560    def output_name(self) -> str:
4561        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):
4564class Neg(Unary):
4565    def to_py(self) -> int | Decimal:
4566        if self.is_number:
4567            return self.this.to_py() * -1
4568        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4565    def to_py(self) -> int | Decimal:
4566        if self.is_number:
4567            return self.this.to_py() * -1
4568        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4571class Alias(Expression):
4572    arg_types = {"this": True, "alias": False}
4573
4574    @property
4575    def output_name(self) -> str:
4576        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4574    @property
4575    def output_name(self) -> str:
4576        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):
4581class PivotAlias(Alias):
4582    pass
key = 'pivotalias'
class PivotAny(Expression):
4587class PivotAny(Expression):
4588    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4591class Aliases(Expression):
4592    arg_types = {"this": True, "expressions": True}
4593
4594    @property
4595    def aliases(self):
4596        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4594    @property
4595    def aliases(self):
4596        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4600class AtIndex(Expression):
4601    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4604class AtTimeZone(Expression):
4605    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4608class FromTimeZone(Expression):
4609    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4612class Between(Predicate):
4613    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4616class Bracket(Condition):
4617    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4618    arg_types = {
4619        "this": True,
4620        "expressions": True,
4621        "offset": False,
4622        "safe": False,
4623        "returns_list_for_maps": False,
4624    }
4625
4626    @property
4627    def output_name(self) -> str:
4628        if len(self.expressions) == 1:
4629            return self.expressions[0].output_name
4630
4631        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4626    @property
4627    def output_name(self) -> str:
4628        if len(self.expressions) == 1:
4629            return self.expressions[0].output_name
4630
4631        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):
4634class Distinct(Expression):
4635    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4638class In(Predicate):
4639    arg_types = {
4640        "this": True,
4641        "expressions": False,
4642        "query": False,
4643        "unnest": False,
4644        "field": False,
4645        "is_global": False,
4646    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4650class ForIn(Expression):
4651    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4654class TimeUnit(Expression):
4655    """Automatically converts unit arg into a var."""
4656
4657    arg_types = {"unit": False}
4658
4659    UNABBREVIATED_UNIT_NAME = {
4660        "D": "DAY",
4661        "H": "HOUR",
4662        "M": "MINUTE",
4663        "MS": "MILLISECOND",
4664        "NS": "NANOSECOND",
4665        "Q": "QUARTER",
4666        "S": "SECOND",
4667        "US": "MICROSECOND",
4668        "W": "WEEK",
4669        "Y": "YEAR",
4670    }
4671
4672    VAR_LIKE = (Column, Literal, Var)
4673
4674    def __init__(self, **args):
4675        unit = args.get("unit")
4676        if isinstance(unit, self.VAR_LIKE):
4677            args["unit"] = Var(
4678                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4679            )
4680        elif isinstance(unit, Week):
4681            unit.set("this", Var(this=unit.this.name.upper()))
4682
4683        super().__init__(**args)
4684
4685    @property
4686    def unit(self) -> t.Optional[Var | IntervalSpan]:
4687        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4674    def __init__(self, **args):
4675        unit = args.get("unit")
4676        if isinstance(unit, self.VAR_LIKE):
4677            args["unit"] = Var(
4678                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4679            )
4680        elif isinstance(unit, Week):
4681            unit.set("this", Var(this=unit.this.name.upper()))
4682
4683        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]
4685    @property
4686    def unit(self) -> t.Optional[Var | IntervalSpan]:
4687        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4690class IntervalOp(TimeUnit):
4691    arg_types = {"unit": True, "expression": True}
4692
4693    def interval(self):
4694        return Interval(
4695            this=self.expression.copy(),
4696            unit=self.unit.copy(),
4697        )
arg_types = {'unit': True, 'expression': True}
def interval(self):
4693    def interval(self):
4694        return Interval(
4695            this=self.expression.copy(),
4696            unit=self.unit.copy(),
4697        )
key = 'intervalop'
class IntervalSpan(DataType):
4703class IntervalSpan(DataType):
4704    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4707class Interval(TimeUnit):
4708    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4711class IgnoreNulls(Expression):
4712    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4715class RespectNulls(Expression):
4716    pass
key = 'respectnulls'
class HavingMax(Expression):
4720class HavingMax(Expression):
4721    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4725class Func(Condition):
4726    """
4727    The base class for all function expressions.
4728
4729    Attributes:
4730        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4731            treated as a variable length argument and the argument's value will be stored as a list.
4732        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4733            function expression. These values are used to map this node to a name during parsing as
4734            well as to provide the function's name during SQL string generation. By default the SQL
4735            name is set to the expression's class name transformed to snake case.
4736    """
4737
4738    is_var_len_args = False
4739
4740    @classmethod
4741    def from_arg_list(cls, args):
4742        if cls.is_var_len_args:
4743            all_arg_keys = list(cls.arg_types)
4744            # If this function supports variable length argument treat the last argument as such.
4745            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4746            num_non_var = len(non_var_len_arg_keys)
4747
4748            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4749            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4750        else:
4751            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4752
4753        return cls(**args_dict)
4754
4755    @classmethod
4756    def sql_names(cls):
4757        if cls is Func:
4758            raise NotImplementedError(
4759                "SQL name is only supported by concrete function implementations"
4760            )
4761        if "_sql_names" not in cls.__dict__:
4762            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4763        return cls._sql_names
4764
4765    @classmethod
4766    def sql_name(cls):
4767        return cls.sql_names()[0]
4768
4769    @classmethod
4770    def default_parser_mappings(cls):
4771        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):
4740    @classmethod
4741    def from_arg_list(cls, args):
4742        if cls.is_var_len_args:
4743            all_arg_keys = list(cls.arg_types)
4744            # If this function supports variable length argument treat the last argument as such.
4745            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4746            num_non_var = len(non_var_len_arg_keys)
4747
4748            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4749            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4750        else:
4751            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4752
4753        return cls(**args_dict)
@classmethod
def sql_names(cls):
4755    @classmethod
4756    def sql_names(cls):
4757        if cls is Func:
4758            raise NotImplementedError(
4759                "SQL name is only supported by concrete function implementations"
4760            )
4761        if "_sql_names" not in cls.__dict__:
4762            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4763        return cls._sql_names
@classmethod
def sql_name(cls):
4765    @classmethod
4766    def sql_name(cls):
4767        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4769    @classmethod
4770    def default_parser_mappings(cls):
4771        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4774class AggFunc(Func):
4775    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4778class ParameterizedAgg(AggFunc):
4779    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4782class Abs(Func):
4783    pass
key = 'abs'
class ArgMax(AggFunc):
4786class ArgMax(AggFunc):
4787    arg_types = {"this": True, "expression": True, "count": False}
4788    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4791class ArgMin(AggFunc):
4792    arg_types = {"this": True, "expression": True, "count": False}
4793    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4796class ApproxTopK(AggFunc):
4797    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4800class Flatten(Func):
4801    pass
key = 'flatten'
class Transform(Func):
4805class Transform(Func):
4806    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4809class Anonymous(Func):
4810    arg_types = {"this": True, "expressions": False}
4811    is_var_len_args = True
4812
4813    @property
4814    def name(self) -> str:
4815        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
4813    @property
4814    def name(self) -> str:
4815        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4818class AnonymousAggFunc(AggFunc):
4819    arg_types = {"this": True, "expressions": False}
4820    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4824class CombinedAggFunc(AnonymousAggFunc):
4825    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4828class CombinedParameterizedAgg(ParameterizedAgg):
4829    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):
4834class Hll(AggFunc):
4835    arg_types = {"this": True, "expressions": False}
4836    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4839class ApproxDistinct(AggFunc):
4840    arg_types = {"this": True, "accuracy": False}
4841    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4844class Array(Func):
4845    arg_types = {"expressions": False, "bracket_notation": False}
4846    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4850class ToArray(Func):
4851    pass
key = 'toarray'
class List(Func):
4855class List(Func):
4856    arg_types = {"expressions": False}
4857    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4861class Pad(Func):
4862    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):
4867class ToChar(Func):
4868    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4873class ToNumber(Func):
4874    arg_types = {
4875        "this": True,
4876        "format": False,
4877        "nlsparam": False,
4878        "precision": False,
4879        "scale": False,
4880    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4884class Convert(Func):
4885    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
4888class ConvertTimezone(Func):
4889    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True}
key = 'converttimezone'
class GenerateSeries(Func):
4892class GenerateSeries(Func):
4893    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
arg_types = {'start': True, 'end': True, 'step': False, 'is_end_exclusive': False}
key = 'generateseries'
class ExplodingGenerateSeries(GenerateSeries):
4899class ExplodingGenerateSeries(GenerateSeries):
4900    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
4903class ArrayAgg(AggFunc):
4904    pass
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4907class ArrayUniqueAgg(AggFunc):
4908    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4911class ArrayAll(Func):
4912    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4916class ArrayAny(Func):
4917    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4920class ArrayConcat(Func):
4921    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4922    arg_types = {"this": True, "expressions": False}
4923    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4926class ArrayConstructCompact(Func):
4927    arg_types = {"expressions": True}
4928    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4931class ArrayContains(Binary, Func):
4932    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
4935class ArrayContainsAll(Binary, Func):
4936    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
4939class ArrayFilter(Func):
4940    arg_types = {"this": True, "expression": True}
4941    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
4944class ArrayToString(Func):
4945    arg_types = {"this": True, "expression": True, "null": False}
4946    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
4949class StringToArray(Func):
4950    arg_types = {"this": True, "expression": True, "null": False}
4951    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
4954class ArrayOverlaps(Binary, Func):
4955    pass
key = 'arrayoverlaps'
class ArraySize(Func):
4958class ArraySize(Func):
4959    arg_types = {"this": True, "expression": False}
4960    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
4963class ArraySort(Func):
4964    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
4967class ArraySum(Func):
4968    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
4971class ArrayUnionAgg(AggFunc):
4972    pass
key = 'arrayunionagg'
class Avg(AggFunc):
4975class Avg(AggFunc):
4976    pass
key = 'avg'
class AnyValue(AggFunc):
4979class AnyValue(AggFunc):
4980    pass
key = 'anyvalue'
class Lag(AggFunc):
4983class Lag(AggFunc):
4984    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
4987class Lead(AggFunc):
4988    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
4993class First(AggFunc):
4994    pass
key = 'first'
class Last(AggFunc):
4997class Last(AggFunc):
4998    pass
key = 'last'
class FirstValue(AggFunc):
5001class FirstValue(AggFunc):
5002    pass
key = 'firstvalue'
class LastValue(AggFunc):
5005class LastValue(AggFunc):
5006    pass
key = 'lastvalue'
class NthValue(AggFunc):
5009class NthValue(AggFunc):
5010    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5013class Case(Func):
5014    arg_types = {"this": False, "ifs": True, "default": False}
5015
5016    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5017        instance = maybe_copy(self, copy)
5018        instance.append(
5019            "ifs",
5020            If(
5021                this=maybe_parse(condition, copy=copy, **opts),
5022                true=maybe_parse(then, copy=copy, **opts),
5023            ),
5024        )
5025        return instance
5026
5027    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5028        instance = maybe_copy(self, copy)
5029        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5030        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:
5016    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5017        instance = maybe_copy(self, copy)
5018        instance.append(
5019            "ifs",
5020            If(
5021                this=maybe_parse(condition, copy=copy, **opts),
5022                true=maybe_parse(then, copy=copy, **opts),
5023            ),
5024        )
5025        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5027    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5028        instance = maybe_copy(self, copy)
5029        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5030        return instance
key = 'case'
class Cast(Func):
5033class Cast(Func):
5034    arg_types = {
5035        "this": True,
5036        "to": True,
5037        "format": False,
5038        "safe": False,
5039        "action": False,
5040    }
5041
5042    @property
5043    def name(self) -> str:
5044        return self.this.name
5045
5046    @property
5047    def to(self) -> DataType:
5048        return self.args["to"]
5049
5050    @property
5051    def output_name(self) -> str:
5052        return self.name
5053
5054    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5055        """
5056        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5057        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5058        array<int> != array<float>.
5059
5060        Args:
5061            dtypes: the data types to compare this Cast's DataType to.
5062
5063        Returns:
5064            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5065        """
5066        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5042    @property
5043    def name(self) -> str:
5044        return self.this.name
to: DataType
5046    @property
5047    def to(self) -> DataType:
5048        return self.args["to"]
output_name: str
5050    @property
5051    def output_name(self) -> str:
5052        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:
5054    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5055        """
5056        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5057        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5058        array<int> != array<float>.
5059
5060        Args:
5061            dtypes: the data types to compare this Cast's DataType to.
5062
5063        Returns:
5064            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5065        """
5066        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):
5069class TryCast(Cast):
5070    pass
key = 'trycast'
class Try(Func):
5073class Try(Func):
5074    pass
key = 'try'
class CastToStrType(Func):
5077class CastToStrType(Func):
5078    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5081class Collate(Binary, Func):
5082    pass
key = 'collate'
class Ceil(Func):
5085class Ceil(Func):
5086    arg_types = {"this": True, "decimals": False}
5087    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5090class Coalesce(Func):
5091    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5092    is_var_len_args = True
5093    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5096class Chr(Func):
5097    arg_types = {"this": True, "charset": False, "expressions": False}
5098    is_var_len_args = True
5099    _sql_names = ["CHR", "CHAR"]
arg_types = {'this': True, 'charset': False, 'expressions': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5102class Concat(Func):
5103    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5104    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5107class ConcatWs(Concat):
5108    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5112class ConnectByRoot(Func):
5113    pass
key = 'connectbyroot'
class Count(AggFunc):
5116class Count(AggFunc):
5117    arg_types = {"this": False, "expressions": False}
5118    is_var_len_args = True
arg_types = {'this': False, 'expressions': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5121class CountIf(AggFunc):
5122    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5126class Cbrt(Func):
5127    pass
key = 'cbrt'
class CurrentDate(Func):
5130class CurrentDate(Func):
5131    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5134class CurrentDatetime(Func):
5135    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5138class CurrentTime(Func):
5139    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5142class CurrentTimestamp(Func):
5143    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5146class CurrentUser(Func):
5147    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5150class DateAdd(Func, IntervalOp):
5151    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5154class DateSub(Func, IntervalOp):
5155    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5158class DateDiff(Func, TimeUnit):
5159    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5160    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5163class DateTrunc(Func):
5164    arg_types = {"unit": True, "this": True, "zone": False}
5165
5166    def __init__(self, **args):
5167        unit = args.get("unit")
5168        if isinstance(unit, TimeUnit.VAR_LIKE):
5169            args["unit"] = Literal.string(
5170                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5171            )
5172        elif isinstance(unit, Week):
5173            unit.set("this", Literal.string(unit.this.name.upper()))
5174
5175        super().__init__(**args)
5176
5177    @property
5178    def unit(self) -> Expression:
5179        return self.args["unit"]
DateTrunc(**args)
5166    def __init__(self, **args):
5167        unit = args.get("unit")
5168        if isinstance(unit, TimeUnit.VAR_LIKE):
5169            args["unit"] = Literal.string(
5170                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5171            )
5172        elif isinstance(unit, Week):
5173            unit.set("this", Literal.string(unit.this.name.upper()))
5174
5175        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5177    @property
5178    def unit(self) -> Expression:
5179        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5184class Datetime(Func):
5185    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5188class DatetimeAdd(Func, IntervalOp):
5189    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5192class DatetimeSub(Func, IntervalOp):
5193    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5196class DatetimeDiff(Func, TimeUnit):
5197    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5200class DatetimeTrunc(Func, TimeUnit):
5201    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5204class DayOfWeek(Func):
5205    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfMonth(Func):
5208class DayOfMonth(Func):
5209    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5212class DayOfYear(Func):
5213    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5216class ToDays(Func):
5217    pass
key = 'todays'
class WeekOfYear(Func):
5220class WeekOfYear(Func):
5221    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5224class MonthsBetween(Func):
5225    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5228class LastDay(Func, TimeUnit):
5229    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5230    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5233class Extract(Func):
5234    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5237class Timestamp(Func):
5238    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5241class TimestampAdd(Func, TimeUnit):
5242    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5245class TimestampSub(Func, TimeUnit):
5246    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5249class TimestampDiff(Func, TimeUnit):
5250    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5251    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5254class TimestampTrunc(Func, TimeUnit):
5255    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5258class TimeAdd(Func, TimeUnit):
5259    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5262class TimeSub(Func, TimeUnit):
5263    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5266class TimeDiff(Func, TimeUnit):
5267    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5270class TimeTrunc(Func, TimeUnit):
5271    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5274class DateFromParts(Func):
5275    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5276    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5279class TimeFromParts(Func):
5280    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5281    arg_types = {
5282        "hour": True,
5283        "min": True,
5284        "sec": True,
5285        "nano": False,
5286        "fractions": False,
5287        "precision": False,
5288    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5291class DateStrToDate(Func):
5292    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5295class DateToDateStr(Func):
5296    pass
key = 'datetodatestr'
class DateToDi(Func):
5299class DateToDi(Func):
5300    pass
key = 'datetodi'
class Date(Func):
5304class Date(Func):
5305    arg_types = {"this": False, "zone": False, "expressions": False}
5306    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5309class Day(Func):
5310    pass
key = 'day'
class Decode(Func):
5313class Decode(Func):
5314    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5317class DiToDate(Func):
5318    pass
key = 'ditodate'
class Encode(Func):
5321class Encode(Func):
5322    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5325class Exp(Func):
5326    pass
key = 'exp'
class Explode(Func):
5330class Explode(Func):
5331    arg_types = {"this": True, "expressions": False}
5332    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class ExplodeOuter(Explode):
5335class ExplodeOuter(Explode):
5336    pass
key = 'explodeouter'
class Posexplode(Explode):
5339class Posexplode(Explode):
5340    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5343class PosexplodeOuter(Posexplode, ExplodeOuter):
5344    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5347class Unnest(Func, UDTF):
5348    arg_types = {
5349        "expressions": True,
5350        "alias": False,
5351        "offset": False,
5352        "explode_array": False,
5353    }
5354
5355    @property
5356    def selects(self) -> t.List[Expression]:
5357        columns = super().selects
5358        offset = self.args.get("offset")
5359        if offset:
5360            columns = columns + [to_identifier("offset") if offset is True else offset]
5361        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5355    @property
5356    def selects(self) -> t.List[Expression]:
5357        columns = super().selects
5358        offset = self.args.get("offset")
5359        if offset:
5360            columns = columns + [to_identifier("offset") if offset is True else offset]
5361        return columns
key = 'unnest'
class Floor(Func):
5364class Floor(Func):
5365    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5368class FromBase64(Func):
5369    pass
key = 'frombase64'
class ToBase64(Func):
5372class ToBase64(Func):
5373    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5377class FromISO8601Timestamp(Func):
5378    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5381class GapFill(Func):
5382    arg_types = {
5383        "this": True,
5384        "ts_column": True,
5385        "bucket_width": True,
5386        "partitioning_columns": False,
5387        "value_columns": False,
5388        "origin": False,
5389        "ignore_nulls": False,
5390    }
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):
5394class GenerateDateArray(Func):
5395    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5399class GenerateTimestampArray(Func):
5400    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5403class Greatest(Func):
5404    arg_types = {"this": True, "expressions": False}
5405    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5408class GroupConcat(AggFunc):
5409    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5412class Hex(Func):
5413    pass
key = 'hex'
class LowerHex(Hex):
5416class LowerHex(Hex):
5417    pass
key = 'lowerhex'
class Xor(Connector, Func):
5420class Xor(Connector, Func):
5421    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5424class If(Func):
5425    arg_types = {"this": True, "true": True, "false": False}
5426    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5429class Nullif(Func):
5430    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5433class Initcap(Func):
5434    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5437class IsNan(Func):
5438    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5441class IsInf(Func):
5442    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSONPath(Expression):
5445class JSONPath(Expression):
5446    arg_types = {"expressions": True}
5447
5448    @property
5449    def output_name(self) -> str:
5450        last_segment = self.expressions[-1].this
5451        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
5448    @property
5449    def output_name(self) -> str:
5450        last_segment = self.expressions[-1].this
5451        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):
5454class JSONPathPart(Expression):
5455    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5458class JSONPathFilter(JSONPathPart):
5459    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5462class JSONPathKey(JSONPathPart):
5463    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5466class JSONPathRecursive(JSONPathPart):
5467    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5470class JSONPathRoot(JSONPathPart):
5471    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5474class JSONPathScript(JSONPathPart):
5475    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5478class JSONPathSlice(JSONPathPart):
5479    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5482class JSONPathSelector(JSONPathPart):
5483    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5486class JSONPathSubscript(JSONPathPart):
5487    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5490class JSONPathUnion(JSONPathPart):
5491    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5494class JSONPathWildcard(JSONPathPart):
5495    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5498class FormatJson(Expression):
5499    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5502class JSONKeyValue(Expression):
5503    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5506class JSONObject(Func):
5507    arg_types = {
5508        "expressions": False,
5509        "null_handling": False,
5510        "unique_keys": False,
5511        "return_type": False,
5512        "encoding": False,
5513    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5516class JSONObjectAgg(AggFunc):
5517    arg_types = {
5518        "expressions": False,
5519        "null_handling": False,
5520        "unique_keys": False,
5521        "return_type": False,
5522        "encoding": False,
5523    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5527class JSONArray(Func):
5528    arg_types = {
5529        "expressions": True,
5530        "null_handling": False,
5531        "return_type": False,
5532        "strict": False,
5533    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5537class JSONArrayAgg(Func):
5538    arg_types = {
5539        "this": True,
5540        "order": False,
5541        "null_handling": False,
5542        "return_type": False,
5543        "strict": False,
5544    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONColumnDef(Expression):
5549class JSONColumnDef(Expression):
5550    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):
5553class JSONSchema(Expression):
5554    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONTable(Func):
5558class JSONTable(Func):
5559    arg_types = {
5560        "this": True,
5561        "schema": True,
5562        "path": False,
5563        "error_handling": False,
5564        "empty_handling": False,
5565    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5569class ObjectInsert(Func):
5570    arg_types = {
5571        "this": True,
5572        "key": True,
5573        "value": True,
5574        "update_flag": False,
5575    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5578class OpenJSONColumnDef(Expression):
5579    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):
5582class OpenJSON(Func):
5583    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5586class JSONBContains(Binary, Func):
5587    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5590class JSONExtract(Binary, Func):
5591    arg_types = {
5592        "this": True,
5593        "expression": True,
5594        "only_json_types": False,
5595        "expressions": False,
5596        "variant_extract": False,
5597    }
5598    _sql_names = ["JSON_EXTRACT"]
5599    is_var_len_args = True
5600
5601    @property
5602    def output_name(self) -> str:
5603        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
5601    @property
5602    def output_name(self) -> str:
5603        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):
5606class JSONExtractScalar(Binary, Func):
5607    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5608    _sql_names = ["JSON_EXTRACT_SCALAR"]
5609    is_var_len_args = True
5610
5611    @property
5612    def output_name(self) -> str:
5613        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
5611    @property
5612    def output_name(self) -> str:
5613        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):
5616class JSONBExtract(Binary, Func):
5617    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5620class JSONBExtractScalar(Binary, Func):
5621    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5624class JSONFormat(Func):
5625    arg_types = {"this": False, "options": False}
5626    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5630class JSONArrayContains(Binary, Predicate, Func):
5631    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5634class ParseJSON(Func):
5635    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5636    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5637    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5638    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5641class Least(Func):
5642    arg_types = {"this": True, "expressions": False}
5643    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5646class Left(Func):
5647    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5654class Length(Func):
5655    arg_types = {"this": True, "binary": False}
5656    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5659class Levenshtein(Func):
5660    arg_types = {
5661        "this": True,
5662        "expression": False,
5663        "ins_cost": False,
5664        "del_cost": False,
5665        "sub_cost": False,
5666    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5669class Ln(Func):
5670    pass
key = 'ln'
class Log(Func):
5673class Log(Func):
5674    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5677class LogicalOr(AggFunc):
5678    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5681class LogicalAnd(AggFunc):
5682    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5685class Lower(Func):
5686    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5689class Map(Func):
5690    arg_types = {"keys": False, "values": False}
5691
5692    @property
5693    def keys(self) -> t.List[Expression]:
5694        keys = self.args.get("keys")
5695        return keys.expressions if keys else []
5696
5697    @property
5698    def values(self) -> t.List[Expression]:
5699        values = self.args.get("values")
5700        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5692    @property
5693    def keys(self) -> t.List[Expression]:
5694        keys = self.args.get("keys")
5695        return keys.expressions if keys else []
values: List[Expression]
5697    @property
5698    def values(self) -> t.List[Expression]:
5699        values = self.args.get("values")
5700        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5704class ToMap(Func):
5705    pass
key = 'tomap'
class MapFromEntries(Func):
5708class MapFromEntries(Func):
5709    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5713class ScopeResolution(Expression):
5714    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
5717class Stream(Expression):
5718    pass
key = 'stream'
class StarMap(Func):
5721class StarMap(Func):
5722    pass
key = 'starmap'
class VarMap(Func):
5725class VarMap(Func):
5726    arg_types = {"keys": True, "values": True}
5727    is_var_len_args = True
5728
5729    @property
5730    def keys(self) -> t.List[Expression]:
5731        return self.args["keys"].expressions
5732
5733    @property
5734    def values(self) -> t.List[Expression]:
5735        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5729    @property
5730    def keys(self) -> t.List[Expression]:
5731        return self.args["keys"].expressions
values: List[Expression]
5733    @property
5734    def values(self) -> t.List[Expression]:
5735        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5739class MatchAgainst(Func):
5740    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5743class Max(AggFunc):
5744    arg_types = {"this": True, "expressions": False}
5745    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5748class MD5(Func):
5749    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5753class MD5Digest(Func):
5754    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5757class Min(AggFunc):
5758    arg_types = {"this": True, "expressions": False}
5759    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5762class Month(Func):
5763    pass
key = 'month'
class AddMonths(Func):
5766class AddMonths(Func):
5767    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5770class Nvl2(Func):
5771    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Predict(Func):
5775class Predict(Func):
5776    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5779class Pow(Binary, Func):
5780    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5783class PercentileCont(AggFunc):
5784    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5787class PercentileDisc(AggFunc):
5788    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5791class Quantile(AggFunc):
5792    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5795class ApproxQuantile(Quantile):
5796    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):
5799class Quarter(Func):
5800    pass
key = 'quarter'
class Rand(Func):
5805class Rand(Func):
5806    _sql_names = ["RAND", "RANDOM"]
5807    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5810class Randn(Func):
5811    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5814class RangeN(Func):
5815    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5818class ReadCSV(Func):
5819    _sql_names = ["READ_CSV"]
5820    is_var_len_args = True
5821    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5824class Reduce(Func):
5825    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):
5828class RegexpExtract(Func):
5829    arg_types = {
5830        "this": True,
5831        "expression": True,
5832        "position": False,
5833        "occurrence": False,
5834        "parameters": False,
5835        "group": False,
5836    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5839class RegexpReplace(Func):
5840    arg_types = {
5841        "this": True,
5842        "expression": True,
5843        "replacement": False,
5844        "position": False,
5845        "occurrence": False,
5846        "modifiers": False,
5847    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5850class RegexpLike(Binary, Func):
5851    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5854class RegexpILike(Binary, Func):
5855    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5860class RegexpSplit(Func):
5861    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5864class Repeat(Func):
5865    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5870class Round(Func):
5871    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5874class RowNumber(Func):
5875    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5878class SafeDivide(Func):
5879    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5882class SHA(Func):
5883    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5886class SHA2(Func):
5887    _sql_names = ["SHA2"]
5888    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5891class Sign(Func):
5892    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5895class SortArray(Func):
5896    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5899class Split(Func):
5900    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
5905class Substring(Func):
5906    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
5909class StandardHash(Func):
5910    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
5913class StartsWith(Func):
5914    _sql_names = ["STARTS_WITH", "STARTSWITH"]
5915    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
5918class StrPosition(Func):
5919    arg_types = {
5920        "this": True,
5921        "substr": True,
5922        "position": False,
5923        "instance": False,
5924    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
5927class StrToDate(Func):
5928    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
5931class StrToTime(Func):
5932    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):
5937class StrToUnix(Func):
5938    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
5943class StrToMap(Func):
5944    arg_types = {
5945        "this": True,
5946        "pair_delim": False,
5947        "key_value_delim": False,
5948        "duplicate_resolution_callback": False,
5949    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
5952class NumberToStr(Func):
5953    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
5956class FromBase(Func):
5957    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
5960class Struct(Func):
5961    arg_types = {"expressions": False}
5962    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
5965class StructExtract(Func):
5966    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
5971class Stuff(Func):
5972    _sql_names = ["STUFF", "INSERT"]
5973    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):
5976class Sum(AggFunc):
5977    pass
key = 'sum'
class Sqrt(Func):
5980class Sqrt(Func):
5981    pass
key = 'sqrt'
class Stddev(AggFunc):
5984class Stddev(AggFunc):
5985    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
5988class StddevPop(AggFunc):
5989    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
5992class StddevSamp(AggFunc):
5993    pass
key = 'stddevsamp'
class Time(Func):
5997class Time(Func):
5998    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6001class TimeToStr(Func):
6002    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
arg_types = {'this': True, 'format': True, 'culture': False, 'zone': False}
key = 'timetostr'
class TimeToTimeStr(Func):
6005class TimeToTimeStr(Func):
6006    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6009class TimeToUnix(Func):
6010    pass
key = 'timetounix'
class TimeStrToDate(Func):
6013class TimeStrToDate(Func):
6014    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6017class TimeStrToTime(Func):
6018    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6021class TimeStrToUnix(Func):
6022    pass
key = 'timestrtounix'
class Trim(Func):
6025class Trim(Func):
6026    arg_types = {
6027        "this": True,
6028        "expression": False,
6029        "position": False,
6030        "collation": False,
6031    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6034class TsOrDsAdd(Func, TimeUnit):
6035    # return_type is used to correctly cast the arguments of this expression when transpiling it
6036    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6037
6038    @property
6039    def return_type(self) -> DataType:
6040        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
6038    @property
6039    def return_type(self) -> DataType:
6040        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6043class TsOrDsDiff(Func, TimeUnit):
6044    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6047class TsOrDsToDateStr(Func):
6048    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6051class TsOrDsToDate(Func):
6052    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6055class TsOrDsToTime(Func):
6056    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6059class TsOrDsToTimestamp(Func):
6060    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6063class TsOrDiToDi(Func):
6064    pass
key = 'tsorditodi'
class Unhex(Func):
6067class Unhex(Func):
6068    pass
key = 'unhex'
class UnixDate(Func):
6072class UnixDate(Func):
6073    pass
key = 'unixdate'
class UnixToStr(Func):
6076class UnixToStr(Func):
6077    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6082class UnixToTime(Func):
6083    arg_types = {
6084        "this": True,
6085        "scale": False,
6086        "zone": False,
6087        "hours": False,
6088        "minutes": False,
6089        "format": False,
6090    }
6091
6092    SECONDS = Literal.number(0)
6093    DECIS = Literal.number(1)
6094    CENTIS = Literal.number(2)
6095    MILLIS = Literal.number(3)
6096    DECIMILLIS = Literal.number(4)
6097    CENTIMILLIS = Literal.number(5)
6098    MICROS = Literal.number(6)
6099    DECIMICROS = Literal.number(7)
6100    CENTIMICROS = Literal.number(8)
6101    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):
6104class UnixToTimeStr(Func):
6105    pass
key = 'unixtotimestr'
class TimestampFromParts(Func):
6108class TimestampFromParts(Func):
6109    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6110    arg_types = {
6111        "year": True,
6112        "month": True,
6113        "day": True,
6114        "hour": True,
6115        "min": True,
6116        "sec": True,
6117        "nano": False,
6118        "zone": False,
6119        "milli": False,
6120    }
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):
6123class Upper(Func):
6124    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6127class Corr(Binary, AggFunc):
6128    pass
key = 'corr'
class Variance(AggFunc):
6131class Variance(AggFunc):
6132    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6135class VariancePop(AggFunc):
6136    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6139class CovarSamp(Binary, AggFunc):
6140    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6143class CovarPop(Binary, AggFunc):
6144    pass
key = 'covarpop'
class Week(Func):
6147class Week(Func):
6148    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6151class XMLTable(Func):
6152    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):
6155class Year(Func):
6156    pass
key = 'year'
class Use(Expression):
6159class Use(Expression):
6160    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6163class Merge(Expression):
6164    arg_types = {
6165        "this": True,
6166        "using": True,
6167        "on": True,
6168        "expressions": True,
6169        "with": False,
6170    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False}
key = 'merge'
class When(Func):
6173class When(Func):
6174    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):
6179class NextValueFor(Func):
6180    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6185class Semicolon(Expression):
6186    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExtract'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'Time'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'When'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONVERT': <class 'Convert'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'IS_INF': <class 'IsInf'>, 'ISINF': <class 'IsInf'>, 'IS_NAN': <class 'IsNan'>, 'ISNAN': <class 'IsNan'>, 'J_S_O_N_ARRAY': <class 'JSONArray'>, 'J_S_O_N_ARRAY_AGG': <class 'JSONArrayAgg'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'LEVENSHTEIN': <class 'Levenshtein'>, 'LIST': <class 'List'>, 'LN': <class 'Ln'>, 'LOG': <class 'Log'>, 'LOGICAL_AND': <class 'LogicalAnd'>, 'BOOL_AND': <class 'LogicalAnd'>, 'BOOLAND_AGG': <class 'LogicalAnd'>, 'LOGICAL_OR': <class 'LogicalOr'>, 'BOOL_OR': <class 'LogicalOr'>, 'BOOLOR_AGG': <class 'LogicalOr'>, 'LOWER': <class 'Lower'>, 'LCASE': <class 'Lower'>, 'LOWER_HEX': <class 'LowerHex'>, 'MD5': <class 'MD5'>, 'MD5_DIGEST': <class 'MD5Digest'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NTH_VALUE': <class 'NthValue'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'PAD': <class 'Pad'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME': <class 'Time'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY': <class 'Try'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'UNHEX': <class 'Unhex'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_TO_STR': <class 'UnixToStr'>, 'UNIX_TO_TIME': <class 'UnixToTime'>, 'UNIX_TO_TIME_STR': <class 'UnixToTimeStr'>, 'UNNEST': <class 'Unnest'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'WHEN': <class 'When'>, 'X_M_L_TABLE': <class 'XMLTable'>, 'XOR': <class 'Xor'>, 'YEAR': <class 'Year'>}
JSON_PATH_PARTS = [<class 'JSONPathFilter'>, <class 'JSONPathKey'>, <class 'JSONPathRecursive'>, <class 'JSONPathRoot'>, <class 'JSONPathScript'>, <class 'JSONPathSelector'>, <class 'JSONPathSlice'>, <class 'JSONPathSubscript'>, <class 'JSONPathUnion'>, <class 'JSONPathWildcard'>]
PERCENTILES = (<class 'PercentileCont'>, <class 'PercentileDisc'>)
def maybe_parse( sql_or_expression: Union[str, Expression], *, into: Union[str, Type[Expression], Collection[Union[str, Type[Expression]]], NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
6226def maybe_parse(
6227    sql_or_expression: ExpOrStr,
6228    *,
6229    into: t.Optional[IntoType] = None,
6230    dialect: DialectType = None,
6231    prefix: t.Optional[str] = None,
6232    copy: bool = False,
6233    **opts,
6234) -> Expression:
6235    """Gracefully handle a possible string or expression.
6236
6237    Example:
6238        >>> maybe_parse("1")
6239        Literal(this=1, is_string=False)
6240        >>> maybe_parse(to_identifier("x"))
6241        Identifier(this=x, quoted=False)
6242
6243    Args:
6244        sql_or_expression: the SQL code string or an expression
6245        into: the SQLGlot Expression to parse into
6246        dialect: the dialect used to parse the input expressions (in the case that an
6247            input expression is a SQL string).
6248        prefix: a string to prefix the sql with before it gets parsed
6249            (automatically includes a space)
6250        copy: whether to copy the expression.
6251        **opts: other options to use to parse the input expressions (again, in the case
6252            that an input expression is a SQL string).
6253
6254    Returns:
6255        Expression: the parsed or given expression.
6256    """
6257    if isinstance(sql_or_expression, Expression):
6258        if copy:
6259            return sql_or_expression.copy()
6260        return sql_or_expression
6261
6262    if sql_or_expression is None:
6263        raise ParseError("SQL cannot be None")
6264
6265    import sqlglot
6266
6267    sql = str(sql_or_expression)
6268    if prefix:
6269        sql = f"{prefix} {sql}"
6270
6271    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):
6282def maybe_copy(instance, copy=True):
6283    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:
6503def union(
6504    left: ExpOrStr,
6505    right: ExpOrStr,
6506    distinct: bool = True,
6507    dialect: DialectType = None,
6508    copy: bool = True,
6509    **opts,
6510) -> Union:
6511    """
6512    Initializes a syntax tree from one UNION expression.
6513
6514    Example:
6515        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6516        'SELECT * FROM foo UNION SELECT * FROM bla'
6517
6518    Args:
6519        left: the SQL code string corresponding to the left-hand side.
6520            If an `Expression` instance is passed, it will be used as-is.
6521        right: the SQL code string corresponding to the right-hand side.
6522            If an `Expression` instance is passed, it will be used as-is.
6523        distinct: set the DISTINCT flag if and only if this is true.
6524        dialect: the dialect used to parse the input expression.
6525        copy: whether to copy the expression.
6526        opts: other options to use to parse the input expressions.
6527
6528    Returns:
6529        The new Union instance.
6530    """
6531    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6532    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6533
6534    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:
6537def intersect(
6538    left: ExpOrStr,
6539    right: ExpOrStr,
6540    distinct: bool = True,
6541    dialect: DialectType = None,
6542    copy: bool = True,
6543    **opts,
6544) -> Intersect:
6545    """
6546    Initializes a syntax tree from one INTERSECT expression.
6547
6548    Example:
6549        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6550        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6551
6552    Args:
6553        left: the SQL code string corresponding to the left-hand side.
6554            If an `Expression` instance is passed, it will be used as-is.
6555        right: the SQL code string corresponding to the right-hand side.
6556            If an `Expression` instance is passed, it will be used as-is.
6557        distinct: set the DISTINCT flag if and only if this is true.
6558        dialect: the dialect used to parse the input expression.
6559        copy: whether to copy the expression.
6560        opts: other options to use to parse the input expressions.
6561
6562    Returns:
6563        The new Intersect instance.
6564    """
6565    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6566    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6567
6568    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:
6571def except_(
6572    left: ExpOrStr,
6573    right: ExpOrStr,
6574    distinct: bool = True,
6575    dialect: DialectType = None,
6576    copy: bool = True,
6577    **opts,
6578) -> Except:
6579    """
6580    Initializes a syntax tree from one EXCEPT expression.
6581
6582    Example:
6583        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6584        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6585
6586    Args:
6587        left: the SQL code string corresponding to the left-hand side.
6588            If an `Expression` instance is passed, it will be used as-is.
6589        right: the SQL code string corresponding to the right-hand side.
6590            If an `Expression` instance is passed, it will be used as-is.
6591        distinct: set the DISTINCT flag if and only if this is true.
6592        dialect: the dialect used to parse the input expression.
6593        copy: whether to copy the expression.
6594        opts: other options to use to parse the input expressions.
6595
6596    Returns:
6597        The new Except instance.
6598    """
6599    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6600    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6601
6602    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:
6605def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6606    """
6607    Initializes a syntax tree from one or multiple SELECT expressions.
6608
6609    Example:
6610        >>> select("col1", "col2").from_("tbl").sql()
6611        'SELECT col1, col2 FROM tbl'
6612
6613    Args:
6614        *expressions: the SQL code string to parse as the expressions of a
6615            SELECT statement. If an Expression instance is passed, this is used as-is.
6616        dialect: the dialect used to parse the input expressions (in the case that an
6617            input expression is a SQL string).
6618        **opts: other options to use to parse the input expressions (again, in the case
6619            that an input expression is a SQL string).
6620
6621    Returns:
6622        Select: the syntax tree for the SELECT statement.
6623    """
6624    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:
6627def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6628    """
6629    Initializes a syntax tree from a FROM expression.
6630
6631    Example:
6632        >>> from_("tbl").select("col1", "col2").sql()
6633        'SELECT col1, col2 FROM tbl'
6634
6635    Args:
6636        *expression: the SQL code string to parse as the FROM expressions of a
6637            SELECT statement. If an Expression instance is passed, this is used as-is.
6638        dialect: the dialect used to parse the input expression (in the case that the
6639            input expression is a SQL string).
6640        **opts: other options to use to parse the input expressions (again, in the case
6641            that the input expression is a SQL string).
6642
6643    Returns:
6644        Select: the syntax tree for the SELECT statement.
6645    """
6646    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:
6649def update(
6650    table: str | Table,
6651    properties: dict,
6652    where: t.Optional[ExpOrStr] = None,
6653    from_: t.Optional[ExpOrStr] = None,
6654    dialect: DialectType = None,
6655    **opts,
6656) -> Update:
6657    """
6658    Creates an update statement.
6659
6660    Example:
6661        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6662        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6663
6664    Args:
6665        *properties: dictionary of properties to set which are
6666            auto converted to sql objects eg None -> NULL
6667        where: sql conditional parsed into a WHERE statement
6668        from_: sql statement parsed into a FROM statement
6669        dialect: the dialect used to parse the input expressions.
6670        **opts: other options to use to parse the input expressions.
6671
6672    Returns:
6673        Update: the syntax tree for the UPDATE statement.
6674    """
6675    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6676    update_expr.set(
6677        "expressions",
6678        [
6679            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6680            for k, v in properties.items()
6681        ],
6682    )
6683    if from_:
6684        update_expr.set(
6685            "from",
6686            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6687        )
6688    if isinstance(where, Condition):
6689        where = Where(this=where)
6690    if where:
6691        update_expr.set(
6692            "where",
6693            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6694        )
6695    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:
6698def delete(
6699    table: ExpOrStr,
6700    where: t.Optional[ExpOrStr] = None,
6701    returning: t.Optional[ExpOrStr] = None,
6702    dialect: DialectType = None,
6703    **opts,
6704) -> Delete:
6705    """
6706    Builds a delete statement.
6707
6708    Example:
6709        >>> delete("my_table", where="id > 1").sql()
6710        'DELETE FROM my_table WHERE id > 1'
6711
6712    Args:
6713        where: sql conditional parsed into a WHERE statement
6714        returning: sql conditional parsed into a RETURNING statement
6715        dialect: the dialect used to parse the input expressions.
6716        **opts: other options to use to parse the input expressions.
6717
6718    Returns:
6719        Delete: the syntax tree for the DELETE statement.
6720    """
6721    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6722    if where:
6723        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6724    if returning:
6725        delete_expr = t.cast(
6726            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6727        )
6728    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:
6731def insert(
6732    expression: ExpOrStr,
6733    into: ExpOrStr,
6734    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6735    overwrite: t.Optional[bool] = None,
6736    returning: t.Optional[ExpOrStr] = None,
6737    dialect: DialectType = None,
6738    copy: bool = True,
6739    **opts,
6740) -> Insert:
6741    """
6742    Builds an INSERT statement.
6743
6744    Example:
6745        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6746        'INSERT INTO tbl VALUES (1, 2, 3)'
6747
6748    Args:
6749        expression: the sql string or expression of the INSERT statement
6750        into: the tbl to insert data to.
6751        columns: optionally the table's column names.
6752        overwrite: whether to INSERT OVERWRITE or not.
6753        returning: sql conditional parsed into a RETURNING statement
6754        dialect: the dialect used to parse the input expressions.
6755        copy: whether to copy the expression.
6756        **opts: other options to use to parse the input expressions.
6757
6758    Returns:
6759        Insert: the syntax tree for the INSERT statement.
6760    """
6761    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6762    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6763
6764    if columns:
6765        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6766
6767    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6768
6769    if returning:
6770        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6771
6772    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:
6775def condition(
6776    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6777) -> Condition:
6778    """
6779    Initialize a logical condition expression.
6780
6781    Example:
6782        >>> condition("x=1").sql()
6783        'x = 1'
6784
6785        This is helpful for composing larger logical syntax trees:
6786        >>> where = condition("x=1")
6787        >>> where = where.and_("y=1")
6788        >>> Select().from_("tbl").select("*").where(where).sql()
6789        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6790
6791    Args:
6792        *expression: the SQL code string to parse.
6793            If an Expression instance is passed, this is used as-is.
6794        dialect: the dialect used to parse the input expression (in the case that the
6795            input expression is a SQL string).
6796        copy: Whether to copy `expression` (only applies to expressions).
6797        **opts: other options to use to parse the input expressions (again, in the case
6798            that the input expression is a SQL string).
6799
6800    Returns:
6801        The new Condition instance
6802    """
6803    return maybe_parse(
6804        expression,
6805        into=Condition,
6806        dialect=dialect,
6807        copy=copy,
6808        **opts,
6809    )

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:
6812def and_(
6813    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6814) -> Condition:
6815    """
6816    Combine multiple conditions with an AND logical operator.
6817
6818    Example:
6819        >>> and_("x=1", and_("y=1", "z=1")).sql()
6820        'x = 1 AND (y = 1 AND z = 1)'
6821
6822    Args:
6823        *expressions: the SQL code strings to parse.
6824            If an Expression instance is passed, this is used as-is.
6825        dialect: the dialect used to parse the input expression.
6826        copy: whether to copy `expressions` (only applies to Expressions).
6827        **opts: other options to use to parse the input expressions.
6828
6829    Returns:
6830        The new condition
6831    """
6832    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:
6835def or_(
6836    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6837) -> Condition:
6838    """
6839    Combine multiple conditions with an OR logical operator.
6840
6841    Example:
6842        >>> or_("x=1", or_("y=1", "z=1")).sql()
6843        'x = 1 OR (y = 1 OR z = 1)'
6844
6845    Args:
6846        *expressions: the SQL code strings to parse.
6847            If an Expression instance is passed, this is used as-is.
6848        dialect: the dialect used to parse the input expression.
6849        copy: whether to copy `expressions` (only applies to Expressions).
6850        **opts: other options to use to parse the input expressions.
6851
6852    Returns:
6853        The new condition
6854    """
6855    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:
6858def xor(
6859    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6860) -> Condition:
6861    """
6862    Combine multiple conditions with an XOR logical operator.
6863
6864    Example:
6865        >>> xor("x=1", xor("y=1", "z=1")).sql()
6866        'x = 1 XOR (y = 1 XOR z = 1)'
6867
6868    Args:
6869        *expressions: the SQL code strings to parse.
6870            If an Expression instance is passed, this is used as-is.
6871        dialect: the dialect used to parse the input expression.
6872        copy: whether to copy `expressions` (only applies to Expressions).
6873        **opts: other options to use to parse the input expressions.
6874
6875    Returns:
6876        The new condition
6877    """
6878    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:
6881def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
6882    """
6883    Wrap a condition with a NOT operator.
6884
6885    Example:
6886        >>> not_("this_suit='black'").sql()
6887        "NOT this_suit = 'black'"
6888
6889    Args:
6890        expression: the SQL code string to parse.
6891            If an Expression instance is passed, this is used as-is.
6892        dialect: the dialect used to parse the input expression.
6893        copy: whether to copy the expression or not.
6894        **opts: other options to use to parse the input expressions.
6895
6896    Returns:
6897        The new condition.
6898    """
6899    this = condition(
6900        expression,
6901        dialect=dialect,
6902        copy=copy,
6903        **opts,
6904    )
6905    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:
6908def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
6909    """
6910    Wrap an expression in parentheses.
6911
6912    Example:
6913        >>> paren("5 + 3").sql()
6914        '(5 + 3)'
6915
6916    Args:
6917        expression: the SQL code string to parse.
6918            If an Expression instance is passed, this is used as-is.
6919        copy: whether to copy the expression or not.
6920
6921    Returns:
6922        The wrapped expression.
6923    """
6924    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):
6940def to_identifier(name, quoted=None, copy=True):
6941    """Builds an identifier.
6942
6943    Args:
6944        name: The name to turn into an identifier.
6945        quoted: Whether to force quote the identifier.
6946        copy: Whether to copy name if it's an Identifier.
6947
6948    Returns:
6949        The identifier ast node.
6950    """
6951
6952    if name is None:
6953        return None
6954
6955    if isinstance(name, Identifier):
6956        identifier = maybe_copy(name, copy)
6957    elif isinstance(name, str):
6958        identifier = Identifier(
6959            this=name,
6960            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
6961        )
6962    else:
6963        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
6964    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:
6967def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
6968    """
6969    Parses a given string into an identifier.
6970
6971    Args:
6972        name: The name to parse into an identifier.
6973        dialect: The dialect to parse against.
6974
6975    Returns:
6976        The identifier ast node.
6977    """
6978    try:
6979        expression = maybe_parse(name, dialect=dialect, into=Identifier)
6980    except (ParseError, TokenError):
6981        expression = to_identifier(name)
6982
6983    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:
6989def to_interval(interval: str | Literal) -> Interval:
6990    """Builds an interval expression from a string like '1 day' or '5 months'."""
6991    if isinstance(interval, Literal):
6992        if not interval.is_string:
6993            raise ValueError("Invalid interval string.")
6994
6995        interval = interval.this
6996
6997    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
6998
6999    if not interval_parts:
7000        raise ValueError("Invalid interval string.")
7001
7002    return Interval(
7003        this=Literal.string(interval_parts.group(1)),
7004        unit=Var(this=interval_parts.group(2).upper()),
7005    )

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

Build a Column.

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

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Cast:
7226def cast(
7227    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7228) -> Cast:
7229    """Cast an expression to a data type.
7230
7231    Example:
7232        >>> cast('x + 1', 'int').sql()
7233        'CAST(x + 1 AS INT)'
7234
7235    Args:
7236        expression: The expression to cast.
7237        to: The datatype to cast to.
7238        copy: Whether to copy the supplied expressions.
7239        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7240            - The expression to be cast is already a exp.Cast expression
7241            - The existing cast is to a type that is logically equivalent to new type
7242
7243            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7244            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7245            and instead just return the original expression `CAST(x as DATETIME)`.
7246
7247            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7248            mapping is applied in the target dialect generator.
7249
7250    Returns:
7251        The new Cast instance.
7252    """
7253    expr = maybe_parse(expression, copy=copy, **opts)
7254    data_type = DataType.build(to, copy=copy, **opts)
7255
7256    # dont re-cast if the expression is already a cast to the correct type
7257    if isinstance(expr, Cast):
7258        from sqlglot.dialects.dialect import Dialect
7259
7260        target_dialect = Dialect.get_or_raise(dialect)
7261        type_mapping = target_dialect.generator_class.TYPE_MAPPING
7262
7263        existing_cast_type: DataType.Type = expr.to.this
7264        new_cast_type: DataType.Type = data_type.this
7265        types_are_equivalent = type_mapping.get(
7266            existing_cast_type, existing_cast_type
7267        ) == type_mapping.get(new_cast_type, new_cast_type)
7268        if expr.is_type(data_type) or types_are_equivalent:
7269            return expr
7270
7271    expr = Cast(this=expr, to=data_type)
7272    expr.type = data_type
7273
7274    return expr

Cast an expression to a data type.

Example:
>>> cast('x + 1', 'int').sql()
'CAST(x + 1 AS INT)'
Arguments:
  • expression: The expression to cast.
  • to: The datatype to cast to.
  • copy: Whether to copy the supplied expressions.
  • dialect: The target dialect. This is used to prevent a re-cast in the following scenario:

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

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

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

Returns:

The new Cast instance.

def table_( table: Identifier | str, db: Union[Identifier, str, NoneType] = None, catalog: Union[Identifier, str, NoneType] = None, quoted: Optional[bool] = None, alias: Union[Identifier, str, NoneType] = None) -> Table:
7277def table_(
7278    table: Identifier | str,
7279    db: t.Optional[Identifier | str] = None,
7280    catalog: t.Optional[Identifier | str] = None,
7281    quoted: t.Optional[bool] = None,
7282    alias: t.Optional[Identifier | str] = None,
7283) -> Table:
7284    """Build a Table.
7285
7286    Args:
7287        table: Table name.
7288        db: Database name.
7289        catalog: Catalog name.
7290        quote: Whether to force quotes on the table's identifiers.
7291        alias: Table's alias.
7292
7293    Returns:
7294        The new Table instance.
7295    """
7296    return Table(
7297        this=to_identifier(table, quoted=quoted) if table else None,
7298        db=to_identifier(db, quoted=quoted) if db else None,
7299        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7300        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7301    )

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:
7304def values(
7305    values: t.Iterable[t.Tuple[t.Any, ...]],
7306    alias: t.Optional[str] = None,
7307    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7308) -> Values:
7309    """Build VALUES statement.
7310
7311    Example:
7312        >>> values([(1, '2')]).sql()
7313        "VALUES (1, '2')"
7314
7315    Args:
7316        values: values statements that will be converted to SQL
7317        alias: optional alias
7318        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7319         If either are provided then an alias is also required.
7320
7321    Returns:
7322        Values: the Values expression object
7323    """
7324    if columns and not alias:
7325        raise ValueError("Alias is required when providing columns")
7326
7327    return Values(
7328        expressions=[convert(tup) for tup in values],
7329        alias=(
7330            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7331            if columns
7332            else (TableAlias(this=to_identifier(alias)) if alias else None)
7333        ),
7334    )

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:
7337def var(name: t.Optional[ExpOrStr]) -> Var:
7338    """Build a SQL variable.
7339
7340    Example:
7341        >>> repr(var('x'))
7342        'Var(this=x)'
7343
7344        >>> repr(var(column('x', table='y')))
7345        'Var(this=x)'
7346
7347    Args:
7348        name: The name of the var or an expression who's name will become the var.
7349
7350    Returns:
7351        The new variable node.
7352    """
7353    if not name:
7354        raise ValueError("Cannot convert empty name into var.")
7355
7356    if isinstance(name, Expression):
7357        name = name.name
7358    return Var(this=name)

Build a SQL variable.

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

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Alter:
7361def rename_table(
7362    old_name: str | Table,
7363    new_name: str | Table,
7364    dialect: DialectType = None,
7365) -> Alter:
7366    """Build ALTER TABLE... RENAME... expression
7367
7368    Args:
7369        old_name: The old name of the table
7370        new_name: The new name of the table
7371        dialect: The dialect to parse the table.
7372
7373    Returns:
7374        Alter table expression
7375    """
7376    old_table = to_table(old_name, dialect=dialect)
7377    new_table = to_table(new_name, dialect=dialect)
7378    return Alter(
7379        this=old_table,
7380        kind="TABLE",
7381        actions=[
7382            RenameTable(this=new_table),
7383        ],
7384    )

Build ALTER TABLE... RENAME... expression

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

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Alter:
7387def rename_column(
7388    table_name: str | Table,
7389    old_column_name: str | Column,
7390    new_column_name: str | Column,
7391    exists: t.Optional[bool] = None,
7392    dialect: DialectType = None,
7393) -> Alter:
7394    """Build ALTER TABLE... RENAME COLUMN... expression
7395
7396    Args:
7397        table_name: Name of the table
7398        old_column: The old name of the column
7399        new_column: The new name of the column
7400        exists: Whether to add the `IF EXISTS` clause
7401        dialect: The dialect to parse the table/column.
7402
7403    Returns:
7404        Alter table expression
7405    """
7406    table = to_table(table_name, dialect=dialect)
7407    old_column = to_column(old_column_name, dialect=dialect)
7408    new_column = to_column(new_column_name, dialect=dialect)
7409    return Alter(
7410        this=table,
7411        kind="TABLE",
7412        actions=[
7413            RenameColumn(this=old_column, to=new_column, exists=exists),
7414        ],
7415    )

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

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:
7552def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7553    """Get the full name of a table as a string.
7554
7555    Args:
7556        table: Table expression node or string.
7557        dialect: The dialect to generate the table name for.
7558        identify: Determines when an identifier should be quoted. Possible values are:
7559            False (default): Never quote, except in cases where it's mandatory by the dialect.
7560            True: Always quote.
7561
7562    Examples:
7563        >>> from sqlglot import exp, parse_one
7564        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7565        'a.b.c'
7566
7567    Returns:
7568        The table name.
7569    """
7570
7571    table = maybe_parse(table, into=Table, dialect=dialect)
7572
7573    if not table:
7574        raise ValueError(f"Cannot parse {table}")
7575
7576    return ".".join(
7577        (
7578            part.sql(dialect=dialect, identify=True, copy=False)
7579            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7580            else part.name
7581        )
7582        for part in table.parts
7583    )

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:
7586def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7587    """Returns a case normalized table name without quotes.
7588
7589    Args:
7590        table: the table to normalize
7591        dialect: the dialect to use for normalization rules
7592        copy: whether to copy the expression.
7593
7594    Examples:
7595        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7596        'A-B.c'
7597    """
7598    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7599
7600    return ".".join(
7601        p.name
7602        for p in normalize_identifiers(
7603            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7604        ).parts
7605    )

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

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:
7835def tuple_(
7836    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7837) -> Tuple:
7838    """
7839    Returns an tuple.
7840
7841    Examples:
7842        >>> tuple_(1, 'x').sql()
7843        '(1, x)'
7844
7845    Args:
7846        expressions: the expressions to add to the tuple.
7847        copy: whether to copy the argument expressions.
7848        dialect: the source dialect.
7849        kwargs: the kwargs used to instantiate the function of interest.
7850
7851    Returns:
7852        A tuple expression.
7853    """
7854    return Tuple(
7855        expressions=[
7856            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
7857            for expression in expressions
7858        ]
7859    )

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:
7862def true() -> Boolean:
7863    """
7864    Returns a true Boolean expression.
7865    """
7866    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
7869def false() -> Boolean:
7870    """
7871    Returns a false Boolean expression.
7872    """
7873    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
7876def null() -> Null:
7877    """
7878    Returns a Null expression.
7879    """
7880    return Null()

Returns a Null expression.

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