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

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
405    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
406        """Yields the key and expression for all arguments, exploding list args."""
407        # remove tuple when python 3.7 is deprecated
408        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
409            if type(vs) is list:
410                for v in reversed(vs) if reverse else vs:
411                    if hasattr(v, "parent"):
412                        yield v
413            else:
414                if hasattr(vs, "parent"):
415                    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]:
417    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
418        """
419        Returns the first node in this tree which matches at least one of
420        the specified types.
421
422        Args:
423            expression_types: the expression type(s) to match.
424            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
425
426        Returns:
427            The node which matches the criteria or None if no such node was found.
428        """
429        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]:
431    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
432        """
433        Returns a generator object which visits all nodes in this tree and only
434        yields those that match at least one of the specified expression types.
435
436        Args:
437            expression_types: the expression type(s) to match.
438            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
439
440        Returns:
441            The generator object.
442        """
443        for expression in self.walk(bfs=bfs):
444            if isinstance(expression, expression_types):
445                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]:
447    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
448        """
449        Returns a nearest parent matching expression_types.
450
451        Args:
452            expression_types: the expression type(s) to match.
453
454        Returns:
455            The parent node.
456        """
457        ancestor = self.parent
458        while ancestor and not isinstance(ancestor, expression_types):
459            ancestor = ancestor.parent
460        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]
462    @property
463    def parent_select(self) -> t.Optional[Select]:
464        """
465        Returns the parent select statement.
466        """
467        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
469    @property
470    def same_parent(self) -> bool:
471        """Returns if the parent is the same class as itself."""
472        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
474    def root(self) -> Expression:
475        """
476        Returns the root expression of this tree.
477        """
478        expression = self
479        while expression.parent:
480            expression = expression.parent
481        return expression

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
483    def walk(
484        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
485    ) -> t.Iterator[Expression]:
486        """
487        Returns a generator object which visits all nodes in this tree.
488
489        Args:
490            bfs: if set to True the BFS traversal order will be applied,
491                otherwise the DFS traversal will be used instead.
492            prune: callable that returns True if the generator should stop traversing
493                this branch of the tree.
494
495        Returns:
496            the generator object.
497        """
498        if bfs:
499            yield from self.bfs(prune=prune)
500        else:
501            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]:
503    def dfs(
504        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
505    ) -> t.Iterator[Expression]:
506        """
507        Returns a generator object which visits all nodes in this tree in
508        the DFS (Depth-first) order.
509
510        Returns:
511            The generator object.
512        """
513        stack = [self]
514
515        while stack:
516            node = stack.pop()
517
518            yield node
519
520            if prune and prune(node):
521                continue
522
523            for v in node.iter_expressions(reverse=True):
524                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]:
526    def bfs(
527        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
528    ) -> t.Iterator[Expression]:
529        """
530        Returns a generator object which visits all nodes in this tree in
531        the BFS (Breadth-first) order.
532
533        Returns:
534            The generator object.
535        """
536        queue = deque([self])
537
538        while queue:
539            node = queue.popleft()
540
541            yield node
542
543            if prune and prune(node):
544                continue
545
546            for v in node.iter_expressions():
547                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):
549    def unnest(self):
550        """
551        Returns the first non parenthesis child or self.
552        """
553        expression = self
554        while type(expression) is Paren:
555            expression = expression.this
556        return expression

Returns the first non parenthesis child or self.

def unalias(self):
558    def unalias(self):
559        """
560        Returns the inner expression if this is an Alias.
561        """
562        if isinstance(self, Alias):
563            return self.this
564        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
566    def unnest_operands(self):
567        """
568        Returns unnested operands as a tuple.
569        """
570        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
572    def flatten(self, unnest=True):
573        """
574        Returns a generator which yields child nodes whose parents are the same class.
575
576        A AND B AND C -> [A, B, C]
577        """
578        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
579            if type(node) is not self.__class__:
580                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:
588    def to_s(self) -> str:
589        """
590        Same as __repr__, but includes additional information which can be useful
591        for debugging, like empty or missing args and the AST nodes' object IDs.
592        """
593        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:
595    def sql(self, dialect: DialectType = None, **opts) -> str:
596        """
597        Returns SQL string representation of this tree.
598
599        Args:
600            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
601            opts: other `sqlglot.generator.Generator` options.
602
603        Returns:
604            The SQL string.
605        """
606        from sqlglot.dialects import Dialect
607
608        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:
610    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
611        """
612        Visits all tree nodes (excluding already transformed ones)
613        and applies the given transformation function to each node.
614
615        Args:
616            fun: a function which takes a node as an argument and returns a
617                new transformed node or the same node without modifications. If the function
618                returns None, then the corresponding node will be removed from the syntax tree.
619            copy: if set to True a new tree instance is constructed, otherwise the tree is
620                modified in place.
621
622        Returns:
623            The transformed tree.
624        """
625        root = None
626        new_node = None
627
628        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
629            parent, arg_key, index = node.parent, node.arg_key, node.index
630            new_node = fun(node, *args, **kwargs)
631
632            if not root:
633                root = new_node
634            elif new_node is not node:
635                parent.set(arg_key, new_node, index)
636
637        assert root
638        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):
646    def replace(self, expression):
647        """
648        Swap out this expression with a new expression.
649
650        For example::
651
652            >>> tree = Select().select("x").from_("tbl")
653            >>> tree.find(Column).replace(column("y"))
654            Column(
655              this=Identifier(this=y, quoted=False))
656            >>> tree.sql()
657            'SELECT y FROM tbl'
658
659        Args:
660            expression: new node
661
662        Returns:
663            The new expression or expressions.
664        """
665        parent = self.parent
666
667        if not parent or parent is expression:
668            return expression
669
670        key = self.arg_key
671        value = parent.args.get(key)
672
673        if type(expression) is list and isinstance(value, Expression):
674            # We are trying to replace an Expression with a list, so it's assumed that
675            # the intention was to really replace the parent of this expression.
676            value.parent.replace(expression)
677        else:
678            parent.set(key, expression, self.index)
679
680        if expression is not self:
681            self.parent = None
682            self.arg_key = None
683            self.index = None
684
685        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:
687    def pop(self: E) -> E:
688        """
689        Remove this expression from its AST.
690
691        Returns:
692            The popped expression.
693        """
694        self.replace(None)
695        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
697    def assert_is(self, type_: t.Type[E]) -> E:
698        """
699        Assert that this `Expression` is an instance of `type_`.
700
701        If it is NOT an instance of `type_`, this raises an assertion error.
702        Otherwise, this returns this expression.
703
704        Examples:
705            This is useful for type security in chained expressions:
706
707            >>> import sqlglot
708            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
709            'SELECT x, z FROM y'
710        """
711        if not isinstance(self, type_):
712            raise AssertionError(f"{self} is not {type_}.")
713        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]:
715    def error_messages(self, args: t.Optional[t.Sequence] = None) -> t.List[str]:
716        """
717        Checks if this expression is valid (e.g. all mandatory args are set).
718
719        Args:
720            args: a sequence of values that were used to instantiate a Func expression. This is used
721                to check that the provided arguments don't exceed the function argument limit.
722
723        Returns:
724            A list of error messages for all possible errors that were found.
725        """
726        errors: t.List[str] = []
727
728        for k in self.args:
729            if k not in self.arg_types:
730                errors.append(f"Unexpected keyword: '{k}' for {self.__class__}")
731        for k, mandatory in self.arg_types.items():
732            v = self.args.get(k)
733            if mandatory and (v is None or (isinstance(v, list) and not v)):
734                errors.append(f"Required keyword: '{k}' missing for {self.__class__}")
735
736        if (
737            args
738            and isinstance(self, Func)
739            and len(args) > len(self.arg_types)
740            and not self.is_var_len_args
741        ):
742            errors.append(
743                f"The number of provided arguments ({len(args)}) is greater than "
744                f"the maximum number of supported arguments ({len(self.arg_types)})"
745            )
746
747        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):
749    def dump(self):
750        """
751        Dump this Expression to a JSON-serializable dict.
752        """
753        from sqlglot.serde import dump
754
755        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
757    @classmethod
758    def load(cls, obj):
759        """
760        Load a dict (as returned by `Expression.dump`) into an Expression instance.
761        """
762        from sqlglot.serde import load
763
764        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:
766    def and_(
767        self,
768        *expressions: t.Optional[ExpOrStr],
769        dialect: DialectType = None,
770        copy: bool = True,
771        **opts,
772    ) -> Condition:
773        """
774        AND this condition with one or multiple expressions.
775
776        Example:
777            >>> condition("x=1").and_("y=1").sql()
778            'x = 1 AND y = 1'
779
780        Args:
781            *expressions: the SQL code strings to parse.
782                If an `Expression` instance is passed, it will be used as-is.
783            dialect: the dialect used to parse the input expression.
784            copy: whether to copy the involved expressions (only applies to Expressions).
785            opts: other options to use to parse the input expressions.
786
787        Returns:
788            The new And condition.
789        """
790        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:
792    def or_(
793        self,
794        *expressions: t.Optional[ExpOrStr],
795        dialect: DialectType = None,
796        copy: bool = True,
797        **opts,
798    ) -> Condition:
799        """
800        OR this condition with one or multiple expressions.
801
802        Example:
803            >>> condition("x=1").or_("y=1").sql()
804            'x = 1 OR y = 1'
805
806        Args:
807            *expressions: the SQL code strings to parse.
808                If an `Expression` instance is passed, it will be used as-is.
809            dialect: the dialect used to parse the input expression.
810            copy: whether to copy the involved expressions (only applies to Expressions).
811            opts: other options to use to parse the input expressions.
812
813        Returns:
814            The new Or condition.
815        """
816        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):
818    def not_(self, copy: bool = True):
819        """
820        Wrap this condition with NOT.
821
822        Example:
823            >>> condition("x=1").not_().sql()
824            'NOT x = 1'
825
826        Args:
827            copy: whether to copy this object.
828
829        Returns:
830            The new Not instance.
831        """
832        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:
834    def as_(
835        self,
836        alias: str | Identifier,
837        quoted: t.Optional[bool] = None,
838        dialect: DialectType = None,
839        copy: bool = True,
840        **opts,
841    ) -> Alias:
842        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:
867    def isin(
868        self,
869        *expressions: t.Any,
870        query: t.Optional[ExpOrStr] = None,
871        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
872        copy: bool = True,
873        **opts,
874    ) -> In:
875        subquery = maybe_parse(query, copy=copy, **opts) if query else None
876        if subquery and not isinstance(subquery, Subquery):
877            subquery = subquery.subquery(copy=False)
878
879        return In(
880            this=maybe_copy(self, copy),
881            expressions=[convert(e, copy=copy) for e in expressions],
882            query=subquery,
883            unnest=(
884                Unnest(
885                    expressions=[
886                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
887                        for e in ensure_list(unnest)
888                    ]
889                )
890                if unnest
891                else None
892            ),
893        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
895    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
896        return Between(
897            this=maybe_copy(self, copy),
898            low=convert(low, copy=copy, **opts),
899            high=convert(high, copy=copy, **opts),
900        )
def is_( self, other: Union[str, Expression]) -> Is:
902    def is_(self, other: ExpOrStr) -> Is:
903        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
905    def like(self, other: ExpOrStr) -> Like:
906        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
908    def ilike(self, other: ExpOrStr) -> ILike:
909        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
911    def eq(self, other: t.Any) -> EQ:
912        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
914    def neq(self, other: t.Any) -> NEQ:
915        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
917    def rlike(self, other: ExpOrStr) -> RegexpLike:
918        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
920    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
921        div = self._binop(Div, other)
922        div.args["typed"] = typed
923        div.args["safe"] = safe
924        return div
def asc(self, nulls_first: bool = True) -> Ordered:
926    def asc(self, nulls_first: bool = True) -> Ordered:
927        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
929    def desc(self, nulls_first: bool = False) -> Ordered:
930        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):
1013class Condition(Expression):
1014    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

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:
1085    def offset(
1086        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1087    ) -> Q:
1088        """
1089        Set the OFFSET expression.
1090
1091        Example:
1092            >>> Select().from_("tbl").select("x").offset(10).sql()
1093            'SELECT x FROM tbl OFFSET 10'
1094
1095        Args:
1096            expression: the SQL code string to parse.
1097                This can also be an integer.
1098                If a `Offset` instance is passed, this is used as-is.
1099                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1100            dialect: the dialect used to parse the input expression.
1101            copy: if `False`, modify this expression instance in-place.
1102            opts: other options to use to parse the input expressions.
1103
1104        Returns:
1105            The modified Select expression.
1106        """
1107        return _apply_builder(
1108            expression=expression,
1109            instance=self,
1110            arg="offset",
1111            into=Offset,
1112            prefix="OFFSET",
1113            dialect=dialect,
1114            copy=copy,
1115            into_arg="expression",
1116            **opts,
1117        )

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:
1119    def order_by(
1120        self: Q,
1121        *expressions: t.Optional[ExpOrStr],
1122        append: bool = True,
1123        dialect: DialectType = None,
1124        copy: bool = True,
1125        **opts,
1126    ) -> Q:
1127        """
1128        Set the ORDER BY expression.
1129
1130        Example:
1131            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1132            'SELECT x FROM tbl ORDER BY x DESC'
1133
1134        Args:
1135            *expressions: the SQL code strings to parse.
1136                If a `Group` instance is passed, this is used as-is.
1137                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1138            append: if `True`, add to any existing expressions.
1139                Otherwise, this flattens all the `Order` expression into a single expression.
1140            dialect: the dialect used to parse the input expression.
1141            copy: if `False`, modify this expression instance in-place.
1142            opts: other options to use to parse the input expressions.
1143
1144        Returns:
1145            The modified Select expression.
1146        """
1147        return _apply_child_list_builder(
1148            *expressions,
1149            instance=self,
1150            arg="order",
1151            append=append,
1152            copy=copy,
1153            prefix="ORDER BY",
1154            into=Order,
1155            dialect=dialect,
1156            **opts,
1157        )

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]
1159    @property
1160    def ctes(self) -> t.List[CTE]:
1161        """Returns a list of all the CTEs attached to this query."""
1162        with_ = self.args.get("with")
1163        return with_.expressions if with_ else []

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

selects: List[Expression]
1165    @property
1166    def selects(self) -> t.List[Expression]:
1167        """Returns the query's projections."""
1168        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1170    @property
1171    def named_selects(self) -> t.List[str]:
1172        """Returns the output names of the query's projections."""
1173        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:
1175    def select(
1176        self: Q,
1177        *expressions: t.Optional[ExpOrStr],
1178        append: bool = True,
1179        dialect: DialectType = None,
1180        copy: bool = True,
1181        **opts,
1182    ) -> Q:
1183        """
1184        Append to or set the SELECT expressions.
1185
1186        Example:
1187            >>> Select().select("x", "y").sql()
1188            'SELECT x, y'
1189
1190        Args:
1191            *expressions: the SQL code strings to parse.
1192                If an `Expression` instance is passed, it will be used as-is.
1193            append: if `True`, add to any existing expressions.
1194                Otherwise, this resets the expressions.
1195            dialect: the dialect used to parse the input expressions.
1196            copy: if `False`, modify this expression instance in-place.
1197            opts: other options to use to parse the input expressions.
1198
1199        Returns:
1200            The modified Query expression.
1201        """
1202        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, materialized: 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:
1204    def with_(
1205        self: Q,
1206        alias: ExpOrStr,
1207        as_: ExpOrStr,
1208        recursive: t.Optional[bool] = None,
1209        materialized: t.Optional[bool] = None,
1210        append: bool = True,
1211        dialect: DialectType = None,
1212        copy: bool = True,
1213        **opts,
1214    ) -> Q:
1215        """
1216        Append to or set the common table expressions.
1217
1218        Example:
1219            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1220            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1221
1222        Args:
1223            alias: the SQL code string to parse as the table name.
1224                If an `Expression` instance is passed, this is used as-is.
1225            as_: the SQL code string to parse as the table expression.
1226                If an `Expression` instance is passed, it will be used as-is.
1227            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1228            materialized: set the MATERIALIZED part of the expression.
1229            append: if `True`, add to any existing expressions.
1230                Otherwise, this resets the expressions.
1231            dialect: the dialect used to parse the input expression.
1232            copy: if `False`, modify this expression instance in-place.
1233            opts: other options to use to parse the input expressions.
1234
1235        Returns:
1236            The modified expression.
1237        """
1238        return _apply_cte_builder(
1239            self,
1240            alias,
1241            as_,
1242            recursive=recursive,
1243            materialized=materialized,
1244            append=append,
1245            dialect=dialect,
1246            copy=copy,
1247            **opts,
1248        )

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.
  • materialized: set the MATERIALIZED part of the expression.
  • 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:
1250    def union(
1251        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1252    ) -> Union:
1253        """
1254        Builds a UNION expression.
1255
1256        Example:
1257            >>> import sqlglot
1258            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1259            'SELECT * FROM foo UNION SELECT * FROM bla'
1260
1261        Args:
1262            expression: the SQL code string.
1263                If an `Expression` instance is passed, it will be used as-is.
1264            distinct: set the DISTINCT flag if and only if this is true.
1265            dialect: the dialect used to parse the input expression.
1266            opts: other options to use to parse the input expressions.
1267
1268        Returns:
1269            The new Union expression.
1270        """
1271        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:
1273    def intersect(
1274        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1275    ) -> Intersect:
1276        """
1277        Builds an INTERSECT expression.
1278
1279        Example:
1280            >>> import sqlglot
1281            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1282            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1283
1284        Args:
1285            expression: the SQL code string.
1286                If an `Expression` instance is passed, it will be used as-is.
1287            distinct: set the DISTINCT flag if and only if this is true.
1288            dialect: the dialect used to parse the input expression.
1289            opts: other options to use to parse the input expressions.
1290
1291        Returns:
1292            The new Intersect expression.
1293        """
1294        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:
1296    def except_(
1297        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1298    ) -> Except:
1299        """
1300        Builds an EXCEPT expression.
1301
1302        Example:
1303            >>> import sqlglot
1304            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1305            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1306
1307        Args:
1308            expression: the SQL code string.
1309                If an `Expression` instance is passed, it will be used as-is.
1310            distinct: set the DISTINCT flag if and only if this is true.
1311            dialect: the dialect used to parse the input expression.
1312            opts: other options to use to parse the input expressions.
1313
1314        Returns:
1315            The new Except expression.
1316        """
1317        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):
1320class UDTF(DerivedTable):
1321    @property
1322    def selects(self) -> t.List[Expression]:
1323        alias = self.args.get("alias")
1324        return alias.columns if alias else []
selects: List[Expression]
1321    @property
1322    def selects(self) -> t.List[Expression]:
1323        alias = self.args.get("alias")
1324        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1327class Cache(Expression):
1328    arg_types = {
1329        "this": True,
1330        "lazy": False,
1331        "options": False,
1332        "expression": False,
1333    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1336class Uncache(Expression):
1337    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1340class Refresh(Expression):
1341    pass
key = 'refresh'
class DDL(Expression):
1344class DDL(Expression):
1345    @property
1346    def ctes(self) -> t.List[CTE]:
1347        """Returns a list of all the CTEs attached to this statement."""
1348        with_ = self.args.get("with")
1349        return with_.expressions if with_ else []
1350
1351    @property
1352    def selects(self) -> t.List[Expression]:
1353        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1354        return self.expression.selects if isinstance(self.expression, Query) else []
1355
1356    @property
1357    def named_selects(self) -> t.List[str]:
1358        """
1359        If this statement contains a query (e.g. a CTAS), this returns the output
1360        names of the query's projections.
1361        """
1362        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1345    @property
1346    def ctes(self) -> t.List[CTE]:
1347        """Returns a list of all the CTEs attached to this statement."""
1348        with_ = self.args.get("with")
1349        return with_.expressions if with_ else []

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

selects: List[Expression]
1351    @property
1352    def selects(self) -> t.List[Expression]:
1353        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1354        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]
1356    @property
1357    def named_selects(self) -> t.List[str]:
1358        """
1359        If this statement contains a query (e.g. a CTAS), this returns the output
1360        names of the query's projections.
1361        """
1362        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):
1365class DML(Expression):
1366    def returning(
1367        self,
1368        expression: ExpOrStr,
1369        dialect: DialectType = None,
1370        copy: bool = True,
1371        **opts,
1372    ) -> "Self":
1373        """
1374        Set the RETURNING expression. Not supported by all dialects.
1375
1376        Example:
1377            >>> delete("tbl").returning("*", dialect="postgres").sql()
1378            'DELETE FROM tbl RETURNING *'
1379
1380        Args:
1381            expression: the SQL code strings to parse.
1382                If an `Expression` instance is passed, it will be used as-is.
1383            dialect: the dialect used to parse the input expressions.
1384            copy: if `False`, modify this expression instance in-place.
1385            opts: other options to use to parse the input expressions.
1386
1387        Returns:
1388            Delete: the modified expression.
1389        """
1390        return _apply_builder(
1391            expression=expression,
1392            instance=self,
1393            arg="returning",
1394            prefix="RETURNING",
1395            dialect=dialect,
1396            copy=copy,
1397            into=Returning,
1398            **opts,
1399        )
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) -> typing_extensions.Self:
1366    def returning(
1367        self,
1368        expression: ExpOrStr,
1369        dialect: DialectType = None,
1370        copy: bool = True,
1371        **opts,
1372    ) -> "Self":
1373        """
1374        Set the RETURNING expression. Not supported by all dialects.
1375
1376        Example:
1377            >>> delete("tbl").returning("*", dialect="postgres").sql()
1378            'DELETE FROM tbl RETURNING *'
1379
1380        Args:
1381            expression: the SQL code strings to parse.
1382                If an `Expression` instance is passed, it will be used as-is.
1383            dialect: the dialect used to parse the input expressions.
1384            copy: if `False`, modify this expression instance in-place.
1385            opts: other options to use to parse the input expressions.
1386
1387        Returns:
1388            Delete: the modified expression.
1389        """
1390        return _apply_builder(
1391            expression=expression,
1392            instance=self,
1393            arg="returning",
1394            prefix="RETURNING",
1395            dialect=dialect,
1396            copy=copy,
1397            into=Returning,
1398            **opts,
1399        )

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):
1402class Create(DDL):
1403    arg_types = {
1404        "with": False,
1405        "this": True,
1406        "kind": True,
1407        "expression": False,
1408        "exists": False,
1409        "properties": False,
1410        "replace": False,
1411        "refresh": False,
1412        "unique": False,
1413        "indexes": False,
1414        "no_schema_binding": False,
1415        "begin": False,
1416        "end": False,
1417        "clone": False,
1418        "concurrently": False,
1419        "clustered": False,
1420    }
1421
1422    @property
1423    def kind(self) -> t.Optional[str]:
1424        kind = self.args.get("kind")
1425        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]
1422    @property
1423    def kind(self) -> t.Optional[str]:
1424        kind = self.args.get("kind")
1425        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1428class SequenceProperties(Expression):
1429    arg_types = {
1430        "increment": False,
1431        "minvalue": False,
1432        "maxvalue": False,
1433        "cache": False,
1434        "start": False,
1435        "owned": False,
1436        "options": False,
1437    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1440class TruncateTable(Expression):
1441    arg_types = {
1442        "expressions": True,
1443        "is_database": False,
1444        "exists": False,
1445        "only": False,
1446        "cluster": False,
1447        "identity": False,
1448        "option": False,
1449        "partition": False,
1450    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1456class Clone(Expression):
1457    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1460class Describe(Expression):
1461    arg_types = {
1462        "this": True,
1463        "style": False,
1464        "kind": False,
1465        "expressions": False,
1466        "partition": False,
1467    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False}
key = 'describe'
class Summarize(Expression):
1471class Summarize(Expression):
1472    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1475class Kill(Expression):
1476    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1479class Pragma(Expression):
1480    pass
key = 'pragma'
class Declare(Expression):
1483class Declare(Expression):
1484    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1487class DeclareItem(Expression):
1488    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1491class Set(Expression):
1492    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1495class Heredoc(Expression):
1496    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1499class SetItem(Expression):
1500    arg_types = {
1501        "this": False,
1502        "expressions": False,
1503        "kind": False,
1504        "collate": False,  # MySQL SET NAMES statement
1505        "global": False,
1506    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1509class Show(Expression):
1510    arg_types = {
1511        "this": True,
1512        "history": False,
1513        "terse": False,
1514        "target": False,
1515        "offset": False,
1516        "starts_with": False,
1517        "limit": False,
1518        "from": False,
1519        "like": False,
1520        "where": False,
1521        "db": False,
1522        "scope": False,
1523        "scope_kind": False,
1524        "full": False,
1525        "mutex": False,
1526        "query": False,
1527        "channel": False,
1528        "global": False,
1529        "log": False,
1530        "position": False,
1531        "types": False,
1532    }
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):
1535class UserDefinedFunction(Expression):
1536    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1539class CharacterSet(Expression):
1540    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1543class With(Expression):
1544    arg_types = {"expressions": True, "recursive": False}
1545
1546    @property
1547    def recursive(self) -> bool:
1548        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1546    @property
1547    def recursive(self) -> bool:
1548        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1551class WithinGroup(Expression):
1552    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1557class CTE(DerivedTable):
1558    arg_types = {
1559        "this": True,
1560        "alias": True,
1561        "scalar": False,
1562        "materialized": False,
1563    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1566class ProjectionDef(Expression):
1567    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1570class TableAlias(Expression):
1571    arg_types = {"this": False, "columns": False}
1572
1573    @property
1574    def columns(self):
1575        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1573    @property
1574    def columns(self):
1575        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1578class BitString(Condition):
1579    pass
key = 'bitstring'
class HexString(Condition):
1582class HexString(Condition):
1583    pass
key = 'hexstring'
class ByteString(Condition):
1586class ByteString(Condition):
1587    pass
key = 'bytestring'
class RawString(Condition):
1590class RawString(Condition):
1591    pass
key = 'rawstring'
class UnicodeString(Condition):
1594class UnicodeString(Condition):
1595    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1598class Column(Condition):
1599    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1600
1601    @property
1602    def table(self) -> str:
1603        return self.text("table")
1604
1605    @property
1606    def db(self) -> str:
1607        return self.text("db")
1608
1609    @property
1610    def catalog(self) -> str:
1611        return self.text("catalog")
1612
1613    @property
1614    def output_name(self) -> str:
1615        return self.name
1616
1617    @property
1618    def parts(self) -> t.List[Identifier]:
1619        """Return the parts of a column in order catalog, db, table, name."""
1620        return [
1621            t.cast(Identifier, self.args[part])
1622            for part in ("catalog", "db", "table", "this")
1623            if self.args.get(part)
1624        ]
1625
1626    def to_dot(self) -> Dot | Identifier:
1627        """Converts the column into a dot expression."""
1628        parts = self.parts
1629        parent = self.parent
1630
1631        while parent:
1632            if isinstance(parent, Dot):
1633                parts.append(parent.expression)
1634            parent = parent.parent
1635
1636        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
1601    @property
1602    def table(self) -> str:
1603        return self.text("table")
db: str
1605    @property
1606    def db(self) -> str:
1607        return self.text("db")
catalog: str
1609    @property
1610    def catalog(self) -> str:
1611        return self.text("catalog")
output_name: str
1613    @property
1614    def output_name(self) -> str:
1615        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]
1617    @property
1618    def parts(self) -> t.List[Identifier]:
1619        """Return the parts of a column in order catalog, db, table, name."""
1620        return [
1621            t.cast(Identifier, self.args[part])
1622            for part in ("catalog", "db", "table", "this")
1623            if self.args.get(part)
1624        ]

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

def to_dot(self) -> Dot | Identifier:
1626    def to_dot(self) -> Dot | Identifier:
1627        """Converts the column into a dot expression."""
1628        parts = self.parts
1629        parent = self.parent
1630
1631        while parent:
1632            if isinstance(parent, Dot):
1633                parts.append(parent.expression)
1634            parent = parent.parent
1635
1636        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1639class ColumnPosition(Expression):
1640    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1643class ColumnDef(Expression):
1644    arg_types = {
1645        "this": True,
1646        "kind": False,
1647        "constraints": False,
1648        "exists": False,
1649        "position": False,
1650    }
1651
1652    @property
1653    def constraints(self) -> t.List[ColumnConstraint]:
1654        return self.args.get("constraints") or []
1655
1656    @property
1657    def kind(self) -> t.Optional[DataType]:
1658        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1652    @property
1653    def constraints(self) -> t.List[ColumnConstraint]:
1654        return self.args.get("constraints") or []
kind: Optional[DataType]
1656    @property
1657    def kind(self) -> t.Optional[DataType]:
1658        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1661class AlterColumn(Expression):
1662    arg_types = {
1663        "this": True,
1664        "dtype": False,
1665        "collate": False,
1666        "using": False,
1667        "default": False,
1668        "drop": False,
1669        "comment": False,
1670        "allow_null": False,
1671    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1675class AlterDistStyle(Expression):
1676    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1679class AlterSortKey(Expression):
1680    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1683class AlterSet(Expression):
1684    arg_types = {
1685        "expressions": False,
1686        "option": False,
1687        "tablespace": False,
1688        "access_method": False,
1689        "file_format": False,
1690        "copy_options": False,
1691        "tag": False,
1692        "location": False,
1693        "serde": False,
1694    }
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):
1697class RenameColumn(Expression):
1698    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class RenameTable(Expression):
1701class RenameTable(Expression):
1702    pass
key = 'renametable'
class SwapTable(Expression):
1705class SwapTable(Expression):
1706    pass
key = 'swaptable'
class Comment(Expression):
1709class Comment(Expression):
1710    arg_types = {
1711        "this": True,
1712        "kind": True,
1713        "expression": True,
1714        "exists": False,
1715        "materialized": False,
1716    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1719class Comprehension(Expression):
1720    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):
1724class MergeTreeTTLAction(Expression):
1725    arg_types = {
1726        "this": True,
1727        "delete": False,
1728        "recompress": False,
1729        "to_disk": False,
1730        "to_volume": False,
1731    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1735class MergeTreeTTL(Expression):
1736    arg_types = {
1737        "expressions": True,
1738        "where": False,
1739        "group": False,
1740        "aggregates": False,
1741    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1745class IndexConstraintOption(Expression):
1746    arg_types = {
1747        "key_block_size": False,
1748        "using": False,
1749        "parser": False,
1750        "comment": False,
1751        "visible": False,
1752        "engine_attr": False,
1753        "secondary_engine_attr": False,
1754    }
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):
1757class ColumnConstraint(Expression):
1758    arg_types = {"this": False, "kind": True}
1759
1760    @property
1761    def kind(self) -> ColumnConstraintKind:
1762        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1760    @property
1761    def kind(self) -> ColumnConstraintKind:
1762        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1765class ColumnConstraintKind(Expression):
1766    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1769class AutoIncrementColumnConstraint(ColumnConstraintKind):
1770    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1773class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1774    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1777class CaseSpecificColumnConstraint(ColumnConstraintKind):
1778    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1781class CharacterSetColumnConstraint(ColumnConstraintKind):
1782    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1785class CheckColumnConstraint(ColumnConstraintKind):
1786    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1789class ClusteredColumnConstraint(ColumnConstraintKind):
1790    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1793class CollateColumnConstraint(ColumnConstraintKind):
1794    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1797class CommentColumnConstraint(ColumnConstraintKind):
1798    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1801class CompressColumnConstraint(ColumnConstraintKind):
1802    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1805class DateFormatColumnConstraint(ColumnConstraintKind):
1806    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1809class DefaultColumnConstraint(ColumnConstraintKind):
1810    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1813class EncodeColumnConstraint(ColumnConstraintKind):
1814    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1818class ExcludeColumnConstraint(ColumnConstraintKind):
1819    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1822class EphemeralColumnConstraint(ColumnConstraintKind):
1823    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1826class WithOperator(Expression):
1827    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1830class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1831    # this: True -> ALWAYS, this: False -> BY DEFAULT
1832    arg_types = {
1833        "this": False,
1834        "expression": False,
1835        "on_null": False,
1836        "start": False,
1837        "increment": False,
1838        "minvalue": False,
1839        "maxvalue": False,
1840        "cycle": False,
1841    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1844class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1845    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1850class IndexColumnConstraint(ColumnConstraintKind):
1851    arg_types = {
1852        "this": False,
1853        "expressions": False,
1854        "kind": False,
1855        "index_type": False,
1856        "options": False,
1857        "expression": False,  # Clickhouse
1858        "granularity": False,
1859    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1862class InlineLengthColumnConstraint(ColumnConstraintKind):
1863    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1866class NonClusteredColumnConstraint(ColumnConstraintKind):
1867    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1870class NotForReplicationColumnConstraint(ColumnConstraintKind):
1871    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1875class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1876    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1879class NotNullColumnConstraint(ColumnConstraintKind):
1880    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1884class OnUpdateColumnConstraint(ColumnConstraintKind):
1885    pass
key = 'onupdatecolumnconstraint'
class TagColumnConstraint(ColumnConstraintKind):
1889class TagColumnConstraint(ColumnConstraintKind):
1890    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tagcolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1894class TransformColumnConstraint(ColumnConstraintKind):
1895    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1898class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1899    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1902class TitleColumnConstraint(ColumnConstraintKind):
1903    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1906class UniqueColumnConstraint(ColumnConstraintKind):
1907    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):
1910class UppercaseColumnConstraint(ColumnConstraintKind):
1911    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1914class PathColumnConstraint(ColumnConstraintKind):
1915    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1919class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1920    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1925class ComputedColumnConstraint(ColumnConstraintKind):
1926    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1929class Constraint(Expression):
1930    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1933class Delete(DML):
1934    arg_types = {
1935        "with": False,
1936        "this": False,
1937        "using": False,
1938        "where": False,
1939        "returning": False,
1940        "limit": False,
1941        "tables": False,  # Multiple-Table Syntax (MySQL)
1942        "cluster": False,  # Clickhouse
1943    }
1944
1945    def delete(
1946        self,
1947        table: ExpOrStr,
1948        dialect: DialectType = None,
1949        copy: bool = True,
1950        **opts,
1951    ) -> Delete:
1952        """
1953        Create a DELETE expression or replace the table on an existing DELETE expression.
1954
1955        Example:
1956            >>> delete("tbl").sql()
1957            'DELETE FROM tbl'
1958
1959        Args:
1960            table: the table from which to delete.
1961            dialect: the dialect used to parse the input expression.
1962            copy: if `False`, modify this expression instance in-place.
1963            opts: other options to use to parse the input expressions.
1964
1965        Returns:
1966            Delete: the modified expression.
1967        """
1968        return _apply_builder(
1969            expression=table,
1970            instance=self,
1971            arg="this",
1972            dialect=dialect,
1973            into=Table,
1974            copy=copy,
1975            **opts,
1976        )
1977
1978    def where(
1979        self,
1980        *expressions: t.Optional[ExpOrStr],
1981        append: bool = True,
1982        dialect: DialectType = None,
1983        copy: bool = True,
1984        **opts,
1985    ) -> Delete:
1986        """
1987        Append to or set the WHERE expressions.
1988
1989        Example:
1990            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1991            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1992
1993        Args:
1994            *expressions: the SQL code strings to parse.
1995                If an `Expression` instance is passed, it will be used as-is.
1996                Multiple expressions are combined with an AND operator.
1997            append: if `True`, AND the new expressions to any existing expression.
1998                Otherwise, this resets the expression.
1999            dialect: the dialect used to parse the input expressions.
2000            copy: if `False`, modify this expression instance in-place.
2001            opts: other options to use to parse the input expressions.
2002
2003        Returns:
2004            Delete: the modified expression.
2005        """
2006        return _apply_conjunction_builder(
2007            *expressions,
2008            instance=self,
2009            arg="where",
2010            append=append,
2011            into=Where,
2012            dialect=dialect,
2013            copy=copy,
2014            **opts,
2015        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False, 'cluster': 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:
1945    def delete(
1946        self,
1947        table: ExpOrStr,
1948        dialect: DialectType = None,
1949        copy: bool = True,
1950        **opts,
1951    ) -> Delete:
1952        """
1953        Create a DELETE expression or replace the table on an existing DELETE expression.
1954
1955        Example:
1956            >>> delete("tbl").sql()
1957            'DELETE FROM tbl'
1958
1959        Args:
1960            table: the table from which to delete.
1961            dialect: the dialect used to parse the input expression.
1962            copy: if `False`, modify this expression instance in-place.
1963            opts: other options to use to parse the input expressions.
1964
1965        Returns:
1966            Delete: the modified expression.
1967        """
1968        return _apply_builder(
1969            expression=table,
1970            instance=self,
1971            arg="this",
1972            dialect=dialect,
1973            into=Table,
1974            copy=copy,
1975            **opts,
1976        )

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:
1978    def where(
1979        self,
1980        *expressions: t.Optional[ExpOrStr],
1981        append: bool = True,
1982        dialect: DialectType = None,
1983        copy: bool = True,
1984        **opts,
1985    ) -> Delete:
1986        """
1987        Append to or set the WHERE expressions.
1988
1989        Example:
1990            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1991            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1992
1993        Args:
1994            *expressions: the SQL code strings to parse.
1995                If an `Expression` instance is passed, it will be used as-is.
1996                Multiple expressions are combined with an AND operator.
1997            append: if `True`, AND the new expressions to any existing expression.
1998                Otherwise, this resets the expression.
1999            dialect: the dialect used to parse the input expressions.
2000            copy: if `False`, modify this expression instance in-place.
2001            opts: other options to use to parse the input expressions.
2002
2003        Returns:
2004            Delete: the modified expression.
2005        """
2006        return _apply_conjunction_builder(
2007            *expressions,
2008            instance=self,
2009            arg="where",
2010            append=append,
2011            into=Where,
2012            dialect=dialect,
2013            copy=copy,
2014            **opts,
2015        )

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):
2018class Drop(Expression):
2019    arg_types = {
2020        "this": False,
2021        "kind": False,
2022        "expressions": False,
2023        "exists": False,
2024        "temporary": False,
2025        "materialized": False,
2026        "cascade": False,
2027        "constraints": False,
2028        "purge": False,
2029        "cluster": False,
2030        "concurrently": False,
2031    }
2032
2033    @property
2034    def kind(self) -> t.Optional[str]:
2035        kind = self.args.get("kind")
2036        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, 'concurrently': False}
kind: Optional[str]
2033    @property
2034    def kind(self) -> t.Optional[str]:
2035        kind = self.args.get("kind")
2036        return kind and kind.upper()
key = 'drop'
class Filter(Expression):
2039class Filter(Expression):
2040    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2043class Check(Expression):
2044    pass
key = 'check'
class Changes(Expression):
2047class Changes(Expression):
2048    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2052class Connect(Expression):
2053    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2056class CopyParameter(Expression):
2057    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2060class Copy(DML):
2061    arg_types = {
2062        "this": True,
2063        "kind": True,
2064        "files": True,
2065        "credentials": False,
2066        "format": False,
2067        "params": False,
2068    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2071class Credentials(Expression):
2072    arg_types = {
2073        "credentials": False,
2074        "encryption": False,
2075        "storage": False,
2076        "iam_role": False,
2077        "region": False,
2078    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2081class Prior(Expression):
2082    pass
key = 'prior'
class Directory(Expression):
2085class Directory(Expression):
2086    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2087    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2090class ForeignKey(Expression):
2091    arg_types = {
2092        "expressions": True,
2093        "reference": False,
2094        "delete": False,
2095        "update": False,
2096    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2099class ColumnPrefix(Expression):
2100    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2103class PrimaryKey(Expression):
2104    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2109class Into(Expression):
2110    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2113class From(Expression):
2114    @property
2115    def name(self) -> str:
2116        return self.this.name
2117
2118    @property
2119    def alias_or_name(self) -> str:
2120        return self.this.alias_or_name
name: str
2114    @property
2115    def name(self) -> str:
2116        return self.this.name
alias_or_name: str
2118    @property
2119    def alias_or_name(self) -> str:
2120        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2123class Having(Expression):
2124    pass
key = 'having'
class Hint(Expression):
2127class Hint(Expression):
2128    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2131class JoinHint(Expression):
2132    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2135class Identifier(Expression):
2136    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2137
2138    @property
2139    def quoted(self) -> bool:
2140        return bool(self.args.get("quoted"))
2141
2142    @property
2143    def hashable_args(self) -> t.Any:
2144        return (self.this, self.quoted)
2145
2146    @property
2147    def output_name(self) -> str:
2148        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2138    @property
2139    def quoted(self) -> bool:
2140        return bool(self.args.get("quoted"))
hashable_args: Any
2142    @property
2143    def hashable_args(self) -> t.Any:
2144        return (self.this, self.quoted)
output_name: str
2146    @property
2147    def output_name(self) -> str:
2148        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):
2152class Opclass(Expression):
2153    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2156class Index(Expression):
2157    arg_types = {
2158        "this": False,
2159        "table": False,
2160        "unique": False,
2161        "primary": False,
2162        "amp": False,  # teradata
2163        "params": False,
2164    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2167class IndexParameters(Expression):
2168    arg_types = {
2169        "using": False,
2170        "include": False,
2171        "columns": False,
2172        "with_storage": False,
2173        "partition_by": False,
2174        "tablespace": False,
2175        "where": False,
2176        "on": False,
2177    }
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):
2180class Insert(DDL, DML):
2181    arg_types = {
2182        "hint": False,
2183        "with": False,
2184        "is_function": False,
2185        "this": False,
2186        "expression": False,
2187        "conflict": False,
2188        "returning": False,
2189        "overwrite": False,
2190        "exists": False,
2191        "alternative": False,
2192        "where": False,
2193        "ignore": False,
2194        "by_name": False,
2195        "stored": False,
2196        "partition": False,
2197        "settings": False,
2198        "source": False,
2199    }
2200
2201    def with_(
2202        self,
2203        alias: ExpOrStr,
2204        as_: ExpOrStr,
2205        recursive: t.Optional[bool] = None,
2206        materialized: t.Optional[bool] = None,
2207        append: bool = True,
2208        dialect: DialectType = None,
2209        copy: bool = True,
2210        **opts,
2211    ) -> Insert:
2212        """
2213        Append to or set the common table expressions.
2214
2215        Example:
2216            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2217            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2218
2219        Args:
2220            alias: the SQL code string to parse as the table name.
2221                If an `Expression` instance is passed, this is used as-is.
2222            as_: the SQL code string to parse as the table expression.
2223                If an `Expression` instance is passed, it will be used as-is.
2224            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2225            materialized: set the MATERIALIZED part of the expression.
2226            append: if `True`, add to any existing expressions.
2227                Otherwise, this resets the expressions.
2228            dialect: the dialect used to parse the input expression.
2229            copy: if `False`, modify this expression instance in-place.
2230            opts: other options to use to parse the input expressions.
2231
2232        Returns:
2233            The modified expression.
2234        """
2235        return _apply_cte_builder(
2236            self,
2237            alias,
2238            as_,
2239            recursive=recursive,
2240            materialized=materialized,
2241            append=append,
2242            dialect=dialect,
2243            copy=copy,
2244            **opts,
2245        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False, 'partition': False, 'settings': False, 'source': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: 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:
2201    def with_(
2202        self,
2203        alias: ExpOrStr,
2204        as_: ExpOrStr,
2205        recursive: t.Optional[bool] = None,
2206        materialized: t.Optional[bool] = None,
2207        append: bool = True,
2208        dialect: DialectType = None,
2209        copy: bool = True,
2210        **opts,
2211    ) -> Insert:
2212        """
2213        Append to or set the common table expressions.
2214
2215        Example:
2216            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2217            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2218
2219        Args:
2220            alias: the SQL code string to parse as the table name.
2221                If an `Expression` instance is passed, this is used as-is.
2222            as_: the SQL code string to parse as the table expression.
2223                If an `Expression` instance is passed, it will be used as-is.
2224            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2225            materialized: set the MATERIALIZED part of the expression.
2226            append: if `True`, add to any existing expressions.
2227                Otherwise, this resets the expressions.
2228            dialect: the dialect used to parse the input expression.
2229            copy: if `False`, modify this expression instance in-place.
2230            opts: other options to use to parse the input expressions.
2231
2232        Returns:
2233            The modified expression.
2234        """
2235        return _apply_cte_builder(
2236            self,
2237            alias,
2238            as_,
2239            recursive=recursive,
2240            materialized=materialized,
2241            append=append,
2242            dialect=dialect,
2243            copy=copy,
2244            **opts,
2245        )

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.
  • materialized: set the MATERIALIZED part of the expression.
  • 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 ConditionalInsert(Expression):
2248class ConditionalInsert(Expression):
2249    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2252class MultitableInserts(Expression):
2253    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2256class OnConflict(Expression):
2257    arg_types = {
2258        "duplicate": False,
2259        "expressions": False,
2260        "action": False,
2261        "conflict_keys": False,
2262        "constraint": False,
2263    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class OnCondition(Expression):
2266class OnCondition(Expression):
2267    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2270class Returning(Expression):
2271    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2275class Introducer(Expression):
2276    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2280class National(Expression):
2281    pass
key = 'national'
class LoadData(Expression):
2284class LoadData(Expression):
2285    arg_types = {
2286        "this": True,
2287        "local": False,
2288        "overwrite": False,
2289        "inpath": True,
2290        "partition": False,
2291        "input_format": False,
2292        "serde": False,
2293    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2296class Partition(Expression):
2297    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2300class PartitionRange(Expression):
2301    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2305class PartitionId(Expression):
2306    pass
key = 'partitionid'
class Fetch(Expression):
2309class Fetch(Expression):
2310    arg_types = {
2311        "direction": False,
2312        "count": False,
2313        "percent": False,
2314        "with_ties": False,
2315    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
2318class Group(Expression):
2319    arg_types = {
2320        "expressions": False,
2321        "grouping_sets": False,
2322        "cube": False,
2323        "rollup": False,
2324        "totals": False,
2325        "all": False,
2326    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2329class Cube(Expression):
2330    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2333class Rollup(Expression):
2334    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2337class GroupingSets(Expression):
2338    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2341class Lambda(Expression):
2342    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2345class Limit(Expression):
2346    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):
2349class Literal(Condition):
2350    arg_types = {"this": True, "is_string": True}
2351
2352    @property
2353    def hashable_args(self) -> t.Any:
2354        return (self.this, self.args.get("is_string"))
2355
2356    @classmethod
2357    def number(cls, number) -> Literal:
2358        return cls(this=str(number), is_string=False)
2359
2360    @classmethod
2361    def string(cls, string) -> Literal:
2362        return cls(this=str(string), is_string=True)
2363
2364    @property
2365    def output_name(self) -> str:
2366        return self.name
2367
2368    def to_py(self) -> int | str | Decimal:
2369        if self.is_number:
2370            try:
2371                return int(self.this)
2372            except ValueError:
2373                return Decimal(self.this)
2374        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2352    @property
2353    def hashable_args(self) -> t.Any:
2354        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2356    @classmethod
2357    def number(cls, number) -> Literal:
2358        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2360    @classmethod
2361    def string(cls, string) -> Literal:
2362        return cls(this=str(string), is_string=True)
output_name: str
2364    @property
2365    def output_name(self) -> str:
2366        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:
2368    def to_py(self) -> int | str | Decimal:
2369        if self.is_number:
2370            try:
2371                return int(self.this)
2372            except ValueError:
2373                return Decimal(self.this)
2374        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2377class Join(Expression):
2378    arg_types = {
2379        "this": True,
2380        "on": False,
2381        "side": False,
2382        "kind": False,
2383        "using": False,
2384        "method": False,
2385        "global": False,
2386        "hint": False,
2387        "match_condition": False,  # Snowflake
2388    }
2389
2390    @property
2391    def method(self) -> str:
2392        return self.text("method").upper()
2393
2394    @property
2395    def kind(self) -> str:
2396        return self.text("kind").upper()
2397
2398    @property
2399    def side(self) -> str:
2400        return self.text("side").upper()
2401
2402    @property
2403    def hint(self) -> str:
2404        return self.text("hint").upper()
2405
2406    @property
2407    def alias_or_name(self) -> str:
2408        return self.this.alias_or_name
2409
2410    def on(
2411        self,
2412        *expressions: t.Optional[ExpOrStr],
2413        append: bool = True,
2414        dialect: DialectType = None,
2415        copy: bool = True,
2416        **opts,
2417    ) -> Join:
2418        """
2419        Append to or set the ON expressions.
2420
2421        Example:
2422            >>> import sqlglot
2423            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2424            'JOIN x ON y = 1'
2425
2426        Args:
2427            *expressions: the SQL code strings to parse.
2428                If an `Expression` instance is passed, it will be used as-is.
2429                Multiple expressions are combined with an AND operator.
2430            append: if `True`, AND the new expressions to any existing expression.
2431                Otherwise, this resets the expression.
2432            dialect: the dialect used to parse the input expressions.
2433            copy: if `False`, modify this expression instance in-place.
2434            opts: other options to use to parse the input expressions.
2435
2436        Returns:
2437            The modified Join expression.
2438        """
2439        join = _apply_conjunction_builder(
2440            *expressions,
2441            instance=self,
2442            arg="on",
2443            append=append,
2444            dialect=dialect,
2445            copy=copy,
2446            **opts,
2447        )
2448
2449        if join.kind == "CROSS":
2450            join.set("kind", None)
2451
2452        return join
2453
2454    def using(
2455        self,
2456        *expressions: t.Optional[ExpOrStr],
2457        append: bool = True,
2458        dialect: DialectType = None,
2459        copy: bool = True,
2460        **opts,
2461    ) -> Join:
2462        """
2463        Append to or set the USING expressions.
2464
2465        Example:
2466            >>> import sqlglot
2467            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2468            'JOIN x USING (foo, bla)'
2469
2470        Args:
2471            *expressions: the SQL code strings to parse.
2472                If an `Expression` instance is passed, it will be used as-is.
2473            append: if `True`, concatenate the new expressions to the existing "using" list.
2474                Otherwise, this resets the expression.
2475            dialect: the dialect used to parse the input expressions.
2476            copy: if `False`, modify this expression instance in-place.
2477            opts: other options to use to parse the input expressions.
2478
2479        Returns:
2480            The modified Join expression.
2481        """
2482        join = _apply_list_builder(
2483            *expressions,
2484            instance=self,
2485            arg="using",
2486            append=append,
2487            dialect=dialect,
2488            copy=copy,
2489            **opts,
2490        )
2491
2492        if join.kind == "CROSS":
2493            join.set("kind", None)
2494
2495        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
2390    @property
2391    def method(self) -> str:
2392        return self.text("method").upper()
kind: str
2394    @property
2395    def kind(self) -> str:
2396        return self.text("kind").upper()
side: str
2398    @property
2399    def side(self) -> str:
2400        return self.text("side").upper()
hint: str
2402    @property
2403    def hint(self) -> str:
2404        return self.text("hint").upper()
alias_or_name: str
2406    @property
2407    def alias_or_name(self) -> str:
2408        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:
2410    def on(
2411        self,
2412        *expressions: t.Optional[ExpOrStr],
2413        append: bool = True,
2414        dialect: DialectType = None,
2415        copy: bool = True,
2416        **opts,
2417    ) -> Join:
2418        """
2419        Append to or set the ON expressions.
2420
2421        Example:
2422            >>> import sqlglot
2423            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2424            'JOIN x ON y = 1'
2425
2426        Args:
2427            *expressions: the SQL code strings to parse.
2428                If an `Expression` instance is passed, it will be used as-is.
2429                Multiple expressions are combined with an AND operator.
2430            append: if `True`, AND the new expressions to any existing expression.
2431                Otherwise, this resets the expression.
2432            dialect: the dialect used to parse the input expressions.
2433            copy: if `False`, modify this expression instance in-place.
2434            opts: other options to use to parse the input expressions.
2435
2436        Returns:
2437            The modified Join expression.
2438        """
2439        join = _apply_conjunction_builder(
2440            *expressions,
2441            instance=self,
2442            arg="on",
2443            append=append,
2444            dialect=dialect,
2445            copy=copy,
2446            **opts,
2447        )
2448
2449        if join.kind == "CROSS":
2450            join.set("kind", None)
2451
2452        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:
2454    def using(
2455        self,
2456        *expressions: t.Optional[ExpOrStr],
2457        append: bool = True,
2458        dialect: DialectType = None,
2459        copy: bool = True,
2460        **opts,
2461    ) -> Join:
2462        """
2463        Append to or set the USING expressions.
2464
2465        Example:
2466            >>> import sqlglot
2467            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2468            'JOIN x USING (foo, bla)'
2469
2470        Args:
2471            *expressions: the SQL code strings to parse.
2472                If an `Expression` instance is passed, it will be used as-is.
2473            append: if `True`, concatenate the new expressions to the existing "using" list.
2474                Otherwise, this resets the expression.
2475            dialect: the dialect used to parse the input expressions.
2476            copy: if `False`, modify this expression instance in-place.
2477            opts: other options to use to parse the input expressions.
2478
2479        Returns:
2480            The modified Join expression.
2481        """
2482        join = _apply_list_builder(
2483            *expressions,
2484            instance=self,
2485            arg="using",
2486            append=append,
2487            dialect=dialect,
2488            copy=copy,
2489            **opts,
2490        )
2491
2492        if join.kind == "CROSS":
2493            join.set("kind", None)
2494
2495        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):
2498class Lateral(UDTF):
2499    arg_types = {
2500        "this": True,
2501        "view": False,
2502        "outer": False,
2503        "alias": False,
2504        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2505    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2508class MatchRecognizeMeasure(Expression):
2509    arg_types = {
2510        "this": True,
2511        "window_frame": False,
2512    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2515class MatchRecognize(Expression):
2516    arg_types = {
2517        "partition_by": False,
2518        "order": False,
2519        "measures": False,
2520        "rows": False,
2521        "after": False,
2522        "pattern": False,
2523        "define": False,
2524        "alias": False,
2525    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2530class Final(Expression):
2531    pass
key = 'final'
class Offset(Expression):
2534class Offset(Expression):
2535    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2538class Order(Expression):
2539    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2543class WithFill(Expression):
2544    arg_types = {
2545        "from": False,
2546        "to": False,
2547        "step": False,
2548        "interpolate": False,
2549    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2554class Cluster(Order):
2555    pass
key = 'cluster'
class Distribute(Order):
2558class Distribute(Order):
2559    pass
key = 'distribute'
class Sort(Order):
2562class Sort(Order):
2563    pass
key = 'sort'
class Ordered(Expression):
2566class Ordered(Expression):
2567    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):
2570class Property(Expression):
2571    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2574class AllowedValuesProperty(Expression):
2575    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2578class AlgorithmProperty(Property):
2579    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2582class AutoIncrementProperty(Property):
2583    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2587class AutoRefreshProperty(Property):
2588    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2591class BackupProperty(Property):
2592    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2595class BlockCompressionProperty(Property):
2596    arg_types = {
2597        "autotemp": False,
2598        "always": False,
2599        "default": False,
2600        "manual": False,
2601        "never": False,
2602    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2605class CharacterSetProperty(Property):
2606    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2609class ChecksumProperty(Property):
2610    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2613class CollateProperty(Property):
2614    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2617class CopyGrantsProperty(Property):
2618    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2621class DataBlocksizeProperty(Property):
2622    arg_types = {
2623        "size": False,
2624        "units": False,
2625        "minimum": False,
2626        "maximum": False,
2627        "default": False,
2628    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2631class DataDeletionProperty(Property):
2632    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):
2635class DefinerProperty(Property):
2636    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2639class DistKeyProperty(Property):
2640    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2645class DistributedByProperty(Property):
2646    arg_types = {"expressions": False, "kind": True, "buckets": False, "order": False}
arg_types = {'expressions': False, 'kind': True, 'buckets': False, 'order': False}
key = 'distributedbyproperty'
class DistStyleProperty(Property):
2649class DistStyleProperty(Property):
2650    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2653class DuplicateKeyProperty(Property):
2654    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2657class EngineProperty(Property):
2658    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2661class HeapProperty(Property):
2662    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2665class ToTableProperty(Property):
2666    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2669class ExecuteAsProperty(Property):
2670    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2673class ExternalProperty(Property):
2674    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2677class FallbackProperty(Property):
2678    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2681class FileFormatProperty(Property):
2682    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2685class FreespaceProperty(Property):
2686    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2689class GlobalProperty(Property):
2690    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2693class IcebergProperty(Property):
2694    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2697class InheritsProperty(Property):
2698    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2701class InputModelProperty(Property):
2702    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2705class OutputModelProperty(Property):
2706    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2709class IsolatedLoadingProperty(Property):
2710    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2713class JournalProperty(Property):
2714    arg_types = {
2715        "no": False,
2716        "dual": False,
2717        "before": False,
2718        "local": False,
2719        "after": False,
2720    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2723class LanguageProperty(Property):
2724    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2728class ClusteredByProperty(Property):
2729    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2732class DictProperty(Property):
2733    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2736class DictSubProperty(Property):
2737    pass
key = 'dictsubproperty'
class DictRange(Property):
2740class DictRange(Property):
2741    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2744class DynamicProperty(Property):
2745    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2750class OnCluster(Property):
2751    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2755class EmptyProperty(Property):
2756    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2759class LikeProperty(Property):
2760    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2763class LocationProperty(Property):
2764    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2767class LockProperty(Property):
2768    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2771class LockingProperty(Property):
2772    arg_types = {
2773        "this": False,
2774        "kind": True,
2775        "for_or_in": False,
2776        "lock_type": True,
2777        "override": False,
2778    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2781class LogProperty(Property):
2782    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2785class MaterializedProperty(Property):
2786    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2789class MergeBlockRatioProperty(Property):
2790    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):
2793class NoPrimaryIndexProperty(Property):
2794    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2797class OnProperty(Property):
2798    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2801class OnCommitProperty(Property):
2802    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2805class PartitionedByProperty(Property):
2806    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2810class PartitionBoundSpec(Expression):
2811    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2812    arg_types = {
2813        "this": False,
2814        "expression": False,
2815        "from_expressions": False,
2816        "to_expressions": False,
2817    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2820class PartitionedOfProperty(Property):
2821    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2822    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2825class StreamingTableProperty(Property):
2826    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2829class RemoteWithConnectionModelProperty(Property):
2830    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2833class ReturnsProperty(Property):
2834    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):
2837class StrictProperty(Property):
2838    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2841class RowFormatProperty(Property):
2842    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2845class RowFormatDelimitedProperty(Property):
2846    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2847    arg_types = {
2848        "fields": False,
2849        "escaped": False,
2850        "collection_items": False,
2851        "map_keys": False,
2852        "lines": False,
2853        "null": False,
2854        "serde": False,
2855    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2858class RowFormatSerdeProperty(Property):
2859    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2863class QueryTransform(Expression):
2864    arg_types = {
2865        "expressions": True,
2866        "command_script": True,
2867        "schema": False,
2868        "row_format_before": False,
2869        "record_writer": False,
2870        "row_format_after": False,
2871        "record_reader": False,
2872    }
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):
2875class SampleProperty(Property):
2876    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2880class SecurityProperty(Property):
2881    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2884class SchemaCommentProperty(Property):
2885    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2888class SerdeProperties(Property):
2889    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2892class SetProperty(Property):
2893    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2896class SharingProperty(Property):
2897    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2900class SetConfigProperty(Property):
2901    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2904class SettingsProperty(Property):
2905    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2908class SortKeyProperty(Property):
2909    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2912class SqlReadWriteProperty(Property):
2913    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2916class SqlSecurityProperty(Property):
2917    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2920class StabilityProperty(Property):
2921    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2924class TemporaryProperty(Property):
2925    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2928class SecureProperty(Property):
2929    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2932class TransformModelProperty(Property):
2933    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2936class TransientProperty(Property):
2937    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2940class UnloggedProperty(Property):
2941    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2945class ViewAttributeProperty(Property):
2946    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2949class VolatileProperty(Property):
2950    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2953class WithDataProperty(Property):
2954    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2957class WithJournalTableProperty(Property):
2958    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2961class WithSchemaBindingProperty(Property):
2962    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2965class WithSystemVersioningProperty(Property):
2966    arg_types = {
2967        "on": False,
2968        "this": False,
2969        "data_consistency": False,
2970        "retention_period": False,
2971        "with": True,
2972    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2975class Properties(Expression):
2976    arg_types = {"expressions": True}
2977
2978    NAME_TO_PROPERTY = {
2979        "ALGORITHM": AlgorithmProperty,
2980        "AUTO_INCREMENT": AutoIncrementProperty,
2981        "CHARACTER SET": CharacterSetProperty,
2982        "CLUSTERED_BY": ClusteredByProperty,
2983        "COLLATE": CollateProperty,
2984        "COMMENT": SchemaCommentProperty,
2985        "DEFINER": DefinerProperty,
2986        "DISTKEY": DistKeyProperty,
2987        "DISTRIBUTED_BY": DistributedByProperty,
2988        "DISTSTYLE": DistStyleProperty,
2989        "ENGINE": EngineProperty,
2990        "EXECUTE AS": ExecuteAsProperty,
2991        "FORMAT": FileFormatProperty,
2992        "LANGUAGE": LanguageProperty,
2993        "LOCATION": LocationProperty,
2994        "LOCK": LockProperty,
2995        "PARTITIONED_BY": PartitionedByProperty,
2996        "RETURNS": ReturnsProperty,
2997        "ROW_FORMAT": RowFormatProperty,
2998        "SORTKEY": SortKeyProperty,
2999    }
3000
3001    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3002
3003    # CREATE property locations
3004    # Form: schema specified
3005    #   create [POST_CREATE]
3006    #     table a [POST_NAME]
3007    #     (b int) [POST_SCHEMA]
3008    #     with ([POST_WITH])
3009    #     index (b) [POST_INDEX]
3010    #
3011    # Form: alias selection
3012    #   create [POST_CREATE]
3013    #     table a [POST_NAME]
3014    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3015    #     index (c) [POST_INDEX]
3016    class Location(AutoName):
3017        POST_CREATE = auto()
3018        POST_NAME = auto()
3019        POST_SCHEMA = auto()
3020        POST_WITH = auto()
3021        POST_ALIAS = auto()
3022        POST_EXPRESSION = auto()
3023        POST_INDEX = auto()
3024        UNSUPPORTED = auto()
3025
3026    @classmethod
3027    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3028        expressions = []
3029        for key, value in properties_dict.items():
3030            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3031            if property_cls:
3032                expressions.append(property_cls(this=convert(value)))
3033            else:
3034                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3035
3036        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'>, 'DISTRIBUTED_BY': <class 'DistributedByProperty'>, '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 'DistributedByProperty'>: 'DISTRIBUTED_BY', <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:
3026    @classmethod
3027    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3028        expressions = []
3029        for key, value in properties_dict.items():
3030            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3031            if property_cls:
3032                expressions.append(property_cls(this=convert(value)))
3033            else:
3034                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3035
3036        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3016    class Location(AutoName):
3017        POST_CREATE = auto()
3018        POST_NAME = auto()
3019        POST_SCHEMA = auto()
3020        POST_WITH = auto()
3021        POST_ALIAS = auto()
3022        POST_EXPRESSION = auto()
3023        POST_INDEX = auto()
3024        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):
3039class Qualify(Expression):
3040    pass
key = 'qualify'
class InputOutputFormat(Expression):
3043class InputOutputFormat(Expression):
3044    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3048class Return(Expression):
3049    pass
key = 'return'
class Reference(Expression):
3052class Reference(Expression):
3053    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3056class Tuple(Expression):
3057    arg_types = {"expressions": False}
3058
3059    def isin(
3060        self,
3061        *expressions: t.Any,
3062        query: t.Optional[ExpOrStr] = None,
3063        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3064        copy: bool = True,
3065        **opts,
3066    ) -> In:
3067        return In(
3068            this=maybe_copy(self, copy),
3069            expressions=[convert(e, copy=copy) for e in expressions],
3070            query=maybe_parse(query, copy=copy, **opts) if query else None,
3071            unnest=(
3072                Unnest(
3073                    expressions=[
3074                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3075                        for e in ensure_list(unnest)
3076                    ]
3077                )
3078                if unnest
3079                else None
3080            ),
3081        )
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:
3059    def isin(
3060        self,
3061        *expressions: t.Any,
3062        query: t.Optional[ExpOrStr] = None,
3063        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3064        copy: bool = True,
3065        **opts,
3066    ) -> In:
3067        return In(
3068            this=maybe_copy(self, copy),
3069            expressions=[convert(e, copy=copy) for e in expressions],
3070            query=maybe_parse(query, copy=copy, **opts) if query else None,
3071            unnest=(
3072                Unnest(
3073                    expressions=[
3074                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3075                        for e in ensure_list(unnest)
3076                    ]
3077                )
3078                if unnest
3079                else None
3080            ),
3081        )
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):
3112class QueryOption(Expression):
3113    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3117class WithTableHint(Expression):
3118    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3122class IndexTableHint(Expression):
3123    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3127class HistoricalData(Expression):
3128    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3131class Table(Expression):
3132    arg_types = {
3133        "this": False,
3134        "alias": False,
3135        "db": False,
3136        "catalog": False,
3137        "laterals": False,
3138        "joins": False,
3139        "pivots": False,
3140        "hints": False,
3141        "system_time": False,
3142        "version": False,
3143        "format": False,
3144        "pattern": False,
3145        "ordinality": False,
3146        "when": False,
3147        "only": False,
3148        "partition": False,
3149        "changes": False,
3150        "rows_from": False,
3151        "sample": False,
3152    }
3153
3154    @property
3155    def name(self) -> str:
3156        if isinstance(self.this, Func):
3157            return ""
3158        return self.this.name
3159
3160    @property
3161    def db(self) -> str:
3162        return self.text("db")
3163
3164    @property
3165    def catalog(self) -> str:
3166        return self.text("catalog")
3167
3168    @property
3169    def selects(self) -> t.List[Expression]:
3170        return []
3171
3172    @property
3173    def named_selects(self) -> t.List[str]:
3174        return []
3175
3176    @property
3177    def parts(self) -> t.List[Expression]:
3178        """Return the parts of a table in order catalog, db, table."""
3179        parts: t.List[Expression] = []
3180
3181        for arg in ("catalog", "db", "this"):
3182            part = self.args.get(arg)
3183
3184            if isinstance(part, Dot):
3185                parts.extend(part.flatten())
3186            elif isinstance(part, Expression):
3187                parts.append(part)
3188
3189        return parts
3190
3191    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3192        parts = self.parts
3193        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3194        alias = self.args.get("alias")
3195        if alias:
3196            col = alias_(col, alias.this, copy=copy)
3197        return col
arg_types = {'this': False, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'ordinality': False, 'when': False, 'only': False, 'partition': False, 'changes': False, 'rows_from': False, 'sample': False}
name: str
3154    @property
3155    def name(self) -> str:
3156        if isinstance(self.this, Func):
3157            return ""
3158        return self.this.name
db: str
3160    @property
3161    def db(self) -> str:
3162        return self.text("db")
catalog: str
3164    @property
3165    def catalog(self) -> str:
3166        return self.text("catalog")
selects: List[Expression]
3168    @property
3169    def selects(self) -> t.List[Expression]:
3170        return []
named_selects: List[str]
3172    @property
3173    def named_selects(self) -> t.List[str]:
3174        return []
parts: List[Expression]
3176    @property
3177    def parts(self) -> t.List[Expression]:
3178        """Return the parts of a table in order catalog, db, table."""
3179        parts: t.List[Expression] = []
3180
3181        for arg in ("catalog", "db", "this"):
3182            part = self.args.get(arg)
3183
3184            if isinstance(part, Dot):
3185                parts.extend(part.flatten())
3186            elif isinstance(part, Expression):
3187                parts.append(part)
3188
3189        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3191    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3192        parts = self.parts
3193        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3194        alias = self.args.get("alias")
3195        if alias:
3196            col = alias_(col, alias.this, copy=copy)
3197        return col
key = 'table'
class SetOperation(Query):
3200class SetOperation(Query):
3201    arg_types = {
3202        "with": False,
3203        "this": True,
3204        "expression": True,
3205        "distinct": False,
3206        "by_name": False,
3207        **QUERY_MODIFIERS,
3208    }
3209
3210    def select(
3211        self: S,
3212        *expressions: t.Optional[ExpOrStr],
3213        append: bool = True,
3214        dialect: DialectType = None,
3215        copy: bool = True,
3216        **opts,
3217    ) -> S:
3218        this = maybe_copy(self, copy)
3219        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3220        this.expression.unnest().select(
3221            *expressions, append=append, dialect=dialect, copy=False, **opts
3222        )
3223        return this
3224
3225    @property
3226    def named_selects(self) -> t.List[str]:
3227        return self.this.unnest().named_selects
3228
3229    @property
3230    def is_star(self) -> bool:
3231        return self.this.is_star or self.expression.is_star
3232
3233    @property
3234    def selects(self) -> t.List[Expression]:
3235        return self.this.unnest().selects
3236
3237    @property
3238    def left(self) -> Query:
3239        return self.this
3240
3241    @property
3242    def right(self) -> Query:
3243        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:
3210    def select(
3211        self: S,
3212        *expressions: t.Optional[ExpOrStr],
3213        append: bool = True,
3214        dialect: DialectType = None,
3215        copy: bool = True,
3216        **opts,
3217    ) -> S:
3218        this = maybe_copy(self, copy)
3219        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3220        this.expression.unnest().select(
3221            *expressions, append=append, dialect=dialect, copy=False, **opts
3222        )
3223        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]
3225    @property
3226    def named_selects(self) -> t.List[str]:
3227        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3229    @property
3230    def is_star(self) -> bool:
3231        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3233    @property
3234    def selects(self) -> t.List[Expression]:
3235        return self.this.unnest().selects

Returns the query's projections.

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

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

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:
3391    def sort_by(
3392        self,
3393        *expressions: t.Optional[ExpOrStr],
3394        append: bool = True,
3395        dialect: DialectType = None,
3396        copy: bool = True,
3397        **opts,
3398    ) -> Select:
3399        """
3400        Set the SORT BY expression.
3401
3402        Example:
3403            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3404            'SELECT x FROM tbl SORT BY x DESC'
3405
3406        Args:
3407            *expressions: the SQL code strings to parse.
3408                If a `Group` instance is passed, this is used as-is.
3409                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3410            append: if `True`, add to any existing expressions.
3411                Otherwise, this flattens all the `Order` expression into a single expression.
3412            dialect: the dialect used to parse the input expression.
3413            copy: if `False`, modify this expression instance in-place.
3414            opts: other options to use to parse the input expressions.
3415
3416        Returns:
3417            The modified Select expression.
3418        """
3419        return _apply_child_list_builder(
3420            *expressions,
3421            instance=self,
3422            arg="sort",
3423            append=append,
3424            copy=copy,
3425            prefix="SORT BY",
3426            into=Sort,
3427            dialect=dialect,
3428            **opts,
3429        )

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:
3431    def cluster_by(
3432        self,
3433        *expressions: t.Optional[ExpOrStr],
3434        append: bool = True,
3435        dialect: DialectType = None,
3436        copy: bool = True,
3437        **opts,
3438    ) -> Select:
3439        """
3440        Set the CLUSTER BY expression.
3441
3442        Example:
3443            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3444            'SELECT x FROM tbl CLUSTER BY x DESC'
3445
3446        Args:
3447            *expressions: the SQL code strings to parse.
3448                If a `Group` instance is passed, this is used as-is.
3449                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3450            append: if `True`, add to any existing expressions.
3451                Otherwise, this flattens all the `Order` expression into a single expression.
3452            dialect: the dialect used to parse the input expression.
3453            copy: if `False`, modify this expression instance in-place.
3454            opts: other options to use to parse the input expressions.
3455
3456        Returns:
3457            The modified Select expression.
3458        """
3459        return _apply_child_list_builder(
3460            *expressions,
3461            instance=self,
3462            arg="cluster",
3463            append=append,
3464            copy=copy,
3465            prefix="CLUSTER BY",
3466            into=Cluster,
3467            dialect=dialect,
3468            **opts,
3469        )

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:
3471    def select(
3472        self,
3473        *expressions: t.Optional[ExpOrStr],
3474        append: bool = True,
3475        dialect: DialectType = None,
3476        copy: bool = True,
3477        **opts,
3478    ) -> Select:
3479        return _apply_list_builder(
3480            *expressions,
3481            instance=self,
3482            arg="expressions",
3483            append=append,
3484            dialect=dialect,
3485            into=Expression,
3486            copy=copy,
3487            **opts,
3488        )

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:
3490    def lateral(
3491        self,
3492        *expressions: t.Optional[ExpOrStr],
3493        append: bool = True,
3494        dialect: DialectType = None,
3495        copy: bool = True,
3496        **opts,
3497    ) -> Select:
3498        """
3499        Append to or set the LATERAL expressions.
3500
3501        Example:
3502            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3503            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3504
3505        Args:
3506            *expressions: the SQL code strings to parse.
3507                If an `Expression` instance is passed, it will be used as-is.
3508            append: if `True`, add to any existing expressions.
3509                Otherwise, this resets the expressions.
3510            dialect: the dialect used to parse the input expressions.
3511            copy: if `False`, modify this expression instance in-place.
3512            opts: other options to use to parse the input expressions.
3513
3514        Returns:
3515            The modified Select expression.
3516        """
3517        return _apply_list_builder(
3518            *expressions,
3519            instance=self,
3520            arg="laterals",
3521            append=append,
3522            into=Lateral,
3523            prefix="LATERAL VIEW",
3524            dialect=dialect,
3525            copy=copy,
3526            **opts,
3527        )

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:
3529    def join(
3530        self,
3531        expression: ExpOrStr,
3532        on: t.Optional[ExpOrStr] = None,
3533        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3534        append: bool = True,
3535        join_type: t.Optional[str] = None,
3536        join_alias: t.Optional[Identifier | str] = None,
3537        dialect: DialectType = None,
3538        copy: bool = True,
3539        **opts,
3540    ) -> Select:
3541        """
3542        Append to or set the JOIN expressions.
3543
3544        Example:
3545            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3546            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3547
3548            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3549            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3550
3551            Use `join_type` to change the type of join:
3552
3553            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3554            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3555
3556        Args:
3557            expression: the SQL code string to parse.
3558                If an `Expression` instance is passed, it will be used as-is.
3559            on: optionally specify the join "on" criteria as a SQL string.
3560                If an `Expression` instance is passed, it will be used as-is.
3561            using: optionally specify the join "using" criteria as a SQL string.
3562                If an `Expression` instance is passed, it will be used as-is.
3563            append: if `True`, add to any existing expressions.
3564                Otherwise, this resets the expressions.
3565            join_type: if set, alter the parsed join type.
3566            join_alias: an optional alias for the joined source.
3567            dialect: the dialect used to parse the input expressions.
3568            copy: if `False`, modify this expression instance in-place.
3569            opts: other options to use to parse the input expressions.
3570
3571        Returns:
3572            Select: the modified expression.
3573        """
3574        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3575
3576        try:
3577            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3578        except ParseError:
3579            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3580
3581        join = expression if isinstance(expression, Join) else Join(this=expression)
3582
3583        if isinstance(join.this, Select):
3584            join.this.replace(join.this.subquery())
3585
3586        if join_type:
3587            method: t.Optional[Token]
3588            side: t.Optional[Token]
3589            kind: t.Optional[Token]
3590
3591            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3592
3593            if method:
3594                join.set("method", method.text)
3595            if side:
3596                join.set("side", side.text)
3597            if kind:
3598                join.set("kind", kind.text)
3599
3600        if on:
3601            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3602            join.set("on", on)
3603
3604        if using:
3605            join = _apply_list_builder(
3606                *ensure_list(using),
3607                instance=join,
3608                arg="using",
3609                append=append,
3610                copy=copy,
3611                into=Identifier,
3612                **opts,
3613            )
3614
3615        if join_alias:
3616            join.set("this", alias_(join.this, join_alias, table=True))
3617
3618        return _apply_list_builder(
3619            join,
3620            instance=self,
3621            arg="joins",
3622            append=append,
3623            copy=copy,
3624            **opts,
3625        )

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:
3627    def where(
3628        self,
3629        *expressions: t.Optional[ExpOrStr],
3630        append: bool = True,
3631        dialect: DialectType = None,
3632        copy: bool = True,
3633        **opts,
3634    ) -> Select:
3635        """
3636        Append to or set the WHERE expressions.
3637
3638        Example:
3639            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3640            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3641
3642        Args:
3643            *expressions: the SQL code strings to parse.
3644                If an `Expression` instance is passed, it will be used as-is.
3645                Multiple expressions are combined with an AND operator.
3646            append: if `True`, AND the new expressions to any existing expression.
3647                Otherwise, this resets the expression.
3648            dialect: the dialect used to parse the input expressions.
3649            copy: if `False`, modify this expression instance in-place.
3650            opts: other options to use to parse the input expressions.
3651
3652        Returns:
3653            Select: the modified expression.
3654        """
3655        return _apply_conjunction_builder(
3656            *expressions,
3657            instance=self,
3658            arg="where",
3659            append=append,
3660            into=Where,
3661            dialect=dialect,
3662            copy=copy,
3663            **opts,
3664        )

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:
3666    def having(
3667        self,
3668        *expressions: t.Optional[ExpOrStr],
3669        append: bool = True,
3670        dialect: DialectType = None,
3671        copy: bool = True,
3672        **opts,
3673    ) -> Select:
3674        """
3675        Append to or set the HAVING expressions.
3676
3677        Example:
3678            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3679            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3680
3681        Args:
3682            *expressions: the SQL code strings to parse.
3683                If an `Expression` instance is passed, it will be used as-is.
3684                Multiple expressions are combined with an AND operator.
3685            append: if `True`, AND the new expressions to any existing expression.
3686                Otherwise, this resets the expression.
3687            dialect: the dialect used to parse the input expressions.
3688            copy: if `False`, modify this expression instance in-place.
3689            opts: other options to use to parse the input expressions.
3690
3691        Returns:
3692            The modified Select expression.
3693        """
3694        return _apply_conjunction_builder(
3695            *expressions,
3696            instance=self,
3697            arg="having",
3698            append=append,
3699            into=Having,
3700            dialect=dialect,
3701            copy=copy,
3702            **opts,
3703        )

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:
3705    def window(
3706        self,
3707        *expressions: t.Optional[ExpOrStr],
3708        append: bool = True,
3709        dialect: DialectType = None,
3710        copy: bool = True,
3711        **opts,
3712    ) -> Select:
3713        return _apply_list_builder(
3714            *expressions,
3715            instance=self,
3716            arg="windows",
3717            append=append,
3718            into=Window,
3719            dialect=dialect,
3720            copy=copy,
3721            **opts,
3722        )
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:
3724    def qualify(
3725        self,
3726        *expressions: t.Optional[ExpOrStr],
3727        append: bool = True,
3728        dialect: DialectType = None,
3729        copy: bool = True,
3730        **opts,
3731    ) -> Select:
3732        return _apply_conjunction_builder(
3733            *expressions,
3734            instance=self,
3735            arg="qualify",
3736            append=append,
3737            into=Qualify,
3738            dialect=dialect,
3739            copy=copy,
3740            **opts,
3741        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3743    def distinct(
3744        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3745    ) -> Select:
3746        """
3747        Set the OFFSET expression.
3748
3749        Example:
3750            >>> Select().from_("tbl").select("x").distinct().sql()
3751            'SELECT DISTINCT x FROM tbl'
3752
3753        Args:
3754            ons: the expressions to distinct on
3755            distinct: whether the Select should be distinct
3756            copy: if `False`, modify this expression instance in-place.
3757
3758        Returns:
3759            Select: the modified expression.
3760        """
3761        instance = maybe_copy(self, copy)
3762        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3763        instance.set("distinct", Distinct(on=on) if distinct else None)
3764        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:
3766    def ctas(
3767        self,
3768        table: ExpOrStr,
3769        properties: t.Optional[t.Dict] = None,
3770        dialect: DialectType = None,
3771        copy: bool = True,
3772        **opts,
3773    ) -> Create:
3774        """
3775        Convert this expression to a CREATE TABLE AS statement.
3776
3777        Example:
3778            >>> Select().select("*").from_("tbl").ctas("x").sql()
3779            'CREATE TABLE x AS SELECT * FROM tbl'
3780
3781        Args:
3782            table: the SQL code string to parse as the table name.
3783                If another `Expression` instance is passed, it will be used as-is.
3784            properties: an optional mapping of table properties
3785            dialect: the dialect used to parse the input table.
3786            copy: if `False`, modify this expression instance in-place.
3787            opts: other options to use to parse the input table.
3788
3789        Returns:
3790            The new Create expression.
3791        """
3792        instance = maybe_copy(self, copy)
3793        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3794
3795        properties_expression = None
3796        if properties:
3797            properties_expression = Properties.from_dict(properties)
3798
3799        return Create(
3800            this=table_expression,
3801            kind="TABLE",
3802            expression=instance,
3803            properties=properties_expression,
3804        )

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:
3806    def lock(self, update: bool = True, copy: bool = True) -> Select:
3807        """
3808        Set the locking read mode for this expression.
3809
3810        Examples:
3811            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3812            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3813
3814            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3815            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3816
3817        Args:
3818            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3819            copy: if `False`, modify this expression instance in-place.
3820
3821        Returns:
3822            The modified expression.
3823        """
3824        inst = maybe_copy(self, copy)
3825        inst.set("locks", [Lock(update=update)])
3826
3827        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:
3829    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3830        """
3831        Set hints for this expression.
3832
3833        Examples:
3834            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3835            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3836
3837        Args:
3838            hints: The SQL code strings to parse as the hints.
3839                If an `Expression` instance is passed, it will be used as-is.
3840            dialect: The dialect used to parse the hints.
3841            copy: If `False`, modify this expression instance in-place.
3842
3843        Returns:
3844            The modified expression.
3845        """
3846        inst = maybe_copy(self, copy)
3847        inst.set(
3848            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3849        )
3850
3851        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]
3853    @property
3854    def named_selects(self) -> t.List[str]:
3855        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
3857    @property
3858    def is_star(self) -> bool:
3859        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3861    @property
3862    def selects(self) -> t.List[Expression]:
3863        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
3869class Subquery(DerivedTable, Query):
3870    arg_types = {
3871        "this": True,
3872        "alias": False,
3873        "with": False,
3874        **QUERY_MODIFIERS,
3875    }
3876
3877    def unnest(self):
3878        """Returns the first non subquery."""
3879        expression = self
3880        while isinstance(expression, Subquery):
3881            expression = expression.this
3882        return expression
3883
3884    def unwrap(self) -> Subquery:
3885        expression = self
3886        while expression.same_parent and expression.is_wrapper:
3887            expression = t.cast(Subquery, expression.parent)
3888        return expression
3889
3890    def select(
3891        self,
3892        *expressions: t.Optional[ExpOrStr],
3893        append: bool = True,
3894        dialect: DialectType = None,
3895        copy: bool = True,
3896        **opts,
3897    ) -> Subquery:
3898        this = maybe_copy(self, copy)
3899        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3900        return this
3901
3902    @property
3903    def is_wrapper(self) -> bool:
3904        """
3905        Whether this Subquery acts as a simple wrapper around another expression.
3906
3907        SELECT * FROM (((SELECT * FROM t)))
3908                      ^
3909                      This corresponds to a "wrapper" Subquery node
3910        """
3911        return all(v is None for k, v in self.args.items() if k != "this")
3912
3913    @property
3914    def is_star(self) -> bool:
3915        return self.this.is_star
3916
3917    @property
3918    def output_name(self) -> str:
3919        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):
3877    def unnest(self):
3878        """Returns the first non subquery."""
3879        expression = self
3880        while isinstance(expression, Subquery):
3881            expression = expression.this
3882        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3884    def unwrap(self) -> Subquery:
3885        expression = self
3886        while expression.same_parent and expression.is_wrapper:
3887            expression = t.cast(Subquery, expression.parent)
3888        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:
3890    def select(
3891        self,
3892        *expressions: t.Optional[ExpOrStr],
3893        append: bool = True,
3894        dialect: DialectType = None,
3895        copy: bool = True,
3896        **opts,
3897    ) -> Subquery:
3898        this = maybe_copy(self, copy)
3899        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3900        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
3902    @property
3903    def is_wrapper(self) -> bool:
3904        """
3905        Whether this Subquery acts as a simple wrapper around another expression.
3906
3907        SELECT * FROM (((SELECT * FROM t)))
3908                      ^
3909                      This corresponds to a "wrapper" Subquery node
3910        """
3911        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
3913    @property
3914    def is_star(self) -> bool:
3915        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3917    @property
3918    def output_name(self) -> str:
3919        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):
3922class TableSample(Expression):
3923    arg_types = {
3924        "expressions": False,
3925        "method": False,
3926        "bucket_numerator": False,
3927        "bucket_denominator": False,
3928        "bucket_field": False,
3929        "percent": False,
3930        "rows": False,
3931        "size": False,
3932        "seed": False,
3933    }
arg_types = {'expressions': False, 'method': False, 'bucket_numerator': False, 'bucket_denominator': False, 'bucket_field': False, 'percent': False, 'rows': False, 'size': False, 'seed': False}
key = 'tablesample'
class Tag(Expression):
3936class Tag(Expression):
3937    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3938
3939    arg_types = {
3940        "this": False,
3941        "prefix": False,
3942        "postfix": False,
3943    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3948class Pivot(Expression):
3949    arg_types = {
3950        "this": False,
3951        "alias": False,
3952        "expressions": False,
3953        "field": False,
3954        "unpivot": False,
3955        "using": False,
3956        "group": False,
3957        "columns": False,
3958        "include_nulls": False,
3959        "default_on_null": False,
3960    }
3961
3962    @property
3963    def unpivot(self) -> bool:
3964        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
3962    @property
3963    def unpivot(self) -> bool:
3964        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3967class Window(Condition):
3968    arg_types = {
3969        "this": True,
3970        "partition_by": False,
3971        "order": False,
3972        "spec": False,
3973        "alias": False,
3974        "over": False,
3975        "first": False,
3976    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3979class WindowSpec(Expression):
3980    arg_types = {
3981        "kind": False,
3982        "start": False,
3983        "start_side": False,
3984        "end": False,
3985        "end_side": False,
3986    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3989class PreWhere(Expression):
3990    pass
key = 'prewhere'
class Where(Expression):
3993class Where(Expression):
3994    pass
key = 'where'
class Star(Expression):
3997class Star(Expression):
3998    arg_types = {"except": False, "replace": False, "rename": False}
3999
4000    @property
4001    def name(self) -> str:
4002        return "*"
4003
4004    @property
4005    def output_name(self) -> str:
4006        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4000    @property
4001    def name(self) -> str:
4002        return "*"
output_name: str
4004    @property
4005    def output_name(self) -> str:
4006        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):
4009class Parameter(Condition):
4010    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4013class SessionParameter(Condition):
4014    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4017class Placeholder(Condition):
4018    arg_types = {"this": False, "kind": False}
4019
4020    @property
4021    def name(self) -> str:
4022        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4020    @property
4021    def name(self) -> str:
4022        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4025class Null(Condition):
4026    arg_types: t.Dict[str, t.Any] = {}
4027
4028    @property
4029    def name(self) -> str:
4030        return "NULL"
4031
4032    def to_py(self) -> Lit[None]:
4033        return None
arg_types: Dict[str, Any] = {}
name: str
4028    @property
4029    def name(self) -> str:
4030        return "NULL"
def to_py(self) -> Literal[None]:
4032    def to_py(self) -> Lit[None]:
4033        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4036class Boolean(Condition):
4037    def to_py(self) -> bool:
4038        return self.this
def to_py(self) -> bool:
4037    def to_py(self) -> bool:
4038        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4041class DataTypeParam(Expression):
4042    arg_types = {"this": True, "expression": False}
4043
4044    @property
4045    def name(self) -> str:
4046        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4044    @property
4045    def name(self) -> str:
4046        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4051class DataType(Expression):
4052    arg_types = {
4053        "this": True,
4054        "expressions": False,
4055        "nested": False,
4056        "values": False,
4057        "prefix": False,
4058        "kind": False,
4059        "nullable": False,
4060    }
4061
4062    class Type(AutoName):
4063        ARRAY = auto()
4064        AGGREGATEFUNCTION = auto()
4065        SIMPLEAGGREGATEFUNCTION = auto()
4066        BIGDECIMAL = auto()
4067        BIGINT = auto()
4068        BIGSERIAL = auto()
4069        BINARY = auto()
4070        BIT = auto()
4071        BOOLEAN = auto()
4072        BPCHAR = auto()
4073        CHAR = auto()
4074        DATE = auto()
4075        DATE32 = auto()
4076        DATEMULTIRANGE = auto()
4077        DATERANGE = auto()
4078        DATETIME = auto()
4079        DATETIME64 = auto()
4080        DECIMAL = auto()
4081        DECIMAL32 = auto()
4082        DECIMAL64 = auto()
4083        DECIMAL128 = auto()
4084        DOUBLE = auto()
4085        ENUM = auto()
4086        ENUM8 = auto()
4087        ENUM16 = auto()
4088        FIXEDSTRING = auto()
4089        FLOAT = auto()
4090        GEOGRAPHY = auto()
4091        GEOMETRY = auto()
4092        HLLSKETCH = auto()
4093        HSTORE = auto()
4094        IMAGE = auto()
4095        INET = auto()
4096        INT = auto()
4097        INT128 = auto()
4098        INT256 = auto()
4099        INT4MULTIRANGE = auto()
4100        INT4RANGE = auto()
4101        INT8MULTIRANGE = auto()
4102        INT8RANGE = auto()
4103        INTERVAL = auto()
4104        IPADDRESS = auto()
4105        IPPREFIX = auto()
4106        IPV4 = auto()
4107        IPV6 = auto()
4108        JSON = auto()
4109        JSONB = auto()
4110        LIST = auto()
4111        LONGBLOB = auto()
4112        LONGTEXT = auto()
4113        LOWCARDINALITY = auto()
4114        MAP = auto()
4115        MEDIUMBLOB = auto()
4116        MEDIUMINT = auto()
4117        MEDIUMTEXT = auto()
4118        MONEY = auto()
4119        NAME = auto()
4120        NCHAR = auto()
4121        NESTED = auto()
4122        NULL = auto()
4123        NUMMULTIRANGE = auto()
4124        NUMRANGE = auto()
4125        NVARCHAR = auto()
4126        OBJECT = auto()
4127        ROWVERSION = auto()
4128        SERIAL = auto()
4129        SET = auto()
4130        SMALLINT = auto()
4131        SMALLMONEY = auto()
4132        SMALLSERIAL = auto()
4133        STRUCT = auto()
4134        SUPER = auto()
4135        TEXT = auto()
4136        TINYBLOB = auto()
4137        TINYTEXT = auto()
4138        TIME = auto()
4139        TIMETZ = auto()
4140        TIMESTAMP = auto()
4141        TIMESTAMPNTZ = auto()
4142        TIMESTAMPLTZ = auto()
4143        TIMESTAMPTZ = auto()
4144        TIMESTAMP_S = auto()
4145        TIMESTAMP_MS = auto()
4146        TIMESTAMP_NS = auto()
4147        TINYINT = auto()
4148        TSMULTIRANGE = auto()
4149        TSRANGE = auto()
4150        TSTZMULTIRANGE = auto()
4151        TSTZRANGE = auto()
4152        UBIGINT = auto()
4153        UINT = auto()
4154        UINT128 = auto()
4155        UINT256 = auto()
4156        UMEDIUMINT = auto()
4157        UDECIMAL = auto()
4158        UNION = auto()
4159        UNIQUEIDENTIFIER = auto()
4160        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4161        USERDEFINED = "USER-DEFINED"
4162        USMALLINT = auto()
4163        UTINYINT = auto()
4164        UUID = auto()
4165        VARBINARY = auto()
4166        VARCHAR = auto()
4167        VARIANT = auto()
4168        VECTOR = auto()
4169        XML = auto()
4170        YEAR = auto()
4171        TDIGEST = auto()
4172
4173    STRUCT_TYPES = {
4174        Type.NESTED,
4175        Type.OBJECT,
4176        Type.STRUCT,
4177        Type.UNION,
4178    }
4179
4180    ARRAY_TYPES = {
4181        Type.ARRAY,
4182        Type.LIST,
4183    }
4184
4185    NESTED_TYPES = {
4186        *STRUCT_TYPES,
4187        *ARRAY_TYPES,
4188        Type.MAP,
4189    }
4190
4191    TEXT_TYPES = {
4192        Type.CHAR,
4193        Type.NCHAR,
4194        Type.NVARCHAR,
4195        Type.TEXT,
4196        Type.VARCHAR,
4197        Type.NAME,
4198    }
4199
4200    SIGNED_INTEGER_TYPES = {
4201        Type.BIGINT,
4202        Type.INT,
4203        Type.INT128,
4204        Type.INT256,
4205        Type.MEDIUMINT,
4206        Type.SMALLINT,
4207        Type.TINYINT,
4208    }
4209
4210    UNSIGNED_INTEGER_TYPES = {
4211        Type.UBIGINT,
4212        Type.UINT,
4213        Type.UINT128,
4214        Type.UINT256,
4215        Type.UMEDIUMINT,
4216        Type.USMALLINT,
4217        Type.UTINYINT,
4218    }
4219
4220    INTEGER_TYPES = {
4221        *SIGNED_INTEGER_TYPES,
4222        *UNSIGNED_INTEGER_TYPES,
4223        Type.BIT,
4224    }
4225
4226    FLOAT_TYPES = {
4227        Type.DOUBLE,
4228        Type.FLOAT,
4229    }
4230
4231    REAL_TYPES = {
4232        *FLOAT_TYPES,
4233        Type.BIGDECIMAL,
4234        Type.DECIMAL,
4235        Type.DECIMAL32,
4236        Type.DECIMAL64,
4237        Type.DECIMAL128,
4238        Type.MONEY,
4239        Type.SMALLMONEY,
4240        Type.UDECIMAL,
4241    }
4242
4243    NUMERIC_TYPES = {
4244        *INTEGER_TYPES,
4245        *REAL_TYPES,
4246    }
4247
4248    TEMPORAL_TYPES = {
4249        Type.DATE,
4250        Type.DATE32,
4251        Type.DATETIME,
4252        Type.DATETIME64,
4253        Type.TIME,
4254        Type.TIMESTAMP,
4255        Type.TIMESTAMPNTZ,
4256        Type.TIMESTAMPLTZ,
4257        Type.TIMESTAMPTZ,
4258        Type.TIMESTAMP_MS,
4259        Type.TIMESTAMP_NS,
4260        Type.TIMESTAMP_S,
4261        Type.TIMETZ,
4262    }
4263
4264    @classmethod
4265    def build(
4266        cls,
4267        dtype: DATA_TYPE,
4268        dialect: DialectType = None,
4269        udt: bool = False,
4270        copy: bool = True,
4271        **kwargs,
4272    ) -> DataType:
4273        """
4274        Constructs a DataType object.
4275
4276        Args:
4277            dtype: the data type of interest.
4278            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4279            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4280                DataType, thus creating a user-defined type.
4281            copy: whether to copy the data type.
4282            kwargs: additional arguments to pass in the constructor of DataType.
4283
4284        Returns:
4285            The constructed DataType object.
4286        """
4287        from sqlglot import parse_one
4288
4289        if isinstance(dtype, str):
4290            if dtype.upper() == "UNKNOWN":
4291                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4292
4293            try:
4294                data_type_exp = parse_one(
4295                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4296                )
4297            except ParseError:
4298                if udt:
4299                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4300                raise
4301        elif isinstance(dtype, DataType.Type):
4302            data_type_exp = DataType(this=dtype)
4303        elif isinstance(dtype, DataType):
4304            return maybe_copy(dtype, copy)
4305        else:
4306            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4307
4308        return DataType(**{**data_type_exp.args, **kwargs})
4309
4310    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4311        """
4312        Checks whether this DataType matches one of the provided data types. Nested types or precision
4313        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4314
4315        Args:
4316            dtypes: the data types to compare this DataType to.
4317            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4318                If false, it means that NULLABLE<INT> is equivalent to INT.
4319
4320        Returns:
4321            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4322        """
4323        self_is_nullable = self.args.get("nullable")
4324        for dtype in dtypes:
4325            other_type = DataType.build(dtype, copy=False, udt=True)
4326            other_is_nullable = other_type.args.get("nullable")
4327            if (
4328                other_type.expressions
4329                or (check_nullable and (self_is_nullable or other_is_nullable))
4330                or self.this == DataType.Type.USERDEFINED
4331                or other_type.this == DataType.Type.USERDEFINED
4332            ):
4333                matches = self == other_type
4334            else:
4335                matches = self.this == other_type.this
4336
4337            if matches:
4338                return True
4339        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.UNION: 'UNION'>, <Type.STRUCT: 'STRUCT'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>}
ARRAY_TYPES = {<Type.LIST: 'LIST'>, <Type.ARRAY: 'ARRAY'>}
NESTED_TYPES = {<Type.LIST: 'LIST'>, <Type.MAP: 'MAP'>, <Type.STRUCT: 'STRUCT'>, <Type.OBJECT: 'OBJECT'>, <Type.UNION: 'UNION'>, <Type.ARRAY: 'ARRAY'>, <Type.NESTED: 'NESTED'>}
TEXT_TYPES = {<Type.TEXT: 'TEXT'>, <Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NAME: 'NAME'>, <Type.NCHAR: 'NCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGINT: 'BIGINT'>, <Type.INT256: 'INT256'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>}
UNSIGNED_INTEGER_TYPES = {<Type.UTINYINT: 'UTINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT: 'UINT'>, <Type.UINT256: 'UINT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>}
INTEGER_TYPES = {<Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGINT: 'BIGINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT: 'UINT'>, <Type.INT256: 'INT256'>, <Type.UINT256: 'UINT256'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.BIT: 'BIT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.UINT128: 'UINT128'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.DECIMAL32: 'DECIMAL32'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.MONEY: 'MONEY'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL128: 'DECIMAL128'>}
NUMERIC_TYPES = {<Type.UTINYINT: 'UTINYINT'>, <Type.BIGINT: 'BIGINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.INT256: 'INT256'>, <Type.DOUBLE: 'DOUBLE'>, <Type.MONEY: 'MONEY'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.UINT: 'UINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UINT256: 'UINT256'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.USMALLINT: 'USMALLINT'>, <Type.BIT: 'BIT'>, <Type.FLOAT: 'FLOAT'>, <Type.INT: 'INT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.UINT128: 'UINT128'>}
TEMPORAL_TYPES = {<Type.DATE32: 'DATE32'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATETIME: 'DATETIME'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>}
@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:
4264    @classmethod
4265    def build(
4266        cls,
4267        dtype: DATA_TYPE,
4268        dialect: DialectType = None,
4269        udt: bool = False,
4270        copy: bool = True,
4271        **kwargs,
4272    ) -> DataType:
4273        """
4274        Constructs a DataType object.
4275
4276        Args:
4277            dtype: the data type of interest.
4278            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4279            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4280                DataType, thus creating a user-defined type.
4281            copy: whether to copy the data type.
4282            kwargs: additional arguments to pass in the constructor of DataType.
4283
4284        Returns:
4285            The constructed DataType object.
4286        """
4287        from sqlglot import parse_one
4288
4289        if isinstance(dtype, str):
4290            if dtype.upper() == "UNKNOWN":
4291                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4292
4293            try:
4294                data_type_exp = parse_one(
4295                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4296                )
4297            except ParseError:
4298                if udt:
4299                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4300                raise
4301        elif isinstance(dtype, DataType.Type):
4302            data_type_exp = DataType(this=dtype)
4303        elif isinstance(dtype, DataType):
4304            return maybe_copy(dtype, copy)
4305        else:
4306            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4307
4308        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:
4310    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4311        """
4312        Checks whether this DataType matches one of the provided data types. Nested types or precision
4313        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4314
4315        Args:
4316            dtypes: the data types to compare this DataType to.
4317            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4318                If false, it means that NULLABLE<INT> is equivalent to INT.
4319
4320        Returns:
4321            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4322        """
4323        self_is_nullable = self.args.get("nullable")
4324        for dtype in dtypes:
4325            other_type = DataType.build(dtype, copy=False, udt=True)
4326            other_is_nullable = other_type.args.get("nullable")
4327            if (
4328                other_type.expressions
4329                or (check_nullable and (self_is_nullable or other_is_nullable))
4330                or self.this == DataType.Type.USERDEFINED
4331                or other_type.this == DataType.Type.USERDEFINED
4332            ):
4333                matches = self == other_type
4334            else:
4335                matches = self.this == other_type.this
4336
4337            if matches:
4338                return True
4339        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):
4062    class Type(AutoName):
4063        ARRAY = auto()
4064        AGGREGATEFUNCTION = auto()
4065        SIMPLEAGGREGATEFUNCTION = auto()
4066        BIGDECIMAL = auto()
4067        BIGINT = auto()
4068        BIGSERIAL = auto()
4069        BINARY = auto()
4070        BIT = auto()
4071        BOOLEAN = auto()
4072        BPCHAR = auto()
4073        CHAR = auto()
4074        DATE = auto()
4075        DATE32 = auto()
4076        DATEMULTIRANGE = auto()
4077        DATERANGE = auto()
4078        DATETIME = auto()
4079        DATETIME64 = auto()
4080        DECIMAL = auto()
4081        DECIMAL32 = auto()
4082        DECIMAL64 = auto()
4083        DECIMAL128 = auto()
4084        DOUBLE = auto()
4085        ENUM = auto()
4086        ENUM8 = auto()
4087        ENUM16 = auto()
4088        FIXEDSTRING = auto()
4089        FLOAT = auto()
4090        GEOGRAPHY = auto()
4091        GEOMETRY = auto()
4092        HLLSKETCH = auto()
4093        HSTORE = auto()
4094        IMAGE = auto()
4095        INET = auto()
4096        INT = auto()
4097        INT128 = auto()
4098        INT256 = auto()
4099        INT4MULTIRANGE = auto()
4100        INT4RANGE = auto()
4101        INT8MULTIRANGE = auto()
4102        INT8RANGE = auto()
4103        INTERVAL = auto()
4104        IPADDRESS = auto()
4105        IPPREFIX = auto()
4106        IPV4 = auto()
4107        IPV6 = auto()
4108        JSON = auto()
4109        JSONB = auto()
4110        LIST = auto()
4111        LONGBLOB = auto()
4112        LONGTEXT = auto()
4113        LOWCARDINALITY = auto()
4114        MAP = auto()
4115        MEDIUMBLOB = auto()
4116        MEDIUMINT = auto()
4117        MEDIUMTEXT = auto()
4118        MONEY = auto()
4119        NAME = auto()
4120        NCHAR = auto()
4121        NESTED = auto()
4122        NULL = auto()
4123        NUMMULTIRANGE = auto()
4124        NUMRANGE = auto()
4125        NVARCHAR = auto()
4126        OBJECT = auto()
4127        ROWVERSION = auto()
4128        SERIAL = auto()
4129        SET = auto()
4130        SMALLINT = auto()
4131        SMALLMONEY = auto()
4132        SMALLSERIAL = auto()
4133        STRUCT = auto()
4134        SUPER = auto()
4135        TEXT = auto()
4136        TINYBLOB = auto()
4137        TINYTEXT = auto()
4138        TIME = auto()
4139        TIMETZ = auto()
4140        TIMESTAMP = auto()
4141        TIMESTAMPNTZ = auto()
4142        TIMESTAMPLTZ = auto()
4143        TIMESTAMPTZ = auto()
4144        TIMESTAMP_S = auto()
4145        TIMESTAMP_MS = auto()
4146        TIMESTAMP_NS = auto()
4147        TINYINT = auto()
4148        TSMULTIRANGE = auto()
4149        TSRANGE = auto()
4150        TSTZMULTIRANGE = auto()
4151        TSTZRANGE = auto()
4152        UBIGINT = auto()
4153        UINT = auto()
4154        UINT128 = auto()
4155        UINT256 = auto()
4156        UMEDIUMINT = auto()
4157        UDECIMAL = auto()
4158        UNION = auto()
4159        UNIQUEIDENTIFIER = auto()
4160        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4161        USERDEFINED = "USER-DEFINED"
4162        USMALLINT = auto()
4163        UTINYINT = auto()
4164        UUID = auto()
4165        VARBINARY = auto()
4166        VARCHAR = auto()
4167        VARIANT = auto()
4168        VECTOR = auto()
4169        XML = auto()
4170        YEAR = auto()
4171        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'>
DECIMAL32 = <Type.DECIMAL32: 'DECIMAL32'>
DECIMAL64 = <Type.DECIMAL64: 'DECIMAL64'>
DECIMAL128 = <Type.DECIMAL128: 'DECIMAL128'>
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'>
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'>
UNION = <Type.UNION: 'UNION'>
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):
4346class PseudoType(DataType):
4347    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4351class ObjectIdentifier(DataType):
4352    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4356class SubqueryPredicate(Predicate):
4357    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4360class All(SubqueryPredicate):
4361    pass
key = 'all'
class Any(SubqueryPredicate):
4364class Any(SubqueryPredicate):
4365    pass
key = 'any'
class Exists(SubqueryPredicate):
4368class Exists(SubqueryPredicate):
4369    pass
key = 'exists'
class Command(Expression):
4374class Command(Expression):
4375    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4378class Transaction(Expression):
4379    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4382class Commit(Expression):
4383    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4386class Rollback(Expression):
4387    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4390class Alter(Expression):
4391    arg_types = {
4392        "this": True,
4393        "kind": True,
4394        "actions": True,
4395        "exists": False,
4396        "only": False,
4397        "options": False,
4398        "cluster": False,
4399        "not_valid": False,
4400    }
4401
4402    @property
4403    def kind(self) -> t.Optional[str]:
4404        kind = self.args.get("kind")
4405        return kind and kind.upper()
4406
4407    @property
4408    def actions(self) -> t.List[Expression]:
4409        return self.args.get("actions") or []
arg_types = {'this': True, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False, 'not_valid': False}
kind: Optional[str]
4402    @property
4403    def kind(self) -> t.Optional[str]:
4404        kind = self.args.get("kind")
4405        return kind and kind.upper()
actions: List[Expression]
4407    @property
4408    def actions(self) -> t.List[Expression]:
4409        return self.args.get("actions") or []
key = 'alter'
class AddConstraint(Expression):
4412class AddConstraint(Expression):
4413    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4416class DropPartition(Expression):
4417    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4421class ReplacePartition(Expression):
4422    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4426class Binary(Condition):
4427    arg_types = {"this": True, "expression": True}
4428
4429    @property
4430    def left(self) -> Expression:
4431        return self.this
4432
4433    @property
4434    def right(self) -> Expression:
4435        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4429    @property
4430    def left(self) -> Expression:
4431        return self.this
right: Expression
4433    @property
4434    def right(self) -> Expression:
4435        return self.expression
key = 'binary'
class Add(Binary):
4438class Add(Binary):
4439    pass
key = 'add'
class Connector(Binary):
4442class Connector(Binary):
4443    pass
key = 'connector'
class And(Connector):
4446class And(Connector):
4447    pass
key = 'and'
class Or(Connector):
4450class Or(Connector):
4451    pass
key = 'or'
class BitwiseAnd(Binary):
4454class BitwiseAnd(Binary):
4455    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4458class BitwiseLeftShift(Binary):
4459    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4462class BitwiseOr(Binary):
4463    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4466class BitwiseRightShift(Binary):
4467    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4470class BitwiseXor(Binary):
4471    pass
key = 'bitwisexor'
class Div(Binary):
4474class Div(Binary):
4475    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):
4478class Overlaps(Binary):
4479    pass
key = 'overlaps'
class Dot(Binary):
4482class Dot(Binary):
4483    @property
4484    def is_star(self) -> bool:
4485        return self.expression.is_star
4486
4487    @property
4488    def name(self) -> str:
4489        return self.expression.name
4490
4491    @property
4492    def output_name(self) -> str:
4493        return self.name
4494
4495    @classmethod
4496    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4497        """Build a Dot object with a sequence of expressions."""
4498        if len(expressions) < 2:
4499            raise ValueError("Dot requires >= 2 expressions.")
4500
4501        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4502
4503    @property
4504    def parts(self) -> t.List[Expression]:
4505        """Return the parts of a table / column in order catalog, db, table."""
4506        this, *parts = self.flatten()
4507
4508        parts.reverse()
4509
4510        for arg in COLUMN_PARTS:
4511            part = this.args.get(arg)
4512
4513            if isinstance(part, Expression):
4514                parts.append(part)
4515
4516        parts.reverse()
4517        return parts
is_star: bool
4483    @property
4484    def is_star(self) -> bool:
4485        return self.expression.is_star

Checks whether an expression is a star.

name: str
4487    @property
4488    def name(self) -> str:
4489        return self.expression.name
output_name: str
4491    @property
4492    def output_name(self) -> str:
4493        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:
4495    @classmethod
4496    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4497        """Build a Dot object with a sequence of expressions."""
4498        if len(expressions) < 2:
4499            raise ValueError("Dot requires >= 2 expressions.")
4500
4501        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]
4503    @property
4504    def parts(self) -> t.List[Expression]:
4505        """Return the parts of a table / column in order catalog, db, table."""
4506        this, *parts = self.flatten()
4507
4508        parts.reverse()
4509
4510        for arg in COLUMN_PARTS:
4511            part = this.args.get(arg)
4512
4513            if isinstance(part, Expression):
4514                parts.append(part)
4515
4516        parts.reverse()
4517        return parts

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

key = 'dot'
class DPipe(Binary):
4520class DPipe(Binary):
4521    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4524class EQ(Binary, Predicate):
4525    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4528class NullSafeEQ(Binary, Predicate):
4529    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4532class NullSafeNEQ(Binary, Predicate):
4533    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4537class PropertyEQ(Binary):
4538    pass
key = 'propertyeq'
class Distance(Binary):
4541class Distance(Binary):
4542    pass
key = 'distance'
class Escape(Binary):
4545class Escape(Binary):
4546    pass
key = 'escape'
class Glob(Binary, Predicate):
4549class Glob(Binary, Predicate):
4550    pass
key = 'glob'
class GT(Binary, Predicate):
4553class GT(Binary, Predicate):
4554    pass
key = 'gt'
class GTE(Binary, Predicate):
4557class GTE(Binary, Predicate):
4558    pass
key = 'gte'
class ILike(Binary, Predicate):
4561class ILike(Binary, Predicate):
4562    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4565class ILikeAny(Binary, Predicate):
4566    pass
key = 'ilikeany'
class IntDiv(Binary):
4569class IntDiv(Binary):
4570    pass
key = 'intdiv'
class Is(Binary, Predicate):
4573class Is(Binary, Predicate):
4574    pass
key = 'is'
class Kwarg(Binary):
4577class Kwarg(Binary):
4578    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4581class Like(Binary, Predicate):
4582    pass
key = 'like'
class LikeAny(Binary, Predicate):
4585class LikeAny(Binary, Predicate):
4586    pass
key = 'likeany'
class LT(Binary, Predicate):
4589class LT(Binary, Predicate):
4590    pass
key = 'lt'
class LTE(Binary, Predicate):
4593class LTE(Binary, Predicate):
4594    pass
key = 'lte'
class Mod(Binary):
4597class Mod(Binary):
4598    pass
key = 'mod'
class Mul(Binary):
4601class Mul(Binary):
4602    pass
key = 'mul'
class NEQ(Binary, Predicate):
4605class NEQ(Binary, Predicate):
4606    pass
key = 'neq'
class Operator(Binary):
4610class Operator(Binary):
4611    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4614class SimilarTo(Binary, Predicate):
4615    pass
key = 'similarto'
class Slice(Binary):
4618class Slice(Binary):
4619    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4622class Sub(Binary):
4623    pass
key = 'sub'
class Unary(Condition):
4628class Unary(Condition):
4629    pass
key = 'unary'
class BitwiseNot(Unary):
4632class BitwiseNot(Unary):
4633    pass
key = 'bitwisenot'
class Not(Unary):
4636class Not(Unary):
4637    pass
key = 'not'
class Paren(Unary):
4640class Paren(Unary):
4641    @property
4642    def output_name(self) -> str:
4643        return self.this.name
output_name: str
4641    @property
4642    def output_name(self) -> str:
4643        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):
4646class Neg(Unary):
4647    def to_py(self) -> int | Decimal:
4648        if self.is_number:
4649            return self.this.to_py() * -1
4650        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4647    def to_py(self) -> int | Decimal:
4648        if self.is_number:
4649            return self.this.to_py() * -1
4650        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4653class Alias(Expression):
4654    arg_types = {"this": True, "alias": False}
4655
4656    @property
4657    def output_name(self) -> str:
4658        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4656    @property
4657    def output_name(self) -> str:
4658        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):
4663class PivotAlias(Alias):
4664    pass
key = 'pivotalias'
class PivotAny(Expression):
4669class PivotAny(Expression):
4670    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4673class Aliases(Expression):
4674    arg_types = {"this": True, "expressions": True}
4675
4676    @property
4677    def aliases(self):
4678        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4676    @property
4677    def aliases(self):
4678        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4682class AtIndex(Expression):
4683    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4686class AtTimeZone(Expression):
4687    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4690class FromTimeZone(Expression):
4691    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4694class Between(Predicate):
4695    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4698class Bracket(Condition):
4699    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4700    arg_types = {
4701        "this": True,
4702        "expressions": True,
4703        "offset": False,
4704        "safe": False,
4705        "returns_list_for_maps": False,
4706    }
4707
4708    @property
4709    def output_name(self) -> str:
4710        if len(self.expressions) == 1:
4711            return self.expressions[0].output_name
4712
4713        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4708    @property
4709    def output_name(self) -> str:
4710        if len(self.expressions) == 1:
4711            return self.expressions[0].output_name
4712
4713        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):
4716class Distinct(Expression):
4717    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4720class In(Predicate):
4721    arg_types = {
4722        "this": True,
4723        "expressions": False,
4724        "query": False,
4725        "unnest": False,
4726        "field": False,
4727        "is_global": False,
4728    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4732class ForIn(Expression):
4733    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4736class TimeUnit(Expression):
4737    """Automatically converts unit arg into a var."""
4738
4739    arg_types = {"unit": False}
4740
4741    UNABBREVIATED_UNIT_NAME = {
4742        "D": "DAY",
4743        "H": "HOUR",
4744        "M": "MINUTE",
4745        "MS": "MILLISECOND",
4746        "NS": "NANOSECOND",
4747        "Q": "QUARTER",
4748        "S": "SECOND",
4749        "US": "MICROSECOND",
4750        "W": "WEEK",
4751        "Y": "YEAR",
4752    }
4753
4754    VAR_LIKE = (Column, Literal, Var)
4755
4756    def __init__(self, **args):
4757        unit = args.get("unit")
4758        if isinstance(unit, self.VAR_LIKE):
4759            args["unit"] = Var(
4760                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4761            )
4762        elif isinstance(unit, Week):
4763            unit.set("this", Var(this=unit.this.name.upper()))
4764
4765        super().__init__(**args)
4766
4767    @property
4768    def unit(self) -> t.Optional[Var | IntervalSpan]:
4769        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4756    def __init__(self, **args):
4757        unit = args.get("unit")
4758        if isinstance(unit, self.VAR_LIKE):
4759            args["unit"] = Var(
4760                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4761            )
4762        elif isinstance(unit, Week):
4763            unit.set("this", Var(this=unit.this.name.upper()))
4764
4765        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]
4767    @property
4768    def unit(self) -> t.Optional[Var | IntervalSpan]:
4769        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4772class IntervalOp(TimeUnit):
4773    arg_types = {"unit": False, "expression": True}
4774
4775    def interval(self):
4776        return Interval(
4777            this=self.expression.copy(),
4778            unit=self.unit.copy() if self.unit else None,
4779        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
4775    def interval(self):
4776        return Interval(
4777            this=self.expression.copy(),
4778            unit=self.unit.copy() if self.unit else None,
4779        )
key = 'intervalop'
class IntervalSpan(DataType):
4785class IntervalSpan(DataType):
4786    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4789class Interval(TimeUnit):
4790    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4793class IgnoreNulls(Expression):
4794    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4797class RespectNulls(Expression):
4798    pass
key = 'respectnulls'
class HavingMax(Expression):
4802class HavingMax(Expression):
4803    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4807class Func(Condition):
4808    """
4809    The base class for all function expressions.
4810
4811    Attributes:
4812        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4813            treated as a variable length argument and the argument's value will be stored as a list.
4814        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4815            function expression. These values are used to map this node to a name during parsing as
4816            well as to provide the function's name during SQL string generation. By default the SQL
4817            name is set to the expression's class name transformed to snake case.
4818    """
4819
4820    is_var_len_args = False
4821
4822    @classmethod
4823    def from_arg_list(cls, args):
4824        if cls.is_var_len_args:
4825            all_arg_keys = list(cls.arg_types)
4826            # If this function supports variable length argument treat the last argument as such.
4827            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4828            num_non_var = len(non_var_len_arg_keys)
4829
4830            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4831            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4832        else:
4833            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4834
4835        return cls(**args_dict)
4836
4837    @classmethod
4838    def sql_names(cls):
4839        if cls is Func:
4840            raise NotImplementedError(
4841                "SQL name is only supported by concrete function implementations"
4842            )
4843        if "_sql_names" not in cls.__dict__:
4844            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4845        return cls._sql_names
4846
4847    @classmethod
4848    def sql_name(cls):
4849        return cls.sql_names()[0]
4850
4851    @classmethod
4852    def default_parser_mappings(cls):
4853        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):
4822    @classmethod
4823    def from_arg_list(cls, args):
4824        if cls.is_var_len_args:
4825            all_arg_keys = list(cls.arg_types)
4826            # If this function supports variable length argument treat the last argument as such.
4827            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4828            num_non_var = len(non_var_len_arg_keys)
4829
4830            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4831            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4832        else:
4833            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4834
4835        return cls(**args_dict)
@classmethod
def sql_names(cls):
4837    @classmethod
4838    def sql_names(cls):
4839        if cls is Func:
4840            raise NotImplementedError(
4841                "SQL name is only supported by concrete function implementations"
4842            )
4843        if "_sql_names" not in cls.__dict__:
4844            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4845        return cls._sql_names
@classmethod
def sql_name(cls):
4847    @classmethod
4848    def sql_name(cls):
4849        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4851    @classmethod
4852    def default_parser_mappings(cls):
4853        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4856class AggFunc(Func):
4857    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4860class ParameterizedAgg(AggFunc):
4861    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4864class Abs(Func):
4865    pass
key = 'abs'
class ArgMax(AggFunc):
4868class ArgMax(AggFunc):
4869    arg_types = {"this": True, "expression": True, "count": False}
4870    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4873class ArgMin(AggFunc):
4874    arg_types = {"this": True, "expression": True, "count": False}
4875    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4878class ApproxTopK(AggFunc):
4879    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4882class Flatten(Func):
4883    pass
key = 'flatten'
class Transform(Func):
4887class Transform(Func):
4888    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4891class Anonymous(Func):
4892    arg_types = {"this": True, "expressions": False}
4893    is_var_len_args = True
4894
4895    @property
4896    def name(self) -> str:
4897        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
4895    @property
4896    def name(self) -> str:
4897        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4900class AnonymousAggFunc(AggFunc):
4901    arg_types = {"this": True, "expressions": False}
4902    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4906class CombinedAggFunc(AnonymousAggFunc):
4907    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4910class CombinedParameterizedAgg(ParameterizedAgg):
4911    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):
4916class Hll(AggFunc):
4917    arg_types = {"this": True, "expressions": False}
4918    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4921class ApproxDistinct(AggFunc):
4922    arg_types = {"this": True, "accuracy": False}
4923    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4926class Array(Func):
4927    arg_types = {"expressions": False, "bracket_notation": False}
4928    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4932class ToArray(Func):
4933    pass
key = 'toarray'
class List(Func):
4937class List(Func):
4938    arg_types = {"expressions": False}
4939    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4943class Pad(Func):
4944    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):
4949class ToChar(Func):
4950    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4955class ToNumber(Func):
4956    arg_types = {
4957        "this": True,
4958        "format": False,
4959        "nlsparam": False,
4960        "precision": False,
4961        "scale": False,
4962    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4966class Convert(Func):
4967    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
4970class ConvertTimezone(Func):
4971    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):
4974class GenerateSeries(Func):
4975    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):
4981class ExplodingGenerateSeries(GenerateSeries):
4982    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
4985class ArrayAgg(AggFunc):
4986    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4989class ArrayUniqueAgg(AggFunc):
4990    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4993class ArrayAll(Func):
4994    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4998class ArrayAny(Func):
4999    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5002class ArrayConcat(Func):
5003    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5004    arg_types = {"this": True, "expressions": False}
5005    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5008class ArrayConstructCompact(Func):
5009    arg_types = {"expressions": True}
5010    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5013class ArrayContains(Binary, Func):
5014    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5017class ArrayContainsAll(Binary, Func):
5018    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5021class ArrayFilter(Func):
5022    arg_types = {"this": True, "expression": True}
5023    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5026class ArrayToString(Func):
5027    arg_types = {"this": True, "expression": True, "null": False}
5028    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
5031class StringToArray(Func):
5032    arg_types = {"this": True, "expression": True, "null": False}
5033    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5036class ArrayOverlaps(Binary, Func):
5037    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5040class ArraySize(Func):
5041    arg_types = {"this": True, "expression": False}
5042    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5045class ArraySort(Func):
5046    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5049class ArraySum(Func):
5050    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5053class ArrayUnionAgg(AggFunc):
5054    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5057class Avg(AggFunc):
5058    pass
key = 'avg'
class AnyValue(AggFunc):
5061class AnyValue(AggFunc):
5062    pass
key = 'anyvalue'
class Lag(AggFunc):
5065class Lag(AggFunc):
5066    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5069class Lead(AggFunc):
5070    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5075class First(AggFunc):
5076    pass
key = 'first'
class Last(AggFunc):
5079class Last(AggFunc):
5080    pass
key = 'last'
class FirstValue(AggFunc):
5083class FirstValue(AggFunc):
5084    pass
key = 'firstvalue'
class LastValue(AggFunc):
5087class LastValue(AggFunc):
5088    pass
key = 'lastvalue'
class NthValue(AggFunc):
5091class NthValue(AggFunc):
5092    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5095class Case(Func):
5096    arg_types = {"this": False, "ifs": True, "default": False}
5097
5098    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5099        instance = maybe_copy(self, copy)
5100        instance.append(
5101            "ifs",
5102            If(
5103                this=maybe_parse(condition, copy=copy, **opts),
5104                true=maybe_parse(then, copy=copy, **opts),
5105            ),
5106        )
5107        return instance
5108
5109    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5110        instance = maybe_copy(self, copy)
5111        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5112        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:
5098    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5099        instance = maybe_copy(self, copy)
5100        instance.append(
5101            "ifs",
5102            If(
5103                this=maybe_parse(condition, copy=copy, **opts),
5104                true=maybe_parse(then, copy=copy, **opts),
5105            ),
5106        )
5107        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5109    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5110        instance = maybe_copy(self, copy)
5111        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5112        return instance
key = 'case'
class Cast(Func):
5115class Cast(Func):
5116    arg_types = {
5117        "this": True,
5118        "to": True,
5119        "format": False,
5120        "safe": False,
5121        "action": False,
5122    }
5123
5124    @property
5125    def name(self) -> str:
5126        return self.this.name
5127
5128    @property
5129    def to(self) -> DataType:
5130        return self.args["to"]
5131
5132    @property
5133    def output_name(self) -> str:
5134        return self.name
5135
5136    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5137        """
5138        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5139        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5140        array<int> != array<float>.
5141
5142        Args:
5143            dtypes: the data types to compare this Cast's DataType to.
5144
5145        Returns:
5146            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5147        """
5148        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5124    @property
5125    def name(self) -> str:
5126        return self.this.name
to: DataType
5128    @property
5129    def to(self) -> DataType:
5130        return self.args["to"]
output_name: str
5132    @property
5133    def output_name(self) -> str:
5134        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:
5136    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5137        """
5138        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5139        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5140        array<int> != array<float>.
5141
5142        Args:
5143            dtypes: the data types to compare this Cast's DataType to.
5144
5145        Returns:
5146            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5147        """
5148        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):
5151class TryCast(Cast):
5152    pass
key = 'trycast'
class Try(Func):
5155class Try(Func):
5156    pass
key = 'try'
class CastToStrType(Func):
5159class CastToStrType(Func):
5160    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5163class Collate(Binary, Func):
5164    pass
key = 'collate'
class Ceil(Func):
5167class Ceil(Func):
5168    arg_types = {"this": True, "decimals": False}
5169    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5172class Coalesce(Func):
5173    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5174    is_var_len_args = True
5175    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5178class Chr(Func):
5179    arg_types = {"expressions": True, "charset": False}
5180    is_var_len_args = True
5181    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5184class Concat(Func):
5185    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5186    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5189class ConcatWs(Concat):
5190    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5194class ConnectByRoot(Func):
5195    pass
key = 'connectbyroot'
class Count(AggFunc):
5198class Count(AggFunc):
5199    arg_types = {"this": False, "expressions": False, "big_int": False}
5200    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5203class CountIf(AggFunc):
5204    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5208class Cbrt(Func):
5209    pass
key = 'cbrt'
class CurrentDate(Func):
5212class CurrentDate(Func):
5213    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5216class CurrentDatetime(Func):
5217    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5220class CurrentTime(Func):
5221    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5224class CurrentTimestamp(Func):
5225    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5228class CurrentUser(Func):
5229    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5232class DateAdd(Func, IntervalOp):
5233    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5236class DateSub(Func, IntervalOp):
5237    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5240class DateDiff(Func, TimeUnit):
5241    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5242    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5245class DateTrunc(Func):
5246    arg_types = {"unit": True, "this": True, "zone": False}
5247
5248    def __init__(self, **args):
5249        unit = args.get("unit")
5250        if isinstance(unit, TimeUnit.VAR_LIKE):
5251            args["unit"] = Literal.string(
5252                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5253            )
5254        elif isinstance(unit, Week):
5255            unit.set("this", Literal.string(unit.this.name.upper()))
5256
5257        super().__init__(**args)
5258
5259    @property
5260    def unit(self) -> Expression:
5261        return self.args["unit"]
DateTrunc(**args)
5248    def __init__(self, **args):
5249        unit = args.get("unit")
5250        if isinstance(unit, TimeUnit.VAR_LIKE):
5251            args["unit"] = Literal.string(
5252                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5253            )
5254        elif isinstance(unit, Week):
5255            unit.set("this", Literal.string(unit.this.name.upper()))
5256
5257        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5259    @property
5260    def unit(self) -> Expression:
5261        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5266class Datetime(Func):
5267    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5270class DatetimeAdd(Func, IntervalOp):
5271    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5274class DatetimeSub(Func, IntervalOp):
5275    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5278class DatetimeDiff(Func, TimeUnit):
5279    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5282class DatetimeTrunc(Func, TimeUnit):
5283    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5286class DayOfWeek(Func):
5287    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5292class DayOfWeekIso(Func):
5293    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5296class DayOfMonth(Func):
5297    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5300class DayOfYear(Func):
5301    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5304class ToDays(Func):
5305    pass
key = 'todays'
class WeekOfYear(Func):
5308class WeekOfYear(Func):
5309    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5312class MonthsBetween(Func):
5313    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5316class LastDay(Func, TimeUnit):
5317    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5318    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5321class Extract(Func):
5322    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5325class Timestamp(Func):
5326    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5329class TimestampAdd(Func, TimeUnit):
5330    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5333class TimestampSub(Func, TimeUnit):
5334    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5337class TimestampDiff(Func, TimeUnit):
5338    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5339    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5342class TimestampTrunc(Func, TimeUnit):
5343    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5346class TimeAdd(Func, TimeUnit):
5347    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5350class TimeSub(Func, TimeUnit):
5351    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5354class TimeDiff(Func, TimeUnit):
5355    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5358class TimeTrunc(Func, TimeUnit):
5359    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5362class DateFromParts(Func):
5363    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5364    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5367class TimeFromParts(Func):
5368    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5369    arg_types = {
5370        "hour": True,
5371        "min": True,
5372        "sec": True,
5373        "nano": False,
5374        "fractions": False,
5375        "precision": False,
5376    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5379class DateStrToDate(Func):
5380    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5383class DateToDateStr(Func):
5384    pass
key = 'datetodatestr'
class DateToDi(Func):
5387class DateToDi(Func):
5388    pass
key = 'datetodi'
class Date(Func):
5392class Date(Func):
5393    arg_types = {"this": False, "zone": False, "expressions": False}
5394    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5397class Day(Func):
5398    pass
key = 'day'
class Decode(Func):
5401class Decode(Func):
5402    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5405class DiToDate(Func):
5406    pass
key = 'ditodate'
class Encode(Func):
5409class Encode(Func):
5410    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5413class Exp(Func):
5414    pass
key = 'exp'
class Explode(Func):
5418class Explode(Func):
5419    arg_types = {"this": True, "expressions": False}
5420    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5424class Inline(Func):
5425    pass
key = 'inline'
class ExplodeOuter(Explode):
5428class ExplodeOuter(Explode):
5429    pass
key = 'explodeouter'
class Posexplode(Explode):
5432class Posexplode(Explode):
5433    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5436class PosexplodeOuter(Posexplode, ExplodeOuter):
5437    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5440class Unnest(Func, UDTF):
5441    arg_types = {
5442        "expressions": True,
5443        "alias": False,
5444        "offset": False,
5445        "explode_array": False,
5446    }
5447
5448    @property
5449    def selects(self) -> t.List[Expression]:
5450        columns = super().selects
5451        offset = self.args.get("offset")
5452        if offset:
5453            columns = columns + [to_identifier("offset") if offset is True else offset]
5454        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5448    @property
5449    def selects(self) -> t.List[Expression]:
5450        columns = super().selects
5451        offset = self.args.get("offset")
5452        if offset:
5453            columns = columns + [to_identifier("offset") if offset is True else offset]
5454        return columns
key = 'unnest'
class Floor(Func):
5457class Floor(Func):
5458    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5461class FromBase64(Func):
5462    pass
key = 'frombase64'
class ToBase64(Func):
5465class ToBase64(Func):
5466    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5470class FromISO8601Timestamp(Func):
5471    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5474class GapFill(Func):
5475    arg_types = {
5476        "this": True,
5477        "ts_column": True,
5478        "bucket_width": True,
5479        "partitioning_columns": False,
5480        "value_columns": False,
5481        "origin": False,
5482        "ignore_nulls": False,
5483    }
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):
5487class GenerateDateArray(Func):
5488    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5492class GenerateTimestampArray(Func):
5493    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5496class Greatest(Func):
5497    arg_types = {"this": True, "expressions": False}
5498    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5501class GroupConcat(AggFunc):
5502    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5505class Hex(Func):
5506    pass
key = 'hex'
class LowerHex(Hex):
5509class LowerHex(Hex):
5510    pass
key = 'lowerhex'
class Xor(Connector, Func):
5513class Xor(Connector, Func):
5514    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5517class If(Func):
5518    arg_types = {"this": True, "true": True, "false": False}
5519    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5522class Nullif(Func):
5523    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5526class Initcap(Func):
5527    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5530class IsNan(Func):
5531    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5534class IsInf(Func):
5535    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5539class JSON(Expression):
5540    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5543class JSONPath(Expression):
5544    arg_types = {"expressions": True, "escape": False}
5545
5546    @property
5547    def output_name(self) -> str:
5548        last_segment = self.expressions[-1].this
5549        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5546    @property
5547    def output_name(self) -> str:
5548        last_segment = self.expressions[-1].this
5549        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):
5552class JSONPathPart(Expression):
5553    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5556class JSONPathFilter(JSONPathPart):
5557    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5560class JSONPathKey(JSONPathPart):
5561    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5564class JSONPathRecursive(JSONPathPart):
5565    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5568class JSONPathRoot(JSONPathPart):
5569    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5572class JSONPathScript(JSONPathPart):
5573    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5576class JSONPathSlice(JSONPathPart):
5577    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5580class JSONPathSelector(JSONPathPart):
5581    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5584class JSONPathSubscript(JSONPathPart):
5585    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5588class JSONPathUnion(JSONPathPart):
5589    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5592class JSONPathWildcard(JSONPathPart):
5593    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5596class FormatJson(Expression):
5597    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5600class JSONKeyValue(Expression):
5601    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5604class JSONObject(Func):
5605    arg_types = {
5606        "expressions": False,
5607        "null_handling": False,
5608        "unique_keys": False,
5609        "return_type": False,
5610        "encoding": False,
5611    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5614class JSONObjectAgg(AggFunc):
5615    arg_types = {
5616        "expressions": False,
5617        "null_handling": False,
5618        "unique_keys": False,
5619        "return_type": False,
5620        "encoding": False,
5621    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5625class JSONArray(Func):
5626    arg_types = {
5627        "expressions": True,
5628        "null_handling": False,
5629        "return_type": False,
5630        "strict": False,
5631    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5635class JSONArrayAgg(Func):
5636    arg_types = {
5637        "this": True,
5638        "order": False,
5639        "null_handling": False,
5640        "return_type": False,
5641        "strict": False,
5642    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
5645class JSONExists(Func):
5646    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
arg_types = {'this': True, 'path': True, 'passing': False, 'on_condition': False}
key = 'jsonexists'
class JSONColumnDef(Expression):
5651class JSONColumnDef(Expression):
5652    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):
5655class JSONSchema(Expression):
5656    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
5660class JSONValue(Expression):
5661    arg_types = {
5662        "this": True,
5663        "path": True,
5664        "returning": False,
5665        "on_condition": False,
5666    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONTable(Func):
5670class JSONTable(Func):
5671    arg_types = {
5672        "this": True,
5673        "schema": True,
5674        "path": False,
5675        "error_handling": False,
5676        "empty_handling": False,
5677    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5681class ObjectInsert(Func):
5682    arg_types = {
5683        "this": True,
5684        "key": True,
5685        "value": True,
5686        "update_flag": False,
5687    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5690class OpenJSONColumnDef(Expression):
5691    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):
5694class OpenJSON(Func):
5695    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5698class JSONBContains(Binary, Func):
5699    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5702class JSONExtract(Binary, Func):
5703    arg_types = {
5704        "this": True,
5705        "expression": True,
5706        "only_json_types": False,
5707        "expressions": False,
5708        "variant_extract": False,
5709    }
5710    _sql_names = ["JSON_EXTRACT"]
5711    is_var_len_args = True
5712
5713    @property
5714    def output_name(self) -> str:
5715        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
5713    @property
5714    def output_name(self) -> str:
5715        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):
5718class JSONExtractScalar(Binary, Func):
5719    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5720    _sql_names = ["JSON_EXTRACT_SCALAR"]
5721    is_var_len_args = True
5722
5723    @property
5724    def output_name(self) -> str:
5725        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
5723    @property
5724    def output_name(self) -> str:
5725        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):
5728class JSONBExtract(Binary, Func):
5729    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5732class JSONBExtractScalar(Binary, Func):
5733    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5736class JSONFormat(Func):
5737    arg_types = {"this": False, "options": False}
5738    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5742class JSONArrayContains(Binary, Predicate, Func):
5743    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5746class ParseJSON(Func):
5747    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5748    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5749    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5750    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5753class Least(Func):
5754    arg_types = {"this": True, "expressions": False}
5755    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5758class Left(Func):
5759    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5766class Length(Func):
5767    arg_types = {"this": True, "binary": False}
5768    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5771class Levenshtein(Func):
5772    arg_types = {
5773        "this": True,
5774        "expression": False,
5775        "ins_cost": False,
5776        "del_cost": False,
5777        "sub_cost": False,
5778    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5781class Ln(Func):
5782    pass
key = 'ln'
class Log(Func):
5785class Log(Func):
5786    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5789class LogicalOr(AggFunc):
5790    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5793class LogicalAnd(AggFunc):
5794    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5797class Lower(Func):
5798    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5801class Map(Func):
5802    arg_types = {"keys": False, "values": False}
5803
5804    @property
5805    def keys(self) -> t.List[Expression]:
5806        keys = self.args.get("keys")
5807        return keys.expressions if keys else []
5808
5809    @property
5810    def values(self) -> t.List[Expression]:
5811        values = self.args.get("values")
5812        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5804    @property
5805    def keys(self) -> t.List[Expression]:
5806        keys = self.args.get("keys")
5807        return keys.expressions if keys else []
values: List[Expression]
5809    @property
5810    def values(self) -> t.List[Expression]:
5811        values = self.args.get("values")
5812        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5816class ToMap(Func):
5817    pass
key = 'tomap'
class MapFromEntries(Func):
5820class MapFromEntries(Func):
5821    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5825class ScopeResolution(Expression):
5826    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
5829class Stream(Expression):
5830    pass
key = 'stream'
class StarMap(Func):
5833class StarMap(Func):
5834    pass
key = 'starmap'
class VarMap(Func):
5837class VarMap(Func):
5838    arg_types = {"keys": True, "values": True}
5839    is_var_len_args = True
5840
5841    @property
5842    def keys(self) -> t.List[Expression]:
5843        return self.args["keys"].expressions
5844
5845    @property
5846    def values(self) -> t.List[Expression]:
5847        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5841    @property
5842    def keys(self) -> t.List[Expression]:
5843        return self.args["keys"].expressions
values: List[Expression]
5845    @property
5846    def values(self) -> t.List[Expression]:
5847        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5851class MatchAgainst(Func):
5852    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5855class Max(AggFunc):
5856    arg_types = {"this": True, "expressions": False}
5857    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5860class MD5(Func):
5861    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5865class MD5Digest(Func):
5866    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5869class Min(AggFunc):
5870    arg_types = {"this": True, "expressions": False}
5871    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5874class Month(Func):
5875    pass
key = 'month'
class AddMonths(Func):
5878class AddMonths(Func):
5879    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5882class Nvl2(Func):
5883    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
5886class Normalize(Func):
5887    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Predict(Func):
5891class Predict(Func):
5892    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5895class Pow(Binary, Func):
5896    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5899class PercentileCont(AggFunc):
5900    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5903class PercentileDisc(AggFunc):
5904    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5907class Quantile(AggFunc):
5908    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5911class ApproxQuantile(Quantile):
5912    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):
5915class Quarter(Func):
5916    pass
key = 'quarter'
class Rand(Func):
5921class Rand(Func):
5922    _sql_names = ["RAND", "RANDOM"]
5923    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5926class Randn(Func):
5927    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5930class RangeN(Func):
5931    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5934class ReadCSV(Func):
5935    _sql_names = ["READ_CSV"]
5936    is_var_len_args = True
5937    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5940class Reduce(Func):
5941    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):
5944class RegexpExtract(Func):
5945    arg_types = {
5946        "this": True,
5947        "expression": True,
5948        "position": False,
5949        "occurrence": False,
5950        "parameters": False,
5951        "group": False,
5952    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5955class RegexpReplace(Func):
5956    arg_types = {
5957        "this": True,
5958        "expression": True,
5959        "replacement": False,
5960        "position": False,
5961        "occurrence": False,
5962        "modifiers": False,
5963    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5966class RegexpLike(Binary, Func):
5967    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5970class RegexpILike(Binary, Func):
5971    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5976class RegexpSplit(Func):
5977    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5980class Repeat(Func):
5981    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5986class Round(Func):
5987    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5990class RowNumber(Func):
5991    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5994class SafeDivide(Func):
5995    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5998class SHA(Func):
5999    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6002class SHA2(Func):
6003    _sql_names = ["SHA2"]
6004    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6007class Sign(Func):
6008    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6011class SortArray(Func):
6012    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6015class Split(Func):
6016    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
6021class Substring(Func):
6022    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6025class StandardHash(Func):
6026    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6029class StartsWith(Func):
6030    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6031    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6034class StrPosition(Func):
6035    arg_types = {
6036        "this": True,
6037        "substr": True,
6038        "position": False,
6039        "instance": False,
6040    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
6043class StrToDate(Func):
6044    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6047class StrToTime(Func):
6048    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):
6053class StrToUnix(Func):
6054    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6059class StrToMap(Func):
6060    arg_types = {
6061        "this": True,
6062        "pair_delim": False,
6063        "key_value_delim": False,
6064        "duplicate_resolution_callback": False,
6065    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6068class NumberToStr(Func):
6069    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6072class FromBase(Func):
6073    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6076class Struct(Func):
6077    arg_types = {"expressions": False}
6078    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6081class StructExtract(Func):
6082    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6087class Stuff(Func):
6088    _sql_names = ["STUFF", "INSERT"]
6089    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):
6092class Sum(AggFunc):
6093    pass
key = 'sum'
class Sqrt(Func):
6096class Sqrt(Func):
6097    pass
key = 'sqrt'
class Stddev(AggFunc):
6100class Stddev(AggFunc):
6101    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6104class StddevPop(AggFunc):
6105    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6108class StddevSamp(AggFunc):
6109    pass
key = 'stddevsamp'
class Time(Func):
6113class Time(Func):
6114    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6117class TimeToStr(Func):
6118    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):
6121class TimeToTimeStr(Func):
6122    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6125class TimeToUnix(Func):
6126    pass
key = 'timetounix'
class TimeStrToDate(Func):
6129class TimeStrToDate(Func):
6130    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6133class TimeStrToTime(Func):
6134    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6137class TimeStrToUnix(Func):
6138    pass
key = 'timestrtounix'
class Trim(Func):
6141class Trim(Func):
6142    arg_types = {
6143        "this": True,
6144        "expression": False,
6145        "position": False,
6146        "collation": False,
6147    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6150class TsOrDsAdd(Func, TimeUnit):
6151    # return_type is used to correctly cast the arguments of this expression when transpiling it
6152    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6153
6154    @property
6155    def return_type(self) -> DataType:
6156        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
6154    @property
6155    def return_type(self) -> DataType:
6156        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6159class TsOrDsDiff(Func, TimeUnit):
6160    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6163class TsOrDsToDateStr(Func):
6164    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6167class TsOrDsToDate(Func):
6168    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6171class TsOrDsToTime(Func):
6172    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6175class TsOrDsToTimestamp(Func):
6176    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6179class TsOrDiToDi(Func):
6180    pass
key = 'tsorditodi'
class Unhex(Func):
6183class Unhex(Func):
6184    pass
key = 'unhex'
class UnixDate(Func):
6188class UnixDate(Func):
6189    pass
key = 'unixdate'
class UnixToStr(Func):
6192class UnixToStr(Func):
6193    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6198class UnixToTime(Func):
6199    arg_types = {
6200        "this": True,
6201        "scale": False,
6202        "zone": False,
6203        "hours": False,
6204        "minutes": False,
6205        "format": False,
6206    }
6207
6208    SECONDS = Literal.number(0)
6209    DECIS = Literal.number(1)
6210    CENTIS = Literal.number(2)
6211    MILLIS = Literal.number(3)
6212    DECIMILLIS = Literal.number(4)
6213    CENTIMILLIS = Literal.number(5)
6214    MICROS = Literal.number(6)
6215    DECIMICROS = Literal.number(7)
6216    CENTIMICROS = Literal.number(8)
6217    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):
6220class UnixToTimeStr(Func):
6221    pass
key = 'unixtotimestr'
class UnpackColumns(Func):
6224class UnpackColumns(Func):
6225    pass
key = 'unpackcolumns'
class Uuid(Func):
6228class Uuid(Func):
6229    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6230
6231    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6234class TimestampFromParts(Func):
6235    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6236    arg_types = {
6237        "year": True,
6238        "month": True,
6239        "day": True,
6240        "hour": True,
6241        "min": True,
6242        "sec": True,
6243        "nano": False,
6244        "zone": False,
6245        "milli": False,
6246    }
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):
6249class Upper(Func):
6250    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6253class Corr(Binary, AggFunc):
6254    pass
key = 'corr'
class Variance(AggFunc):
6257class Variance(AggFunc):
6258    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6261class VariancePop(AggFunc):
6262    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6265class CovarSamp(Binary, AggFunc):
6266    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6269class CovarPop(Binary, AggFunc):
6270    pass
key = 'covarpop'
class Week(Func):
6273class Week(Func):
6274    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6277class XMLTable(Func):
6278    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):
6281class Year(Func):
6282    pass
key = 'year'
class Use(Expression):
6285class Use(Expression):
6286    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(DML):
6289class Merge(DML):
6290    arg_types = {
6291        "this": True,
6292        "using": True,
6293        "on": True,
6294        "expressions": True,
6295        "with": False,
6296        "returning": False,
6297    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False, 'returning': False}
key = 'merge'
class When(Func):
6300class When(Func):
6301    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):
6306class NextValueFor(Func):
6307    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6312class Semicolon(Expression):
6313    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 'DayOfWeekIso'>, <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 'Inline'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExists'>, <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 'Normalize'>, <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 'UnpackColumns'>, <class 'Upper'>, <class 'Uuid'>, <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'>, 'DAYOFWEEK_ISO': <class 'DayOfWeekIso'>, 'ISODOW': <class 'DayOfWeekIso'>, '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'>, 'INLINE': <class 'Inline'>, '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'>, 'J_S_O_N_EXISTS': <class 'JSONExists'>, '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'>, 'NORMALIZE': <class 'Normalize'>, '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'>, 'UNPACK_COLUMNS': <class 'UnpackColumns'>, 'UPPER': <class 'Upper'>, 'UCASE': <class 'Upper'>, 'UUID': <class 'Uuid'>, 'GEN_RANDOM_UUID': <class 'Uuid'>, 'GENERATE_UUID': <class 'Uuid'>, 'UUID_STRING': <class 'Uuid'>, '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:
6353def maybe_parse(
6354    sql_or_expression: ExpOrStr,
6355    *,
6356    into: t.Optional[IntoType] = None,
6357    dialect: DialectType = None,
6358    prefix: t.Optional[str] = None,
6359    copy: bool = False,
6360    **opts,
6361) -> Expression:
6362    """Gracefully handle a possible string or expression.
6363
6364    Example:
6365        >>> maybe_parse("1")
6366        Literal(this=1, is_string=False)
6367        >>> maybe_parse(to_identifier("x"))
6368        Identifier(this=x, quoted=False)
6369
6370    Args:
6371        sql_or_expression: the SQL code string or an expression
6372        into: the SQLGlot Expression to parse into
6373        dialect: the dialect used to parse the input expressions (in the case that an
6374            input expression is a SQL string).
6375        prefix: a string to prefix the sql with before it gets parsed
6376            (automatically includes a space)
6377        copy: whether to copy the expression.
6378        **opts: other options to use to parse the input expressions (again, in the case
6379            that an input expression is a SQL string).
6380
6381    Returns:
6382        Expression: the parsed or given expression.
6383    """
6384    if isinstance(sql_or_expression, Expression):
6385        if copy:
6386            return sql_or_expression.copy()
6387        return sql_or_expression
6388
6389    if sql_or_expression is None:
6390        raise ParseError("SQL cannot be None")
6391
6392    import sqlglot
6393
6394    sql = str(sql_or_expression)
6395    if prefix:
6396        sql = f"{prefix} {sql}"
6397
6398    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):
6409def maybe_copy(instance, copy=True):
6410    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:
6631def union(
6632    left: ExpOrStr,
6633    right: ExpOrStr,
6634    distinct: bool = True,
6635    dialect: DialectType = None,
6636    copy: bool = True,
6637    **opts,
6638) -> Union:
6639    """
6640    Initializes a syntax tree from one UNION expression.
6641
6642    Example:
6643        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6644        'SELECT * FROM foo UNION SELECT * FROM bla'
6645
6646    Args:
6647        left: the SQL code string corresponding to the left-hand side.
6648            If an `Expression` instance is passed, it will be used as-is.
6649        right: the SQL code string corresponding to the right-hand side.
6650            If an `Expression` instance is passed, it will be used as-is.
6651        distinct: set the DISTINCT flag if and only if this is true.
6652        dialect: the dialect used to parse the input expression.
6653        copy: whether to copy the expression.
6654        opts: other options to use to parse the input expressions.
6655
6656    Returns:
6657        The new Union instance.
6658    """
6659    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6660    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6661
6662    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:
6665def intersect(
6666    left: ExpOrStr,
6667    right: ExpOrStr,
6668    distinct: bool = True,
6669    dialect: DialectType = None,
6670    copy: bool = True,
6671    **opts,
6672) -> Intersect:
6673    """
6674    Initializes a syntax tree from one INTERSECT expression.
6675
6676    Example:
6677        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6678        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6679
6680    Args:
6681        left: the SQL code string corresponding to the left-hand side.
6682            If an `Expression` instance is passed, it will be used as-is.
6683        right: the SQL code string corresponding to the right-hand side.
6684            If an `Expression` instance is passed, it will be used as-is.
6685        distinct: set the DISTINCT flag if and only if this is true.
6686        dialect: the dialect used to parse the input expression.
6687        copy: whether to copy the expression.
6688        opts: other options to use to parse the input expressions.
6689
6690    Returns:
6691        The new Intersect instance.
6692    """
6693    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6694    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6695
6696    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:
6699def except_(
6700    left: ExpOrStr,
6701    right: ExpOrStr,
6702    distinct: bool = True,
6703    dialect: DialectType = None,
6704    copy: bool = True,
6705    **opts,
6706) -> Except:
6707    """
6708    Initializes a syntax tree from one EXCEPT expression.
6709
6710    Example:
6711        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6712        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6713
6714    Args:
6715        left: the SQL code string corresponding to the left-hand side.
6716            If an `Expression` instance is passed, it will be used as-is.
6717        right: the SQL code string corresponding to the right-hand side.
6718            If an `Expression` instance is passed, it will be used as-is.
6719        distinct: set the DISTINCT flag if and only if this is true.
6720        dialect: the dialect used to parse the input expression.
6721        copy: whether to copy the expression.
6722        opts: other options to use to parse the input expressions.
6723
6724    Returns:
6725        The new Except instance.
6726    """
6727    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6728    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6729
6730    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:
6733def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6734    """
6735    Initializes a syntax tree from one or multiple SELECT expressions.
6736
6737    Example:
6738        >>> select("col1", "col2").from_("tbl").sql()
6739        'SELECT col1, col2 FROM tbl'
6740
6741    Args:
6742        *expressions: the SQL code string to parse as the expressions of a
6743            SELECT statement. If an Expression instance is passed, this is used as-is.
6744        dialect: the dialect used to parse the input expressions (in the case that an
6745            input expression is a SQL string).
6746        **opts: other options to use to parse the input expressions (again, in the case
6747            that an input expression is a SQL string).
6748
6749    Returns:
6750        Select: the syntax tree for the SELECT statement.
6751    """
6752    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:
6755def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6756    """
6757    Initializes a syntax tree from a FROM expression.
6758
6759    Example:
6760        >>> from_("tbl").select("col1", "col2").sql()
6761        'SELECT col1, col2 FROM tbl'
6762
6763    Args:
6764        *expression: the SQL code string to parse as the FROM expressions of a
6765            SELECT statement. If an Expression instance is passed, this is used as-is.
6766        dialect: the dialect used to parse the input expression (in the case that the
6767            input expression is a SQL string).
6768        **opts: other options to use to parse the input expressions (again, in the case
6769            that the input expression is a SQL string).
6770
6771    Returns:
6772        Select: the syntax tree for the SELECT statement.
6773    """
6774    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:
6777def update(
6778    table: str | Table,
6779    properties: dict,
6780    where: t.Optional[ExpOrStr] = None,
6781    from_: t.Optional[ExpOrStr] = None,
6782    dialect: DialectType = None,
6783    **opts,
6784) -> Update:
6785    """
6786    Creates an update statement.
6787
6788    Example:
6789        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6790        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6791
6792    Args:
6793        *properties: dictionary of properties to set which are
6794            auto converted to sql objects eg None -> NULL
6795        where: sql conditional parsed into a WHERE statement
6796        from_: sql statement parsed into a FROM statement
6797        dialect: the dialect used to parse the input expressions.
6798        **opts: other options to use to parse the input expressions.
6799
6800    Returns:
6801        Update: the syntax tree for the UPDATE statement.
6802    """
6803    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6804    update_expr.set(
6805        "expressions",
6806        [
6807            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6808            for k, v in properties.items()
6809        ],
6810    )
6811    if from_:
6812        update_expr.set(
6813            "from",
6814            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6815        )
6816    if isinstance(where, Condition):
6817        where = Where(this=where)
6818    if where:
6819        update_expr.set(
6820            "where",
6821            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6822        )
6823    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:
6826def delete(
6827    table: ExpOrStr,
6828    where: t.Optional[ExpOrStr] = None,
6829    returning: t.Optional[ExpOrStr] = None,
6830    dialect: DialectType = None,
6831    **opts,
6832) -> Delete:
6833    """
6834    Builds a delete statement.
6835
6836    Example:
6837        >>> delete("my_table", where="id > 1").sql()
6838        'DELETE FROM my_table WHERE id > 1'
6839
6840    Args:
6841        where: sql conditional parsed into a WHERE statement
6842        returning: sql conditional parsed into a RETURNING statement
6843        dialect: the dialect used to parse the input expressions.
6844        **opts: other options to use to parse the input expressions.
6845
6846    Returns:
6847        Delete: the syntax tree for the DELETE statement.
6848    """
6849    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6850    if where:
6851        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6852    if returning:
6853        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6854    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:
6857def insert(
6858    expression: ExpOrStr,
6859    into: ExpOrStr,
6860    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6861    overwrite: t.Optional[bool] = None,
6862    returning: t.Optional[ExpOrStr] = None,
6863    dialect: DialectType = None,
6864    copy: bool = True,
6865    **opts,
6866) -> Insert:
6867    """
6868    Builds an INSERT statement.
6869
6870    Example:
6871        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6872        'INSERT INTO tbl VALUES (1, 2, 3)'
6873
6874    Args:
6875        expression: the sql string or expression of the INSERT statement
6876        into: the tbl to insert data to.
6877        columns: optionally the table's column names.
6878        overwrite: whether to INSERT OVERWRITE or not.
6879        returning: sql conditional parsed into a RETURNING statement
6880        dialect: the dialect used to parse the input expressions.
6881        copy: whether to copy the expression.
6882        **opts: other options to use to parse the input expressions.
6883
6884    Returns:
6885        Insert: the syntax tree for the INSERT statement.
6886    """
6887    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6888    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6889
6890    if columns:
6891        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6892
6893    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6894
6895    if returning:
6896        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
6897
6898    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 merge( *when_exprs: Union[str, Expression], into: Union[str, Expression], using: Union[str, Expression], on: Union[str, Expression], returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
6901def merge(
6902    *when_exprs: ExpOrStr,
6903    into: ExpOrStr,
6904    using: ExpOrStr,
6905    on: ExpOrStr,
6906    returning: t.Optional[ExpOrStr] = None,
6907    dialect: DialectType = None,
6908    copy: bool = True,
6909    **opts,
6910) -> Merge:
6911    """
6912    Builds a MERGE statement.
6913
6914    Example:
6915        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
6916        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
6917        ...       into="my_table",
6918        ...       using="source_table",
6919        ...       on="my_table.id = source_table.id").sql()
6920        'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
6921
6922    Args:
6923        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
6924        into: The target table to merge data into.
6925        using: The source table to merge data from.
6926        on: The join condition for the merge.
6927        returning: The columns to return from the merge.
6928        dialect: The dialect used to parse the input expressions.
6929        copy: Whether to copy the expression.
6930        **opts: Other options to use to parse the input expressions.
6931
6932    Returns:
6933        Merge: The syntax tree for the MERGE statement.
6934    """
6935    merge = Merge(
6936        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
6937        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
6938        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
6939        expressions=[
6940            maybe_parse(when_expr, dialect=dialect, copy=copy, into=When, **opts)
6941            for when_expr in when_exprs
6942        ],
6943    )
6944    if returning:
6945        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
6946
6947    return merge

Builds a MERGE statement.

Example:
>>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
...       into="my_table",
...       using="source_table",
...       on="my_table.id = source_table.id").sql()
'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
Arguments:
  • *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
  • into: The target table to merge data into.
  • using: The source table to merge data from.
  • on: The join condition for the merge.
  • returning: The columns to return from the merge.
  • 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:

Merge: The syntax tree for the MERGE 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:
6950def condition(
6951    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6952) -> Condition:
6953    """
6954    Initialize a logical condition expression.
6955
6956    Example:
6957        >>> condition("x=1").sql()
6958        'x = 1'
6959
6960        This is helpful for composing larger logical syntax trees:
6961        >>> where = condition("x=1")
6962        >>> where = where.and_("y=1")
6963        >>> Select().from_("tbl").select("*").where(where).sql()
6964        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6965
6966    Args:
6967        *expression: the SQL code string to parse.
6968            If an Expression instance is passed, this is used as-is.
6969        dialect: the dialect used to parse the input expression (in the case that the
6970            input expression is a SQL string).
6971        copy: Whether to copy `expression` (only applies to expressions).
6972        **opts: other options to use to parse the input expressions (again, in the case
6973            that the input expression is a SQL string).
6974
6975    Returns:
6976        The new Condition instance
6977    """
6978    return maybe_parse(
6979        expression,
6980        into=Condition,
6981        dialect=dialect,
6982        copy=copy,
6983        **opts,
6984    )

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:
6987def and_(
6988    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6989) -> Condition:
6990    """
6991    Combine multiple conditions with an AND logical operator.
6992
6993    Example:
6994        >>> and_("x=1", and_("y=1", "z=1")).sql()
6995        'x = 1 AND (y = 1 AND z = 1)'
6996
6997    Args:
6998        *expressions: the SQL code strings to parse.
6999            If an Expression instance is passed, this is used as-is.
7000        dialect: the dialect used to parse the input expression.
7001        copy: whether to copy `expressions` (only applies to Expressions).
7002        **opts: other options to use to parse the input expressions.
7003
7004    Returns:
7005        The new condition
7006    """
7007    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:
7010def or_(
7011    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7012) -> Condition:
7013    """
7014    Combine multiple conditions with an OR logical operator.
7015
7016    Example:
7017        >>> or_("x=1", or_("y=1", "z=1")).sql()
7018        'x = 1 OR (y = 1 OR z = 1)'
7019
7020    Args:
7021        *expressions: the SQL code strings to parse.
7022            If an Expression instance is passed, this is used as-is.
7023        dialect: the dialect used to parse the input expression.
7024        copy: whether to copy `expressions` (only applies to Expressions).
7025        **opts: other options to use to parse the input expressions.
7026
7027    Returns:
7028        The new condition
7029    """
7030    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:
7033def xor(
7034    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7035) -> Condition:
7036    """
7037    Combine multiple conditions with an XOR logical operator.
7038
7039    Example:
7040        >>> xor("x=1", xor("y=1", "z=1")).sql()
7041        'x = 1 XOR (y = 1 XOR z = 1)'
7042
7043    Args:
7044        *expressions: the SQL code strings to parse.
7045            If an Expression instance is passed, this is used as-is.
7046        dialect: the dialect used to parse the input expression.
7047        copy: whether to copy `expressions` (only applies to Expressions).
7048        **opts: other options to use to parse the input expressions.
7049
7050    Returns:
7051        The new condition
7052    """
7053    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:
7056def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7057    """
7058    Wrap a condition with a NOT operator.
7059
7060    Example:
7061        >>> not_("this_suit='black'").sql()
7062        "NOT this_suit = 'black'"
7063
7064    Args:
7065        expression: the SQL code string to parse.
7066            If an Expression instance is passed, this is used as-is.
7067        dialect: the dialect used to parse the input expression.
7068        copy: whether to copy the expression or not.
7069        **opts: other options to use to parse the input expressions.
7070
7071    Returns:
7072        The new condition.
7073    """
7074    this = condition(
7075        expression,
7076        dialect=dialect,
7077        copy=copy,
7078        **opts,
7079    )
7080    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:
7083def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7084    """
7085    Wrap an expression in parentheses.
7086
7087    Example:
7088        >>> paren("5 + 3").sql()
7089        '(5 + 3)'
7090
7091    Args:
7092        expression: the SQL code string to parse.
7093            If an Expression instance is passed, this is used as-is.
7094        copy: whether to copy the expression or not.
7095
7096    Returns:
7097        The wrapped expression.
7098    """
7099    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):
7115def to_identifier(name, quoted=None, copy=True):
7116    """Builds an identifier.
7117
7118    Args:
7119        name: The name to turn into an identifier.
7120        quoted: Whether to force quote the identifier.
7121        copy: Whether to copy name if it's an Identifier.
7122
7123    Returns:
7124        The identifier ast node.
7125    """
7126
7127    if name is None:
7128        return None
7129
7130    if isinstance(name, Identifier):
7131        identifier = maybe_copy(name, copy)
7132    elif isinstance(name, str):
7133        identifier = Identifier(
7134            this=name,
7135            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7136        )
7137    else:
7138        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7139    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:
7142def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7143    """
7144    Parses a given string into an identifier.
7145
7146    Args:
7147        name: The name to parse into an identifier.
7148        dialect: The dialect to parse against.
7149
7150    Returns:
7151        The identifier ast node.
7152    """
7153    try:
7154        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7155    except (ParseError, TokenError):
7156        expression = to_identifier(name)
7157
7158    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:
7164def to_interval(interval: str | Literal) -> Interval:
7165    """Builds an interval expression from a string like '1 day' or '5 months'."""
7166    if isinstance(interval, Literal):
7167        if not interval.is_string:
7168            raise ValueError("Invalid interval string.")
7169
7170        interval = interval.this
7171
7172    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
7173
7174    if not interval_parts:
7175        raise ValueError("Invalid interval string.")
7176
7177    return Interval(
7178        this=Literal.string(interval_parts.group(1)),
7179        unit=Var(this=interval_parts.group(2).upper()),
7180    )

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:
7183def to_table(
7184    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7185) -> Table:
7186    """
7187    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7188    If a table is passed in then that table is returned.
7189
7190    Args:
7191        sql_path: a `[catalog].[schema].[table]` string.
7192        dialect: the source dialect according to which the table name will be parsed.
7193        copy: Whether to copy a table if it is passed in.
7194        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7195
7196    Returns:
7197        A table expression.
7198    """
7199    if isinstance(sql_path, Table):
7200        return maybe_copy(sql_path, copy=copy)
7201
7202    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7203
7204    for k, v in kwargs.items():
7205        table.set(k, v)
7206
7207    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:
7210def to_column(
7211    sql_path: str | Column,
7212    quoted: t.Optional[bool] = None,
7213    dialect: DialectType = None,
7214    copy: bool = True,
7215    **kwargs,
7216) -> Column:
7217    """
7218    Create a column from a `[table].[column]` sql path. Table is optional.
7219    If a column is passed in then that column is returned.
7220
7221    Args:
7222        sql_path: a `[table].[column]` string.
7223        quoted: Whether or not to force quote identifiers.
7224        dialect: the source dialect according to which the column name will be parsed.
7225        copy: Whether to copy a column if it is passed in.
7226        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7227
7228    Returns:
7229        A column expression.
7230    """
7231    if isinstance(sql_path, Column):
7232        return maybe_copy(sql_path, copy=copy)
7233
7234    try:
7235        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7236    except ParseError:
7237        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7238
7239    for k, v in kwargs.items():
7240        col.set(k, v)
7241
7242    if quoted:
7243        for i in col.find_all(Identifier):
7244            i.set("quoted", True)
7245
7246    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):
7249def alias_(
7250    expression: ExpOrStr,
7251    alias: t.Optional[str | Identifier],
7252    table: bool | t.Sequence[str | Identifier] = False,
7253    quoted: t.Optional[bool] = None,
7254    dialect: DialectType = None,
7255    copy: bool = True,
7256    **opts,
7257):
7258    """Create an Alias expression.
7259
7260    Example:
7261        >>> alias_('foo', 'bar').sql()
7262        'foo AS bar'
7263
7264        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7265        '(SELECT 1, 2) AS bar(a, b)'
7266
7267    Args:
7268        expression: the SQL code strings to parse.
7269            If an Expression instance is passed, this is used as-is.
7270        alias: the alias name to use. If the name has
7271            special characters it is quoted.
7272        table: Whether to create a table alias, can also be a list of columns.
7273        quoted: whether to quote the alias
7274        dialect: the dialect used to parse the input expression.
7275        copy: Whether to copy the expression.
7276        **opts: other options to use to parse the input expressions.
7277
7278    Returns:
7279        Alias: the aliased expression
7280    """
7281    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7282    alias = to_identifier(alias, quoted=quoted)
7283
7284    if table:
7285        table_alias = TableAlias(this=alias)
7286        exp.set("alias", table_alias)
7287
7288        if not isinstance(table, bool):
7289            for column in table:
7290                table_alias.append("columns", to_identifier(column, quoted=quoted))
7291
7292        return exp
7293
7294    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7295    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7296    # for the complete Window expression.
7297    #
7298    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7299
7300    if "alias" in exp.arg_types and not isinstance(exp, Window):
7301        exp.set("alias", alias)
7302        return exp
7303    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:
7306def subquery(
7307    expression: ExpOrStr,
7308    alias: t.Optional[Identifier | str] = None,
7309    dialect: DialectType = None,
7310    **opts,
7311) -> Select:
7312    """
7313    Build a subquery expression that's selected from.
7314
7315    Example:
7316        >>> subquery('select x from tbl', 'bar').select('x').sql()
7317        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7318
7319    Args:
7320        expression: the SQL code strings to parse.
7321            If an Expression instance is passed, this is used as-is.
7322        alias: the alias name to use.
7323        dialect: the dialect used to parse the input expression.
7324        **opts: other options to use to parse the input expressions.
7325
7326    Returns:
7327        A new Select instance with the subquery expression included.
7328    """
7329
7330    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7331    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):
7362def column(
7363    col,
7364    table=None,
7365    db=None,
7366    catalog=None,
7367    *,
7368    fields=None,
7369    quoted=None,
7370    copy=True,
7371):
7372    """
7373    Build a Column.
7374
7375    Args:
7376        col: Column name.
7377        table: Table name.
7378        db: Database name.
7379        catalog: Catalog name.
7380        fields: Additional fields using dots.
7381        quoted: Whether to force quotes on the column's identifiers.
7382        copy: Whether to copy identifiers if passed in.
7383
7384    Returns:
7385        The new Column instance.
7386    """
7387    this = Column(
7388        this=to_identifier(col, quoted=quoted, copy=copy),
7389        table=to_identifier(table, quoted=quoted, copy=copy),
7390        db=to_identifier(db, quoted=quoted, copy=copy),
7391        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7392    )
7393
7394    if fields:
7395        this = Dot.build(
7396            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7397        )
7398    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:
7401def cast(
7402    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7403) -> Cast:
7404    """Cast an expression to a data type.
7405
7406    Example:
7407        >>> cast('x + 1', 'int').sql()
7408        'CAST(x + 1 AS INT)'
7409
7410    Args:
7411        expression: The expression to cast.
7412        to: The datatype to cast to.
7413        copy: Whether to copy the supplied expressions.
7414        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7415            - The expression to be cast is already a exp.Cast expression
7416            - The existing cast is to a type that is logically equivalent to new type
7417
7418            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7419            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7420            and instead just return the original expression `CAST(x as DATETIME)`.
7421
7422            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7423            mapping is applied in the target dialect generator.
7424
7425    Returns:
7426        The new Cast instance.
7427    """
7428    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
7429    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
7430
7431    # dont re-cast if the expression is already a cast to the correct type
7432    if isinstance(expr, Cast):
7433        from sqlglot.dialects.dialect import Dialect
7434
7435        target_dialect = Dialect.get_or_raise(dialect)
7436        type_mapping = target_dialect.generator_class.TYPE_MAPPING
7437
7438        existing_cast_type: DataType.Type = expr.to.this
7439        new_cast_type: DataType.Type = data_type.this
7440        types_are_equivalent = type_mapping.get(
7441            existing_cast_type, existing_cast_type
7442        ) == type_mapping.get(new_cast_type, new_cast_type)
7443        if expr.is_type(data_type) or types_are_equivalent:
7444            return expr
7445
7446    expr = Cast(this=expr, to=data_type)
7447    expr.type = data_type
7448
7449    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:
7452def table_(
7453    table: Identifier | str,
7454    db: t.Optional[Identifier | str] = None,
7455    catalog: t.Optional[Identifier | str] = None,
7456    quoted: t.Optional[bool] = None,
7457    alias: t.Optional[Identifier | str] = None,
7458) -> Table:
7459    """Build a Table.
7460
7461    Args:
7462        table: Table name.
7463        db: Database name.
7464        catalog: Catalog name.
7465        quote: Whether to force quotes on the table's identifiers.
7466        alias: Table's alias.
7467
7468    Returns:
7469        The new Table instance.
7470    """
7471    return Table(
7472        this=to_identifier(table, quoted=quoted) if table else None,
7473        db=to_identifier(db, quoted=quoted) if db else None,
7474        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7475        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7476    )

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:
7479def values(
7480    values: t.Iterable[t.Tuple[t.Any, ...]],
7481    alias: t.Optional[str] = None,
7482    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7483) -> Values:
7484    """Build VALUES statement.
7485
7486    Example:
7487        >>> values([(1, '2')]).sql()
7488        "VALUES (1, '2')"
7489
7490    Args:
7491        values: values statements that will be converted to SQL
7492        alias: optional alias
7493        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7494         If either are provided then an alias is also required.
7495
7496    Returns:
7497        Values: the Values expression object
7498    """
7499    if columns and not alias:
7500        raise ValueError("Alias is required when providing columns")
7501
7502    return Values(
7503        expressions=[convert(tup) for tup in values],
7504        alias=(
7505            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7506            if columns
7507            else (TableAlias(this=to_identifier(alias)) if alias else None)
7508        ),
7509    )

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:
7512def var(name: t.Optional[ExpOrStr]) -> Var:
7513    """Build a SQL variable.
7514
7515    Example:
7516        >>> repr(var('x'))
7517        'Var(this=x)'
7518
7519        >>> repr(var(column('x', table='y')))
7520        'Var(this=x)'
7521
7522    Args:
7523        name: The name of the var or an expression who's name will become the var.
7524
7525    Returns:
7526        The new variable node.
7527    """
7528    if not name:
7529        raise ValueError("Cannot convert empty name into var.")
7530
7531    if isinstance(name, Expression):
7532        name = name.name
7533    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:
7536def rename_table(
7537    old_name: str | Table,
7538    new_name: str | Table,
7539    dialect: DialectType = None,
7540) -> Alter:
7541    """Build ALTER TABLE... RENAME... expression
7542
7543    Args:
7544        old_name: The old name of the table
7545        new_name: The new name of the table
7546        dialect: The dialect to parse the table.
7547
7548    Returns:
7549        Alter table expression
7550    """
7551    old_table = to_table(old_name, dialect=dialect)
7552    new_table = to_table(new_name, dialect=dialect)
7553    return Alter(
7554        this=old_table,
7555        kind="TABLE",
7556        actions=[
7557            RenameTable(this=new_table),
7558        ],
7559    )

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:
7562def rename_column(
7563    table_name: str | Table,
7564    old_column_name: str | Column,
7565    new_column_name: str | Column,
7566    exists: t.Optional[bool] = None,
7567    dialect: DialectType = None,
7568) -> Alter:
7569    """Build ALTER TABLE... RENAME COLUMN... expression
7570
7571    Args:
7572        table_name: Name of the table
7573        old_column: The old name of the column
7574        new_column: The new name of the column
7575        exists: Whether to add the `IF EXISTS` clause
7576        dialect: The dialect to parse the table/column.
7577
7578    Returns:
7579        Alter table expression
7580    """
7581    table = to_table(table_name, dialect=dialect)
7582    old_column = to_column(old_column_name, dialect=dialect)
7583    new_column = to_column(new_column_name, dialect=dialect)
7584    return Alter(
7585        this=table,
7586        kind="TABLE",
7587        actions=[
7588            RenameColumn(this=old_column, to=new_column, exists=exists),
7589        ],
7590    )

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:
7593def convert(value: t.Any, copy: bool = False) -> Expression:
7594    """Convert a python value into an expression object.
7595
7596    Raises an error if a conversion is not possible.
7597
7598    Args:
7599        value: A python object.
7600        copy: Whether to copy `value` (only applies to Expressions and collections).
7601
7602    Returns:
7603        The equivalent expression object.
7604    """
7605    if isinstance(value, Expression):
7606        return maybe_copy(value, copy)
7607    if isinstance(value, str):
7608        return Literal.string(value)
7609    if isinstance(value, bool):
7610        return Boolean(this=value)
7611    if value is None or (isinstance(value, float) and math.isnan(value)):
7612        return null()
7613    if isinstance(value, numbers.Number):
7614        return Literal.number(value)
7615    if isinstance(value, bytes):
7616        return HexString(this=value.hex())
7617    if isinstance(value, datetime.datetime):
7618        datetime_literal = Literal.string(value.isoformat(sep=" "))
7619
7620        tz = None
7621        if value.tzinfo:
7622            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
7623            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
7624            tz = Literal.string(str(value.tzinfo))
7625
7626        return TimeStrToTime(this=datetime_literal, zone=tz)
7627    if isinstance(value, datetime.date):
7628        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7629        return DateStrToDate(this=date_literal)
7630    if isinstance(value, tuple):
7631        if hasattr(value, "_fields"):
7632            return Struct(
7633                expressions=[
7634                    PropertyEQ(
7635                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7636                    )
7637                    for k in value._fields
7638                ]
7639            )
7640        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7641    if isinstance(value, list):
7642        return Array(expressions=[convert(v, copy=copy) for v in value])
7643    if isinstance(value, dict):
7644        return Map(
7645            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7646            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7647        )
7648    if hasattr(value, "__dict__"):
7649        return Struct(
7650            expressions=[
7651                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7652                for k, v in value.__dict__.items()
7653            ]
7654        )
7655    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:
7658def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7659    """
7660    Replace children of an expression with the result of a lambda fun(child) -> exp.
7661    """
7662    for k, v in tuple(expression.args.items()):
7663        is_list_arg = type(v) is list
7664
7665        child_nodes = v if is_list_arg else [v]
7666        new_child_nodes = []
7667
7668        for cn in child_nodes:
7669            if isinstance(cn, Expression):
7670                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7671                    new_child_nodes.append(child_node)
7672            else:
7673                new_child_nodes.append(cn)
7674
7675        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:
7678def replace_tree(
7679    expression: Expression,
7680    fun: t.Callable,
7681    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7682) -> Expression:
7683    """
7684    Replace an entire tree with the result of function calls on each node.
7685
7686    This will be traversed in reverse dfs, so leaves first.
7687    If new nodes are created as a result of function calls, they will also be traversed.
7688    """
7689    stack = list(expression.dfs(prune=prune))
7690
7691    while stack:
7692        node = stack.pop()
7693        new_node = fun(node)
7694
7695        if new_node is not node:
7696            node.replace(new_node)
7697
7698            if isinstance(new_node, Expression):
7699                stack.append(new_node)
7700
7701    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]:
7704def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7705    """
7706    Return all table names referenced through columns in an expression.
7707
7708    Example:
7709        >>> import sqlglot
7710        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7711        ['a', 'c']
7712
7713    Args:
7714        expression: expression to find table names.
7715        exclude: a table name to exclude
7716
7717    Returns:
7718        A list of unique names.
7719    """
7720    return {
7721        table
7722        for table in (column.table for column in expression.find_all(Column))
7723        if table and table != exclude
7724    }

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:
7727def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7728    """Get the full name of a table as a string.
7729
7730    Args:
7731        table: Table expression node or string.
7732        dialect: The dialect to generate the table name for.
7733        identify: Determines when an identifier should be quoted. Possible values are:
7734            False (default): Never quote, except in cases where it's mandatory by the dialect.
7735            True: Always quote.
7736
7737    Examples:
7738        >>> from sqlglot import exp, parse_one
7739        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7740        'a.b.c'
7741
7742    Returns:
7743        The table name.
7744    """
7745
7746    table = maybe_parse(table, into=Table, dialect=dialect)
7747
7748    if not table:
7749        raise ValueError(f"Cannot parse {table}")
7750
7751    return ".".join(
7752        (
7753            part.sql(dialect=dialect, identify=True, copy=False)
7754            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7755            else part.name
7756        )
7757        for part in table.parts
7758    )

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:
7761def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7762    """Returns a case normalized table name without quotes.
7763
7764    Args:
7765        table: the table to normalize
7766        dialect: the dialect to use for normalization rules
7767        copy: whether to copy the expression.
7768
7769    Examples:
7770        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7771        'A-B.c'
7772    """
7773    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7774
7775    return ".".join(
7776        p.name
7777        for p in normalize_identifiers(
7778            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7779        ).parts
7780    )

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:
7783def replace_tables(
7784    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7785) -> E:
7786    """Replace all tables in expression according to the mapping.
7787
7788    Args:
7789        expression: expression node to be transformed and replaced.
7790        mapping: mapping of table names.
7791        dialect: the dialect of the mapping table
7792        copy: whether to copy the expression.
7793
7794    Examples:
7795        >>> from sqlglot import exp, parse_one
7796        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7797        'SELECT * FROM c /* a.b */'
7798
7799    Returns:
7800        The mapped expression.
7801    """
7802
7803    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7804
7805    def _replace_tables(node: Expression) -> Expression:
7806        if isinstance(node, Table):
7807            original = normalize_table_name(node, dialect=dialect)
7808            new_name = mapping.get(original)
7809
7810            if new_name:
7811                table = to_table(
7812                    new_name,
7813                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7814                    dialect=dialect,
7815                )
7816                table.add_comments([original])
7817                return table
7818        return node
7819
7820    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:
7823def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7824    """Replace placeholders in an expression.
7825
7826    Args:
7827        expression: expression node to be transformed and replaced.
7828        args: positional names that will substitute unnamed placeholders in the given order.
7829        kwargs: keyword arguments that will substitute named placeholders.
7830
7831    Examples:
7832        >>> from sqlglot import exp, parse_one
7833        >>> replace_placeholders(
7834        ...     parse_one("select * from :tbl where ? = ?"),
7835        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7836        ... ).sql()
7837        "SELECT * FROM foo WHERE str_col = 'b'"
7838
7839    Returns:
7840        The mapped expression.
7841    """
7842
7843    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7844        if isinstance(node, Placeholder):
7845            if node.this:
7846                new_name = kwargs.get(node.this)
7847                if new_name is not None:
7848                    return convert(new_name)
7849            else:
7850                try:
7851                    return convert(next(args))
7852                except StopIteration:
7853                    pass
7854        return node
7855
7856    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:
7859def expand(
7860    expression: Expression,
7861    sources: t.Dict[str, Query],
7862    dialect: DialectType = None,
7863    copy: bool = True,
7864) -> Expression:
7865    """Transforms an expression by expanding all referenced sources into subqueries.
7866
7867    Examples:
7868        >>> from sqlglot import parse_one
7869        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7870        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7871
7872        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7873        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7874
7875    Args:
7876        expression: The expression to expand.
7877        sources: A dictionary of name to Queries.
7878        dialect: The dialect of the sources dict.
7879        copy: Whether to copy the expression during transformation. Defaults to True.
7880
7881    Returns:
7882        The transformed expression.
7883    """
7884    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7885
7886    def _expand(node: Expression):
7887        if isinstance(node, Table):
7888            name = normalize_table_name(node, dialect=dialect)
7889            source = sources.get(name)
7890            if source:
7891                subquery = source.subquery(node.alias or name)
7892                subquery.comments = [f"source: {name}"]
7893                return subquery.transform(_expand, copy=False)
7894        return node
7895
7896    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:
7899def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7900    """
7901    Returns a Func expression.
7902
7903    Examples:
7904        >>> func("abs", 5).sql()
7905        'ABS(5)'
7906
7907        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7908        'CAST(5 AS DOUBLE)'
7909
7910    Args:
7911        name: the name of the function to build.
7912        args: the args used to instantiate the function of interest.
7913        copy: whether to copy the argument expressions.
7914        dialect: the source dialect.
7915        kwargs: the kwargs used to instantiate the function of interest.
7916
7917    Note:
7918        The arguments `args` and `kwargs` are mutually exclusive.
7919
7920    Returns:
7921        An instance of the function of interest, or an anonymous function, if `name` doesn't
7922        correspond to an existing `sqlglot.expressions.Func` class.
7923    """
7924    if args and kwargs:
7925        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7926
7927    from sqlglot.dialects.dialect import Dialect
7928
7929    dialect = Dialect.get_or_raise(dialect)
7930
7931    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7932    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7933
7934    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7935    if constructor:
7936        if converted:
7937            if "dialect" in constructor.__code__.co_varnames:
7938                function = constructor(converted, dialect=dialect)
7939            else:
7940                function = constructor(converted)
7941        elif constructor.__name__ == "from_arg_list":
7942            function = constructor.__self__(**kwargs)  # type: ignore
7943        else:
7944            constructor = FUNCTION_BY_NAME.get(name.upper())
7945            if constructor:
7946                function = constructor(**kwargs)
7947            else:
7948                raise ValueError(
7949                    f"Unable to convert '{name}' into a Func. Either manually construct "
7950                    "the Func expression of interest or parse the function call."
7951                )
7952    else:
7953        kwargs = kwargs or {"expressions": converted}
7954        function = Anonymous(this=name, **kwargs)
7955
7956    for error_message in function.error_messages(converted):
7957        raise ValueError(error_message)
7958
7959    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 sqlglot.expressions.Func class.

def case( expression: Union[str, Expression, NoneType] = None, **opts) -> Case:
7962def case(
7963    expression: t.Optional[ExpOrStr] = None,
7964    **opts,
7965) -> Case:
7966    """
7967    Initialize a CASE statement.
7968
7969    Example:
7970        case().when("a = 1", "foo").else_("bar")
7971
7972    Args:
7973        expression: Optionally, the input expression (not all dialects support this)
7974        **opts: Extra keyword arguments for parsing `expression`
7975    """
7976    if expression is not None:
7977        this = maybe_parse(expression, **opts)
7978    else:
7979        this = None
7980    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:
7983def array(
7984    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7985) -> Array:
7986    """
7987    Returns an array.
7988
7989    Examples:
7990        >>> array(1, 'x').sql()
7991        'ARRAY(1, x)'
7992
7993    Args:
7994        expressions: the expressions to add to the array.
7995        copy: whether to copy the argument expressions.
7996        dialect: the source dialect.
7997        kwargs: the kwargs used to instantiate the function of interest.
7998
7999    Returns:
8000        An array expression.
8001    """
8002    return Array(
8003        expressions=[
8004            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8005            for expression in expressions
8006        ]
8007    )

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:
8010def tuple_(
8011    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8012) -> Tuple:
8013    """
8014    Returns an tuple.
8015
8016    Examples:
8017        >>> tuple_(1, 'x').sql()
8018        '(1, x)'
8019
8020    Args:
8021        expressions: the expressions to add to the tuple.
8022        copy: whether to copy the argument expressions.
8023        dialect: the source dialect.
8024        kwargs: the kwargs used to instantiate the function of interest.
8025
8026    Returns:
8027        A tuple expression.
8028    """
8029    return Tuple(
8030        expressions=[
8031            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8032            for expression in expressions
8033        ]
8034    )

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:
8037def true() -> Boolean:
8038    """
8039    Returns a true Boolean expression.
8040    """
8041    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8044def false() -> Boolean:
8045    """
8046    Returns a false Boolean expression.
8047    """
8048    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8051def null() -> Null:
8052    """
8053    Returns a Null expression.
8054    """
8055    return Null()

Returns a Null expression.

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