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

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:
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        )

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):
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()
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]
2032    @property
2033    def kind(self) -> t.Optional[str]:
2034        kind = self.args.get("kind")
2035        return kind and kind.upper()
key = 'drop'
class Filter(Expression):
2038class Filter(Expression):
2039    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2042class Check(Expression):
2043    pass
key = 'check'
class Changes(Expression):
2046class Changes(Expression):
2047    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2051class Connect(Expression):
2052    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2055class CopyParameter(Expression):
2056    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
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    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2070class Credentials(Expression):
2071    arg_types = {
2072        "credentials": False,
2073        "encryption": False,
2074        "storage": False,
2075        "iam_role": False,
2076        "region": False,
2077    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2080class Prior(Expression):
2081    pass
key = 'prior'
class Directory(Expression):
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}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2089class ForeignKey(Expression):
2090    arg_types = {
2091        "expressions": True,
2092        "reference": False,
2093        "delete": False,
2094        "update": False,
2095    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2098class ColumnPrefix(Expression):
2099    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2102class PrimaryKey(Expression):
2103    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2108class Into(Expression):
2109    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
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
name: str
2113    @property
2114    def name(self) -> str:
2115        return self.this.name
alias_or_name: str
2117    @property
2118    def alias_or_name(self) -> str:
2119        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2122class Having(Expression):
2123    pass
key = 'having'
class Hint(Expression):
2126class Hint(Expression):
2127    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2130class JoinHint(Expression):
2131    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
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
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2137    @property
2138    def quoted(self) -> bool:
2139        return bool(self.args.get("quoted"))
hashable_args: Any
2141    @property
2142    def hashable_args(self) -> t.Any:
2143        return (self.this, self.quoted)
output_name: str
2145    @property
2146    def output_name(self) -> str:
2147        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):
2151class Opclass(Expression):
2152    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
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    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
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    }
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):
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        )
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:
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        )

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):
2247class ConditionalInsert(Expression):
2248    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2251class MultitableInserts(Expression):
2252    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2255class OnConflict(Expression):
2256    arg_types = {
2257        "duplicate": False,
2258        "expressions": False,
2259        "action": False,
2260        "conflict_keys": False,
2261        "constraint": False,
2262    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class OnCondition(Expression):
2265class OnCondition(Expression):
2266    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2269class Returning(Expression):
2270    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2274class Introducer(Expression):
2275    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2279class National(Expression):
2280    pass
key = 'national'
class LoadData(Expression):
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    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2295class Partition(Expression):
2296    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2299class PartitionRange(Expression):
2300    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2304class PartitionId(Expression):
2305    pass
key = 'partitionid'
class Fetch(Expression):
2308class Fetch(Expression):
2309    arg_types = {
2310        "direction": False,
2311        "count": False,
2312        "percent": False,
2313        "with_ties": False,
2314    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Group(Expression):
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    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2328class Cube(Expression):
2329    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2332class Rollup(Expression):
2333    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2336class GroupingSets(Expression):
2337    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2340class Lambda(Expression):
2341    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2344class Limit(Expression):
2345    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):
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
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2351    @property
2352    def hashable_args(self) -> t.Any:
2353        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2355    @classmethod
2356    def number(cls, number) -> Literal:
2357        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2359    @classmethod
2360    def string(cls, string) -> Literal:
2361        return cls(this=str(string), is_string=True)
output_name: str
2363    @property
2364    def output_name(self) -> str:
2365        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:
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

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
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
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False}
method: str
2389    @property
2390    def method(self) -> str:
2391        return self.text("method").upper()
kind: str
2393    @property
2394    def kind(self) -> str:
2395        return self.text("kind").upper()
side: str
2397    @property
2398    def side(self) -> str:
2399        return self.text("side").upper()
hint: str
2401    @property
2402    def hint(self) -> str:
2403        return self.text("hint").upper()
alias_or_name: str
2405    @property
2406    def alias_or_name(self) -> str:
2407        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:
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

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:
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

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):
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    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2507class MatchRecognizeMeasure(Expression):
2508    arg_types = {
2509        "this": True,
2510        "window_frame": False,
2511    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
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    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2529class Final(Expression):
2530    pass
key = 'final'
class Offset(Expression):
2533class Offset(Expression):
2534    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2537class Order(Expression):
2538    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2542class WithFill(Expression):
2543    arg_types = {
2544        "from": False,
2545        "to": False,
2546        "step": False,
2547        "interpolate": False,
2548    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2553class Cluster(Order):
2554    pass
key = 'cluster'
class Distribute(Order):
2557class Distribute(Order):
2558    pass
key = 'distribute'
class Sort(Order):
2561class Sort(Order):
2562    pass
key = 'sort'
class Ordered(Expression):
2565class Ordered(Expression):
2566    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):
2569class Property(Expression):
2570    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class AllowedValuesProperty(Expression):
2573class AllowedValuesProperty(Expression):
2574    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2577class AlgorithmProperty(Property):
2578    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2581class AutoIncrementProperty(Property):
2582    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2586class AutoRefreshProperty(Property):
2587    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2590class BackupProperty(Property):
2591    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2594class BlockCompressionProperty(Property):
2595    arg_types = {
2596        "autotemp": False,
2597        "always": False,
2598        "default": False,
2599        "manual": False,
2600        "never": False,
2601    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2604class CharacterSetProperty(Property):
2605    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2608class ChecksumProperty(Property):
2609    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2612class CollateProperty(Property):
2613    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2616class CopyGrantsProperty(Property):
2617    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2620class DataBlocksizeProperty(Property):
2621    arg_types = {
2622        "size": False,
2623        "units": False,
2624        "minimum": False,
2625        "maximum": False,
2626        "default": False,
2627    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2630class DataDeletionProperty(Property):
2631    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):
2634class DefinerProperty(Property):
2635    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2638class DistKeyProperty(Property):
2639    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2644class DistributedByProperty(Property):
2645    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):
2648class DistStyleProperty(Property):
2649    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2652class DuplicateKeyProperty(Property):
2653    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2656class EngineProperty(Property):
2657    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2660class HeapProperty(Property):
2661    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2664class ToTableProperty(Property):
2665    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2668class ExecuteAsProperty(Property):
2669    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2672class ExternalProperty(Property):
2673    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2676class FallbackProperty(Property):
2677    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2680class FileFormatProperty(Property):
2681    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2684class FreespaceProperty(Property):
2685    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2688class GlobalProperty(Property):
2689    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2692class IcebergProperty(Property):
2693    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2696class InheritsProperty(Property):
2697    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2700class InputModelProperty(Property):
2701    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2704class OutputModelProperty(Property):
2705    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2708class IsolatedLoadingProperty(Property):
2709    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2712class JournalProperty(Property):
2713    arg_types = {
2714        "no": False,
2715        "dual": False,
2716        "before": False,
2717        "local": False,
2718        "after": False,
2719    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2722class LanguageProperty(Property):
2723    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2727class ClusteredByProperty(Property):
2728    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2731class DictProperty(Property):
2732    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2735class DictSubProperty(Property):
2736    pass
key = 'dictsubproperty'
class DictRange(Property):
2739class DictRange(Property):
2740    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2743class DynamicProperty(Property):
2744    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2749class OnCluster(Property):
2750    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2754class EmptyProperty(Property):
2755    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2758class LikeProperty(Property):
2759    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2762class LocationProperty(Property):
2763    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2766class LockProperty(Property):
2767    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
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    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2780class LogProperty(Property):
2781    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2784class MaterializedProperty(Property):
2785    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2788class MergeBlockRatioProperty(Property):
2789    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):
2792class NoPrimaryIndexProperty(Property):
2793    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2796class OnProperty(Property):
2797    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2800class OnCommitProperty(Property):
2801    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2804class PartitionedByProperty(Property):
2805    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
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    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2819class PartitionedOfProperty(Property):
2820    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2821    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2824class StreamingTableProperty(Property):
2825    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2828class RemoteWithConnectionModelProperty(Property):
2829    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2832class ReturnsProperty(Property):
2833    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):
2836class StrictProperty(Property):
2837    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2840class RowFormatProperty(Property):
2841    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
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    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2857class RowFormatSerdeProperty(Property):
2858    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
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    }
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):
2874class SampleProperty(Property):
2875    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2879class SecurityProperty(Property):
2880    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2883class SchemaCommentProperty(Property):
2884    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2887class SerdeProperties(Property):
2888    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2891class SetProperty(Property):
2892    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2895class SharingProperty(Property):
2896    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2899class SetConfigProperty(Property):
2900    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2903class SettingsProperty(Property):
2904    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2907class SortKeyProperty(Property):
2908    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2911class SqlReadWriteProperty(Property):
2912    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2915class SqlSecurityProperty(Property):
2916    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2919class StabilityProperty(Property):
2920    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2923class TemporaryProperty(Property):
2924    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2927class SecureProperty(Property):
2928    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2931class TransformModelProperty(Property):
2932    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2935class TransientProperty(Property):
2936    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2939class UnloggedProperty(Property):
2940    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2944class ViewAttributeProperty(Property):
2945    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2948class VolatileProperty(Property):
2949    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2952class WithDataProperty(Property):
2953    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2956class WithJournalTableProperty(Property):
2957    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2960class WithSchemaBindingProperty(Property):
2961    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2964class WithSystemVersioningProperty(Property):
2965    arg_types = {
2966        "on": False,
2967        "this": False,
2968        "data_consistency": False,
2969        "retention_period": False,
2970        "with": True,
2971    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
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)
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:
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)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
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()

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):
3038class Qualify(Expression):
3039    pass
key = 'qualify'
class InputOutputFormat(Expression):
3042class InputOutputFormat(Expression):
3043    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3047class Return(Expression):
3048    pass
key = 'return'
class Reference(Expression):
3051class Reference(Expression):
3052    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
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        )
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:
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        )
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):
3111class QueryOption(Expression):
3112    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3116class WithTableHint(Expression):
3117    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3121class IndexTableHint(Expression):
3122    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3126class HistoricalData(Expression):
3127    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
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
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
3153    @property
3154    def name(self) -> str:
3155        if isinstance(self.this, Func):
3156            return ""
3157        return self.this.name
db: str
3159    @property
3160    def db(self) -> str:
3161        return self.text("db")
catalog: str
3163    @property
3164    def catalog(self) -> str:
3165        return self.text("catalog")
selects: List[Expression]
3167    @property
3168    def selects(self) -> t.List[Expression]:
3169        return []
named_selects: List[str]
3171    @property
3172    def named_selects(self) -> t.List[str]:
3173        return []
parts: List[Expression]
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

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
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
key = 'table'
class SetOperation(Query):
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
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:
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

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]
3224    @property
3225    def named_selects(self) -> t.List[str]:
3226        return self.this.unnest().named_selects

Returns the output names of the query's projections.

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

Checks whether an expression is a star.

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

Returns the query's projections.

left: Query
3236    @property
3237    def left(self) -> Query:
3238        return self.this
right: Query
3240    @property
3241    def right(self) -> Query:
3242        return self.expression
key = 'setoperation'
class Union(SetOperation):
3245class Union(SetOperation):
3246    pass
key = 'union'
class Except(SetOperation):
3249class Except(SetOperation):
3250    pass
key = 'except'
class Intersect(SetOperation):
3253class Intersect(SetOperation):
3254    pass
key = 'intersect'
class Update(Expression):
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    }
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
key = 'update'
class Values(UDTF):
3270class Values(UDTF):
3271    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3274class Var(Expression):
3275    pass
key = 'var'
class Version(Expression):
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}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3292class Schema(Expression):
3293    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3298class Lock(Expression):
3299    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
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
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:
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        )

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:
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        )

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:
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        )

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:
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        )

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:
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        )

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:
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        )

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:
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        )

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:
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        )

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:
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        )

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:
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        )
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:
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        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
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

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:
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        )

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:
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

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:
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

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]
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]

Returns the output names of the query's projections.

is_star: bool
3856    @property
3857    def is_star(self) -> bool:
3858        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

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

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
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
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):
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

Returns the first non subquery.

def unwrap(self) -> Subquery:
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
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:
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

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
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")

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
3912    @property
3913    def is_star(self) -> bool:
3914        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3916    @property
3917    def output_name(self) -> str:
3918        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):
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    }
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):
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    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
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"))
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
3961    @property
3962    def unpivot(self) -> bool:
3963        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
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    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3978class WindowSpec(Expression):
3979    arg_types = {
3980        "kind": False,
3981        "start": False,
3982        "start_side": False,
3983        "end": False,
3984        "end_side": False,
3985    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
3988class PreWhere(Expression):
3989    pass
key = 'prewhere'
class Where(Expression):
3992class Where(Expression):
3993    pass
key = 'where'
class Star(Expression):
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
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
3999    @property
4000    def name(self) -> str:
4001        return "*"
output_name: str
4003    @property
4004    def output_name(self) -> str:
4005        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):
4008class Parameter(Condition):
4009    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4012class SessionParameter(Condition):
4013    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4016class Placeholder(Condition):
4017    arg_types = {"this": False, "kind": False}
4018
4019    @property
4020    def name(self) -> str:
4021        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4019    @property
4020    def name(self) -> str:
4021        return self.this or "?"
key = 'placeholder'
class Null(Condition):
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
arg_types: Dict[str, Any] = {}
name: str
4027    @property
4028    def name(self) -> str:
4029        return "NULL"
def to_py(self) -> Literal[None]:
4031    def to_py(self) -> Lit[None]:
4032        return None

Returns a Python object equivalent of the SQL node.

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

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4040class DataTypeParam(Expression):
4041    arg_types = {"this": True, "expression": False}
4042
4043    @property
4044    def name(self) -> str:
4045        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4043    @property
4044    def name(self) -> str:
4045        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
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        UNIQUEIDENTIFIER = auto()
4158        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4159        USERDEFINED = "USER-DEFINED"
4160        USMALLINT = auto()
4161        UTINYINT = auto()
4162        UUID = auto()
4163        VARBINARY = auto()
4164        VARCHAR = auto()
4165        VARIANT = auto()
4166        VECTOR = auto()
4167        XML = auto()
4168        YEAR = auto()
4169        TDIGEST = auto()
4170
4171    STRUCT_TYPES = {
4172        Type.NESTED,
4173        Type.OBJECT,
4174        Type.STRUCT,
4175    }
4176
4177    NESTED_TYPES = {
4178        *STRUCT_TYPES,
4179        Type.ARRAY,
4180        Type.MAP,
4181    }
4182
4183    TEXT_TYPES = {
4184        Type.CHAR,
4185        Type.NCHAR,
4186        Type.NVARCHAR,
4187        Type.TEXT,
4188        Type.VARCHAR,
4189        Type.NAME,
4190    }
4191
4192    SIGNED_INTEGER_TYPES = {
4193        Type.BIGINT,
4194        Type.INT,
4195        Type.INT128,
4196        Type.INT256,
4197        Type.MEDIUMINT,
4198        Type.SMALLINT,
4199        Type.TINYINT,
4200    }
4201
4202    UNSIGNED_INTEGER_TYPES = {
4203        Type.UBIGINT,
4204        Type.UINT,
4205        Type.UINT128,
4206        Type.UINT256,
4207        Type.UMEDIUMINT,
4208        Type.USMALLINT,
4209        Type.UTINYINT,
4210    }
4211
4212    INTEGER_TYPES = {
4213        *SIGNED_INTEGER_TYPES,
4214        *UNSIGNED_INTEGER_TYPES,
4215        Type.BIT,
4216    }
4217
4218    FLOAT_TYPES = {
4219        Type.DOUBLE,
4220        Type.FLOAT,
4221    }
4222
4223    REAL_TYPES = {
4224        *FLOAT_TYPES,
4225        Type.BIGDECIMAL,
4226        Type.DECIMAL,
4227        Type.DECIMAL32,
4228        Type.DECIMAL64,
4229        Type.DECIMAL128,
4230        Type.MONEY,
4231        Type.SMALLMONEY,
4232        Type.UDECIMAL,
4233    }
4234
4235    NUMERIC_TYPES = {
4236        *INTEGER_TYPES,
4237        *REAL_TYPES,
4238    }
4239
4240    TEMPORAL_TYPES = {
4241        Type.DATE,
4242        Type.DATE32,
4243        Type.DATETIME,
4244        Type.DATETIME64,
4245        Type.TIME,
4246        Type.TIMESTAMP,
4247        Type.TIMESTAMPNTZ,
4248        Type.TIMESTAMPLTZ,
4249        Type.TIMESTAMPTZ,
4250        Type.TIMESTAMP_MS,
4251        Type.TIMESTAMP_NS,
4252        Type.TIMESTAMP_S,
4253        Type.TIMETZ,
4254    }
4255
4256    @classmethod
4257    def build(
4258        cls,
4259        dtype: DATA_TYPE,
4260        dialect: DialectType = None,
4261        udt: bool = False,
4262        copy: bool = True,
4263        **kwargs,
4264    ) -> DataType:
4265        """
4266        Constructs a DataType object.
4267
4268        Args:
4269            dtype: the data type of interest.
4270            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4271            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4272                DataType, thus creating a user-defined type.
4273            copy: whether to copy the data type.
4274            kwargs: additional arguments to pass in the constructor of DataType.
4275
4276        Returns:
4277            The constructed DataType object.
4278        """
4279        from sqlglot import parse_one
4280
4281        if isinstance(dtype, str):
4282            if dtype.upper() == "UNKNOWN":
4283                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4284
4285            try:
4286                data_type_exp = parse_one(
4287                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4288                )
4289            except ParseError:
4290                if udt:
4291                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4292                raise
4293        elif isinstance(dtype, DataType.Type):
4294            data_type_exp = DataType(this=dtype)
4295        elif isinstance(dtype, DataType):
4296            return maybe_copy(dtype, copy)
4297        else:
4298            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4299
4300        return DataType(**{**data_type_exp.args, **kwargs})
4301
4302    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4303        """
4304        Checks whether this DataType matches one of the provided data types. Nested types or precision
4305        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4306
4307        Args:
4308            dtypes: the data types to compare this DataType to.
4309            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4310                If false, it means that NULLABLE<INT> is equivalent to INT.
4311
4312        Returns:
4313            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4314        """
4315        self_is_nullable = self.args.get("nullable")
4316        for dtype in dtypes:
4317            other_type = DataType.build(dtype, copy=False, udt=True)
4318            other_is_nullable = other_type.args.get("nullable")
4319            if (
4320                other_type.expressions
4321                or (check_nullable and (self_is_nullable or other_is_nullable))
4322                or self.this == DataType.Type.USERDEFINED
4323                or other_type.this == DataType.Type.USERDEFINED
4324            ):
4325                matches = self == other_type
4326            else:
4327                matches = self.this == other_type.this
4328
4329            if matches:
4330                return True
4331        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>}
NESTED_TYPES = {<Type.MAP: 'MAP'>, <Type.OBJECT: 'OBJECT'>, <Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>, <Type.ARRAY: 'ARRAY'>}
TEXT_TYPES = {<Type.NCHAR: 'NCHAR'>, <Type.NAME: 'NAME'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.CHAR: 'CHAR'>, <Type.TEXT: 'TEXT'>}
SIGNED_INTEGER_TYPES = {<Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT256: 'INT256'>}
UNSIGNED_INTEGER_TYPES = {<Type.USMALLINT: 'USMALLINT'>, <Type.UINT256: 'UINT256'>, <Type.UINT128: 'UINT128'>, <Type.UINT: 'UINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
INTEGER_TYPES = {<Type.USMALLINT: 'USMALLINT'>, <Type.BIT: 'BIT'>, <Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.UINT256: 'UINT256'>, <Type.UBIGINT: 'UBIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT128: 'UINT128'>, <Type.INT128: 'INT128'>, <Type.BIGINT: 'BIGINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT: 'UINT'>, <Type.INT256: 'INT256'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.UDECIMAL: 'UDECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.MONEY: 'MONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DECIMAL32: 'DECIMAL32'>}
NUMERIC_TYPES = {<Type.USMALLINT: 'USMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT128: 'UINT128'>, <Type.INT128: 'INT128'>, <Type.DOUBLE: 'DOUBLE'>, <Type.MONEY: 'MONEY'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.FLOAT: 'FLOAT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.INT256: 'INT256'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.BIT: 'BIT'>, <Type.UINT256: 'UINT256'>, <Type.INT: 'INT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.BIGINT: 'BIGINT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT: 'UINT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
TEMPORAL_TYPES = {<Type.DATETIME64: 'DATETIME64'>, <Type.DATE32: 'DATE32'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATE: 'DATE'>, <Type.TIME: 'TIME'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <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:
4256    @classmethod
4257    def build(
4258        cls,
4259        dtype: DATA_TYPE,
4260        dialect: DialectType = None,
4261        udt: bool = False,
4262        copy: bool = True,
4263        **kwargs,
4264    ) -> DataType:
4265        """
4266        Constructs a DataType object.
4267
4268        Args:
4269            dtype: the data type of interest.
4270            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4271            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4272                DataType, thus creating a user-defined type.
4273            copy: whether to copy the data type.
4274            kwargs: additional arguments to pass in the constructor of DataType.
4275
4276        Returns:
4277            The constructed DataType object.
4278        """
4279        from sqlglot import parse_one
4280
4281        if isinstance(dtype, str):
4282            if dtype.upper() == "UNKNOWN":
4283                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4284
4285            try:
4286                data_type_exp = parse_one(
4287                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4288                )
4289            except ParseError:
4290                if udt:
4291                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4292                raise
4293        elif isinstance(dtype, DataType.Type):
4294            data_type_exp = DataType(this=dtype)
4295        elif isinstance(dtype, DataType):
4296            return maybe_copy(dtype, copy)
4297        else:
4298            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4299
4300        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:
4302    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4303        """
4304        Checks whether this DataType matches one of the provided data types. Nested types or precision
4305        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4306
4307        Args:
4308            dtypes: the data types to compare this DataType to.
4309            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4310                If false, it means that NULLABLE<INT> is equivalent to INT.
4311
4312        Returns:
4313            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4314        """
4315        self_is_nullable = self.args.get("nullable")
4316        for dtype in dtypes:
4317            other_type = DataType.build(dtype, copy=False, udt=True)
4318            other_is_nullable = other_type.args.get("nullable")
4319            if (
4320                other_type.expressions
4321                or (check_nullable and (self_is_nullable or other_is_nullable))
4322                or self.this == DataType.Type.USERDEFINED
4323                or other_type.this == DataType.Type.USERDEFINED
4324            ):
4325                matches = self == other_type
4326            else:
4327                matches = self.this == other_type.this
4328
4329            if matches:
4330                return True
4331        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):
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        UNIQUEIDENTIFIER = auto()
4158        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4159        USERDEFINED = "USER-DEFINED"
4160        USMALLINT = auto()
4161        UTINYINT = auto()
4162        UUID = auto()
4163        VARBINARY = auto()
4164        VARCHAR = auto()
4165        VARIANT = auto()
4166        VECTOR = auto()
4167        XML = auto()
4168        YEAR = auto()
4169        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'>
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):
4338class PseudoType(DataType):
4339    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4343class ObjectIdentifier(DataType):
4344    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4348class SubqueryPredicate(Predicate):
4349    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4352class All(SubqueryPredicate):
4353    pass
key = 'all'
class Any(SubqueryPredicate):
4356class Any(SubqueryPredicate):
4357    pass
key = 'any'
class Exists(SubqueryPredicate):
4360class Exists(SubqueryPredicate):
4361    pass
key = 'exists'
class Command(Expression):
4366class Command(Expression):
4367    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4370class Transaction(Expression):
4371    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4374class Commit(Expression):
4375    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4378class Rollback(Expression):
4379    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4382class Alter(Expression):
4383    arg_types = {
4384        "this": True,
4385        "kind": True,
4386        "actions": True,
4387        "exists": False,
4388        "only": False,
4389        "options": False,
4390        "cluster": False,
4391        "not_valid": False,
4392    }
arg_types = {'this': True, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False, 'not_valid': False}
key = 'alter'
class AddConstraint(Expression):
4395class AddConstraint(Expression):
4396    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class DropPartition(Expression):
4399class DropPartition(Expression):
4400    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4404class ReplacePartition(Expression):
4405    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4409class Binary(Condition):
4410    arg_types = {"this": True, "expression": True}
4411
4412    @property
4413    def left(self) -> Expression:
4414        return self.this
4415
4416    @property
4417    def right(self) -> Expression:
4418        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4412    @property
4413    def left(self) -> Expression:
4414        return self.this
right: Expression
4416    @property
4417    def right(self) -> Expression:
4418        return self.expression
key = 'binary'
class Add(Binary):
4421class Add(Binary):
4422    pass
key = 'add'
class Connector(Binary):
4425class Connector(Binary):
4426    pass
key = 'connector'
class And(Connector):
4429class And(Connector):
4430    pass
key = 'and'
class Or(Connector):
4433class Or(Connector):
4434    pass
key = 'or'
class BitwiseAnd(Binary):
4437class BitwiseAnd(Binary):
4438    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4441class BitwiseLeftShift(Binary):
4442    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4445class BitwiseOr(Binary):
4446    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4449class BitwiseRightShift(Binary):
4450    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4453class BitwiseXor(Binary):
4454    pass
key = 'bitwisexor'
class Div(Binary):
4457class Div(Binary):
4458    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):
4461class Overlaps(Binary):
4462    pass
key = 'overlaps'
class Dot(Binary):
4465class Dot(Binary):
4466    @property
4467    def is_star(self) -> bool:
4468        return self.expression.is_star
4469
4470    @property
4471    def name(self) -> str:
4472        return self.expression.name
4473
4474    @property
4475    def output_name(self) -> str:
4476        return self.name
4477
4478    @classmethod
4479    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4480        """Build a Dot object with a sequence of expressions."""
4481        if len(expressions) < 2:
4482            raise ValueError("Dot requires >= 2 expressions.")
4483
4484        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4485
4486    @property
4487    def parts(self) -> t.List[Expression]:
4488        """Return the parts of a table / column in order catalog, db, table."""
4489        this, *parts = self.flatten()
4490
4491        parts.reverse()
4492
4493        for arg in COLUMN_PARTS:
4494            part = this.args.get(arg)
4495
4496            if isinstance(part, Expression):
4497                parts.append(part)
4498
4499        parts.reverse()
4500        return parts
is_star: bool
4466    @property
4467    def is_star(self) -> bool:
4468        return self.expression.is_star

Checks whether an expression is a star.

name: str
4470    @property
4471    def name(self) -> str:
4472        return self.expression.name
output_name: str
4474    @property
4475    def output_name(self) -> str:
4476        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:
4478    @classmethod
4479    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4480        """Build a Dot object with a sequence of expressions."""
4481        if len(expressions) < 2:
4482            raise ValueError("Dot requires >= 2 expressions.")
4483
4484        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]
4486    @property
4487    def parts(self) -> t.List[Expression]:
4488        """Return the parts of a table / column in order catalog, db, table."""
4489        this, *parts = self.flatten()
4490
4491        parts.reverse()
4492
4493        for arg in COLUMN_PARTS:
4494            part = this.args.get(arg)
4495
4496            if isinstance(part, Expression):
4497                parts.append(part)
4498
4499        parts.reverse()
4500        return parts

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

key = 'dot'
class DPipe(Binary):
4503class DPipe(Binary):
4504    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4507class EQ(Binary, Predicate):
4508    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4511class NullSafeEQ(Binary, Predicate):
4512    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4515class NullSafeNEQ(Binary, Predicate):
4516    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4520class PropertyEQ(Binary):
4521    pass
key = 'propertyeq'
class Distance(Binary):
4524class Distance(Binary):
4525    pass
key = 'distance'
class Escape(Binary):
4528class Escape(Binary):
4529    pass
key = 'escape'
class Glob(Binary, Predicate):
4532class Glob(Binary, Predicate):
4533    pass
key = 'glob'
class GT(Binary, Predicate):
4536class GT(Binary, Predicate):
4537    pass
key = 'gt'
class GTE(Binary, Predicate):
4540class GTE(Binary, Predicate):
4541    pass
key = 'gte'
class ILike(Binary, Predicate):
4544class ILike(Binary, Predicate):
4545    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4548class ILikeAny(Binary, Predicate):
4549    pass
key = 'ilikeany'
class IntDiv(Binary):
4552class IntDiv(Binary):
4553    pass
key = 'intdiv'
class Is(Binary, Predicate):
4556class Is(Binary, Predicate):
4557    pass
key = 'is'
class Kwarg(Binary):
4560class Kwarg(Binary):
4561    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4564class Like(Binary, Predicate):
4565    pass
key = 'like'
class LikeAny(Binary, Predicate):
4568class LikeAny(Binary, Predicate):
4569    pass
key = 'likeany'
class LT(Binary, Predicate):
4572class LT(Binary, Predicate):
4573    pass
key = 'lt'
class LTE(Binary, Predicate):
4576class LTE(Binary, Predicate):
4577    pass
key = 'lte'
class Mod(Binary):
4580class Mod(Binary):
4581    pass
key = 'mod'
class Mul(Binary):
4584class Mul(Binary):
4585    pass
key = 'mul'
class NEQ(Binary, Predicate):
4588class NEQ(Binary, Predicate):
4589    pass
key = 'neq'
class Operator(Binary):
4593class Operator(Binary):
4594    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4597class SimilarTo(Binary, Predicate):
4598    pass
key = 'similarto'
class Slice(Binary):
4601class Slice(Binary):
4602    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4605class Sub(Binary):
4606    pass
key = 'sub'
class Unary(Condition):
4611class Unary(Condition):
4612    pass
key = 'unary'
class BitwiseNot(Unary):
4615class BitwiseNot(Unary):
4616    pass
key = 'bitwisenot'
class Not(Unary):
4619class Not(Unary):
4620    pass
key = 'not'
class Paren(Unary):
4623class Paren(Unary):
4624    @property
4625    def output_name(self) -> str:
4626        return self.this.name
output_name: str
4624    @property
4625    def output_name(self) -> str:
4626        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):
4629class Neg(Unary):
4630    def to_py(self) -> int | Decimal:
4631        if self.is_number:
4632            return self.this.to_py() * -1
4633        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4630    def to_py(self) -> int | Decimal:
4631        if self.is_number:
4632            return self.this.to_py() * -1
4633        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4636class Alias(Expression):
4637    arg_types = {"this": True, "alias": False}
4638
4639    @property
4640    def output_name(self) -> str:
4641        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4639    @property
4640    def output_name(self) -> str:
4641        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):
4646class PivotAlias(Alias):
4647    pass
key = 'pivotalias'
class PivotAny(Expression):
4652class PivotAny(Expression):
4653    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4656class Aliases(Expression):
4657    arg_types = {"this": True, "expressions": True}
4658
4659    @property
4660    def aliases(self):
4661        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4659    @property
4660    def aliases(self):
4661        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4665class AtIndex(Expression):
4666    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4669class AtTimeZone(Expression):
4670    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4673class FromTimeZone(Expression):
4674    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4677class Between(Predicate):
4678    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4681class Bracket(Condition):
4682    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4683    arg_types = {
4684        "this": True,
4685        "expressions": True,
4686        "offset": False,
4687        "safe": False,
4688        "returns_list_for_maps": False,
4689    }
4690
4691    @property
4692    def output_name(self) -> str:
4693        if len(self.expressions) == 1:
4694            return self.expressions[0].output_name
4695
4696        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4691    @property
4692    def output_name(self) -> str:
4693        if len(self.expressions) == 1:
4694            return self.expressions[0].output_name
4695
4696        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):
4699class Distinct(Expression):
4700    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4703class In(Predicate):
4704    arg_types = {
4705        "this": True,
4706        "expressions": False,
4707        "query": False,
4708        "unnest": False,
4709        "field": False,
4710        "is_global": False,
4711    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4715class ForIn(Expression):
4716    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4719class TimeUnit(Expression):
4720    """Automatically converts unit arg into a var."""
4721
4722    arg_types = {"unit": False}
4723
4724    UNABBREVIATED_UNIT_NAME = {
4725        "D": "DAY",
4726        "H": "HOUR",
4727        "M": "MINUTE",
4728        "MS": "MILLISECOND",
4729        "NS": "NANOSECOND",
4730        "Q": "QUARTER",
4731        "S": "SECOND",
4732        "US": "MICROSECOND",
4733        "W": "WEEK",
4734        "Y": "YEAR",
4735    }
4736
4737    VAR_LIKE = (Column, Literal, Var)
4738
4739    def __init__(self, **args):
4740        unit = args.get("unit")
4741        if isinstance(unit, self.VAR_LIKE):
4742            args["unit"] = Var(
4743                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4744            )
4745        elif isinstance(unit, Week):
4746            unit.set("this", Var(this=unit.this.name.upper()))
4747
4748        super().__init__(**args)
4749
4750    @property
4751    def unit(self) -> t.Optional[Var | IntervalSpan]:
4752        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4739    def __init__(self, **args):
4740        unit = args.get("unit")
4741        if isinstance(unit, self.VAR_LIKE):
4742            args["unit"] = Var(
4743                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4744            )
4745        elif isinstance(unit, Week):
4746            unit.set("this", Var(this=unit.this.name.upper()))
4747
4748        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]
4750    @property
4751    def unit(self) -> t.Optional[Var | IntervalSpan]:
4752        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4755class IntervalOp(TimeUnit):
4756    arg_types = {"unit": False, "expression": True}
4757
4758    def interval(self):
4759        return Interval(
4760            this=self.expression.copy(),
4761            unit=self.unit.copy() if self.unit else None,
4762        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
4758    def interval(self):
4759        return Interval(
4760            this=self.expression.copy(),
4761            unit=self.unit.copy() if self.unit else None,
4762        )
key = 'intervalop'
class IntervalSpan(DataType):
4768class IntervalSpan(DataType):
4769    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4772class Interval(TimeUnit):
4773    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4776class IgnoreNulls(Expression):
4777    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4780class RespectNulls(Expression):
4781    pass
key = 'respectnulls'
class HavingMax(Expression):
4785class HavingMax(Expression):
4786    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4790class Func(Condition):
4791    """
4792    The base class for all function expressions.
4793
4794    Attributes:
4795        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4796            treated as a variable length argument and the argument's value will be stored as a list.
4797        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4798            function expression. These values are used to map this node to a name during parsing as
4799            well as to provide the function's name during SQL string generation. By default the SQL
4800            name is set to the expression's class name transformed to snake case.
4801    """
4802
4803    is_var_len_args = False
4804
4805    @classmethod
4806    def from_arg_list(cls, args):
4807        if cls.is_var_len_args:
4808            all_arg_keys = list(cls.arg_types)
4809            # If this function supports variable length argument treat the last argument as such.
4810            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4811            num_non_var = len(non_var_len_arg_keys)
4812
4813            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4814            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4815        else:
4816            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4817
4818        return cls(**args_dict)
4819
4820    @classmethod
4821    def sql_names(cls):
4822        if cls is Func:
4823            raise NotImplementedError(
4824                "SQL name is only supported by concrete function implementations"
4825            )
4826        if "_sql_names" not in cls.__dict__:
4827            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4828        return cls._sql_names
4829
4830    @classmethod
4831    def sql_name(cls):
4832        return cls.sql_names()[0]
4833
4834    @classmethod
4835    def default_parser_mappings(cls):
4836        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):
4805    @classmethod
4806    def from_arg_list(cls, args):
4807        if cls.is_var_len_args:
4808            all_arg_keys = list(cls.arg_types)
4809            # If this function supports variable length argument treat the last argument as such.
4810            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4811            num_non_var = len(non_var_len_arg_keys)
4812
4813            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4814            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4815        else:
4816            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4817
4818        return cls(**args_dict)
@classmethod
def sql_names(cls):
4820    @classmethod
4821    def sql_names(cls):
4822        if cls is Func:
4823            raise NotImplementedError(
4824                "SQL name is only supported by concrete function implementations"
4825            )
4826        if "_sql_names" not in cls.__dict__:
4827            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4828        return cls._sql_names
@classmethod
def sql_name(cls):
4830    @classmethod
4831    def sql_name(cls):
4832        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4834    @classmethod
4835    def default_parser_mappings(cls):
4836        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4839class AggFunc(Func):
4840    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4843class ParameterizedAgg(AggFunc):
4844    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4847class Abs(Func):
4848    pass
key = 'abs'
class ArgMax(AggFunc):
4851class ArgMax(AggFunc):
4852    arg_types = {"this": True, "expression": True, "count": False}
4853    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4856class ArgMin(AggFunc):
4857    arg_types = {"this": True, "expression": True, "count": False}
4858    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4861class ApproxTopK(AggFunc):
4862    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4865class Flatten(Func):
4866    pass
key = 'flatten'
class Transform(Func):
4870class Transform(Func):
4871    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4874class Anonymous(Func):
4875    arg_types = {"this": True, "expressions": False}
4876    is_var_len_args = True
4877
4878    @property
4879    def name(self) -> str:
4880        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
4878    @property
4879    def name(self) -> str:
4880        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4883class AnonymousAggFunc(AggFunc):
4884    arg_types = {"this": True, "expressions": False}
4885    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4889class CombinedAggFunc(AnonymousAggFunc):
4890    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4893class CombinedParameterizedAgg(ParameterizedAgg):
4894    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):
4899class Hll(AggFunc):
4900    arg_types = {"this": True, "expressions": False}
4901    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4904class ApproxDistinct(AggFunc):
4905    arg_types = {"this": True, "accuracy": False}
4906    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Array(Func):
4909class Array(Func):
4910    arg_types = {"expressions": False, "bracket_notation": False}
4911    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4915class ToArray(Func):
4916    pass
key = 'toarray'
class List(Func):
4920class List(Func):
4921    arg_types = {"expressions": False}
4922    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4926class Pad(Func):
4927    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):
4932class ToChar(Func):
4933    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4938class ToNumber(Func):
4939    arg_types = {
4940        "this": True,
4941        "format": False,
4942        "nlsparam": False,
4943        "precision": False,
4944        "scale": False,
4945    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4949class Convert(Func):
4950    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
4953class ConvertTimezone(Func):
4954    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):
4957class GenerateSeries(Func):
4958    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):
4964class ExplodingGenerateSeries(GenerateSeries):
4965    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
4968class ArrayAgg(AggFunc):
4969    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
4972class ArrayUniqueAgg(AggFunc):
4973    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
4976class ArrayAll(Func):
4977    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
4981class ArrayAny(Func):
4982    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
4985class ArrayConcat(Func):
4986    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
4987    arg_types = {"this": True, "expressions": False}
4988    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
4991class ArrayConstructCompact(Func):
4992    arg_types = {"expressions": True}
4993    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
4996class ArrayContains(Binary, Func):
4997    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5000class ArrayContainsAll(Binary, Func):
5001    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5004class ArrayFilter(Func):
5005    arg_types = {"this": True, "expression": True}
5006    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5009class ArrayToString(Func):
5010    arg_types = {"this": True, "expression": True, "null": False}
5011    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
5014class StringToArray(Func):
5015    arg_types = {"this": True, "expression": True, "null": False}
5016    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5019class ArrayOverlaps(Binary, Func):
5020    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5023class ArraySize(Func):
5024    arg_types = {"this": True, "expression": False}
5025    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5028class ArraySort(Func):
5029    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5032class ArraySum(Func):
5033    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5036class ArrayUnionAgg(AggFunc):
5037    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5040class Avg(AggFunc):
5041    pass
key = 'avg'
class AnyValue(AggFunc):
5044class AnyValue(AggFunc):
5045    pass
key = 'anyvalue'
class Lag(AggFunc):
5048class Lag(AggFunc):
5049    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5052class Lead(AggFunc):
5053    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5058class First(AggFunc):
5059    pass
key = 'first'
class Last(AggFunc):
5062class Last(AggFunc):
5063    pass
key = 'last'
class FirstValue(AggFunc):
5066class FirstValue(AggFunc):
5067    pass
key = 'firstvalue'
class LastValue(AggFunc):
5070class LastValue(AggFunc):
5071    pass
key = 'lastvalue'
class NthValue(AggFunc):
5074class NthValue(AggFunc):
5075    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5078class Case(Func):
5079    arg_types = {"this": False, "ifs": True, "default": False}
5080
5081    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5082        instance = maybe_copy(self, copy)
5083        instance.append(
5084            "ifs",
5085            If(
5086                this=maybe_parse(condition, copy=copy, **opts),
5087                true=maybe_parse(then, copy=copy, **opts),
5088            ),
5089        )
5090        return instance
5091
5092    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5093        instance = maybe_copy(self, copy)
5094        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5095        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:
5081    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5082        instance = maybe_copy(self, copy)
5083        instance.append(
5084            "ifs",
5085            If(
5086                this=maybe_parse(condition, copy=copy, **opts),
5087                true=maybe_parse(then, copy=copy, **opts),
5088            ),
5089        )
5090        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5092    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5093        instance = maybe_copy(self, copy)
5094        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5095        return instance
key = 'case'
class Cast(Func):
5098class Cast(Func):
5099    arg_types = {
5100        "this": True,
5101        "to": True,
5102        "format": False,
5103        "safe": False,
5104        "action": False,
5105    }
5106
5107    @property
5108    def name(self) -> str:
5109        return self.this.name
5110
5111    @property
5112    def to(self) -> DataType:
5113        return self.args["to"]
5114
5115    @property
5116    def output_name(self) -> str:
5117        return self.name
5118
5119    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5120        """
5121        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5122        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5123        array<int> != array<float>.
5124
5125        Args:
5126            dtypes: the data types to compare this Cast's DataType to.
5127
5128        Returns:
5129            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5130        """
5131        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5107    @property
5108    def name(self) -> str:
5109        return self.this.name
to: DataType
5111    @property
5112    def to(self) -> DataType:
5113        return self.args["to"]
output_name: str
5115    @property
5116    def output_name(self) -> str:
5117        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:
5119    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5120        """
5121        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5122        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5123        array<int> != array<float>.
5124
5125        Args:
5126            dtypes: the data types to compare this Cast's DataType to.
5127
5128        Returns:
5129            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5130        """
5131        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):
5134class TryCast(Cast):
5135    pass
key = 'trycast'
class Try(Func):
5138class Try(Func):
5139    pass
key = 'try'
class CastToStrType(Func):
5142class CastToStrType(Func):
5143    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5146class Collate(Binary, Func):
5147    pass
key = 'collate'
class Ceil(Func):
5150class Ceil(Func):
5151    arg_types = {"this": True, "decimals": False}
5152    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5155class Coalesce(Func):
5156    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5157    is_var_len_args = True
5158    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5161class Chr(Func):
5162    arg_types = {"expressions": True, "charset": False}
5163    is_var_len_args = True
5164    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5167class Concat(Func):
5168    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5169    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5172class ConcatWs(Concat):
5173    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5177class ConnectByRoot(Func):
5178    pass
key = 'connectbyroot'
class Count(AggFunc):
5181class Count(AggFunc):
5182    arg_types = {"this": False, "expressions": False, "big_int": False}
5183    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5186class CountIf(AggFunc):
5187    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5191class Cbrt(Func):
5192    pass
key = 'cbrt'
class CurrentDate(Func):
5195class CurrentDate(Func):
5196    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5199class CurrentDatetime(Func):
5200    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5203class CurrentTime(Func):
5204    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5207class CurrentTimestamp(Func):
5208    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5211class CurrentUser(Func):
5212    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5215class DateAdd(Func, IntervalOp):
5216    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5219class DateSub(Func, IntervalOp):
5220    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5223class DateDiff(Func, TimeUnit):
5224    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5225    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5228class DateTrunc(Func):
5229    arg_types = {"unit": True, "this": True, "zone": False}
5230
5231    def __init__(self, **args):
5232        unit = args.get("unit")
5233        if isinstance(unit, TimeUnit.VAR_LIKE):
5234            args["unit"] = Literal.string(
5235                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5236            )
5237        elif isinstance(unit, Week):
5238            unit.set("this", Literal.string(unit.this.name.upper()))
5239
5240        super().__init__(**args)
5241
5242    @property
5243    def unit(self) -> Expression:
5244        return self.args["unit"]
DateTrunc(**args)
5231    def __init__(self, **args):
5232        unit = args.get("unit")
5233        if isinstance(unit, TimeUnit.VAR_LIKE):
5234            args["unit"] = Literal.string(
5235                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5236            )
5237        elif isinstance(unit, Week):
5238            unit.set("this", Literal.string(unit.this.name.upper()))
5239
5240        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5242    @property
5243    def unit(self) -> Expression:
5244        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5249class Datetime(Func):
5250    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5253class DatetimeAdd(Func, IntervalOp):
5254    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5257class DatetimeSub(Func, IntervalOp):
5258    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5261class DatetimeDiff(Func, TimeUnit):
5262    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5265class DatetimeTrunc(Func, TimeUnit):
5266    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5269class DayOfWeek(Func):
5270    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5275class DayOfWeekIso(Func):
5276    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5279class DayOfMonth(Func):
5280    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5283class DayOfYear(Func):
5284    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5287class ToDays(Func):
5288    pass
key = 'todays'
class WeekOfYear(Func):
5291class WeekOfYear(Func):
5292    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5295class MonthsBetween(Func):
5296    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5299class LastDay(Func, TimeUnit):
5300    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5301    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5304class Extract(Func):
5305    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5308class Timestamp(Func):
5309    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5312class TimestampAdd(Func, TimeUnit):
5313    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5316class TimestampSub(Func, TimeUnit):
5317    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5320class TimestampDiff(Func, TimeUnit):
5321    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5322    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5325class TimestampTrunc(Func, TimeUnit):
5326    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5329class TimeAdd(Func, TimeUnit):
5330    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5333class TimeSub(Func, TimeUnit):
5334    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5337class TimeDiff(Func, TimeUnit):
5338    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5341class TimeTrunc(Func, TimeUnit):
5342    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5345class DateFromParts(Func):
5346    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5347    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5350class TimeFromParts(Func):
5351    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5352    arg_types = {
5353        "hour": True,
5354        "min": True,
5355        "sec": True,
5356        "nano": False,
5357        "fractions": False,
5358        "precision": False,
5359    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5362class DateStrToDate(Func):
5363    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5366class DateToDateStr(Func):
5367    pass
key = 'datetodatestr'
class DateToDi(Func):
5370class DateToDi(Func):
5371    pass
key = 'datetodi'
class Date(Func):
5375class Date(Func):
5376    arg_types = {"this": False, "zone": False, "expressions": False}
5377    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5380class Day(Func):
5381    pass
key = 'day'
class Decode(Func):
5384class Decode(Func):
5385    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5388class DiToDate(Func):
5389    pass
key = 'ditodate'
class Encode(Func):
5392class Encode(Func):
5393    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5396class Exp(Func):
5397    pass
key = 'exp'
class Explode(Func):
5401class Explode(Func):
5402    arg_types = {"this": True, "expressions": False}
5403    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5407class Inline(Func):
5408    pass
key = 'inline'
class ExplodeOuter(Explode):
5411class ExplodeOuter(Explode):
5412    pass
key = 'explodeouter'
class Posexplode(Explode):
5415class Posexplode(Explode):
5416    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5419class PosexplodeOuter(Posexplode, ExplodeOuter):
5420    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5423class Unnest(Func, UDTF):
5424    arg_types = {
5425        "expressions": True,
5426        "alias": False,
5427        "offset": False,
5428        "explode_array": False,
5429    }
5430
5431    @property
5432    def selects(self) -> t.List[Expression]:
5433        columns = super().selects
5434        offset = self.args.get("offset")
5435        if offset:
5436            columns = columns + [to_identifier("offset") if offset is True else offset]
5437        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5431    @property
5432    def selects(self) -> t.List[Expression]:
5433        columns = super().selects
5434        offset = self.args.get("offset")
5435        if offset:
5436            columns = columns + [to_identifier("offset") if offset is True else offset]
5437        return columns
key = 'unnest'
class Floor(Func):
5440class Floor(Func):
5441    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5444class FromBase64(Func):
5445    pass
key = 'frombase64'
class ToBase64(Func):
5448class ToBase64(Func):
5449    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5453class FromISO8601Timestamp(Func):
5454    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5457class GapFill(Func):
5458    arg_types = {
5459        "this": True,
5460        "ts_column": True,
5461        "bucket_width": True,
5462        "partitioning_columns": False,
5463        "value_columns": False,
5464        "origin": False,
5465        "ignore_nulls": False,
5466    }
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):
5470class GenerateDateArray(Func):
5471    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5475class GenerateTimestampArray(Func):
5476    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5479class Greatest(Func):
5480    arg_types = {"this": True, "expressions": False}
5481    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5484class GroupConcat(AggFunc):
5485    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5488class Hex(Func):
5489    pass
key = 'hex'
class LowerHex(Hex):
5492class LowerHex(Hex):
5493    pass
key = 'lowerhex'
class Xor(Connector, Func):
5496class Xor(Connector, Func):
5497    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5500class If(Func):
5501    arg_types = {"this": True, "true": True, "false": False}
5502    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5505class Nullif(Func):
5506    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5509class Initcap(Func):
5510    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5513class IsNan(Func):
5514    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5517class IsInf(Func):
5518    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5522class JSON(Expression):
5523    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5526class JSONPath(Expression):
5527    arg_types = {"expressions": True, "escape": False}
5528
5529    @property
5530    def output_name(self) -> str:
5531        last_segment = self.expressions[-1].this
5532        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5529    @property
5530    def output_name(self) -> str:
5531        last_segment = self.expressions[-1].this
5532        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):
5535class JSONPathPart(Expression):
5536    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5539class JSONPathFilter(JSONPathPart):
5540    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5543class JSONPathKey(JSONPathPart):
5544    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5547class JSONPathRecursive(JSONPathPart):
5548    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5551class JSONPathRoot(JSONPathPart):
5552    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5555class JSONPathScript(JSONPathPart):
5556    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5559class JSONPathSlice(JSONPathPart):
5560    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5563class JSONPathSelector(JSONPathPart):
5564    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5567class JSONPathSubscript(JSONPathPart):
5568    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5571class JSONPathUnion(JSONPathPart):
5572    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5575class JSONPathWildcard(JSONPathPart):
5576    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5579class FormatJson(Expression):
5580    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5583class JSONKeyValue(Expression):
5584    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5587class JSONObject(Func):
5588    arg_types = {
5589        "expressions": False,
5590        "null_handling": False,
5591        "unique_keys": False,
5592        "return_type": False,
5593        "encoding": False,
5594    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5597class JSONObjectAgg(AggFunc):
5598    arg_types = {
5599        "expressions": False,
5600        "null_handling": False,
5601        "unique_keys": False,
5602        "return_type": False,
5603        "encoding": False,
5604    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5608class JSONArray(Func):
5609    arg_types = {
5610        "expressions": True,
5611        "null_handling": False,
5612        "return_type": False,
5613        "strict": False,
5614    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5618class JSONArrayAgg(Func):
5619    arg_types = {
5620        "this": True,
5621        "order": False,
5622        "null_handling": False,
5623        "return_type": False,
5624        "strict": False,
5625    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
5628class JSONExists(Func):
5629    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):
5634class JSONColumnDef(Expression):
5635    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):
5638class JSONSchema(Expression):
5639    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
5643class JSONValue(Expression):
5644    arg_types = {
5645        "this": True,
5646        "path": True,
5647        "returning": False,
5648        "on_condition": False,
5649    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONTable(Func):
5653class JSONTable(Func):
5654    arg_types = {
5655        "this": True,
5656        "schema": True,
5657        "path": False,
5658        "error_handling": False,
5659        "empty_handling": False,
5660    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5664class ObjectInsert(Func):
5665    arg_types = {
5666        "this": True,
5667        "key": True,
5668        "value": True,
5669        "update_flag": False,
5670    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5673class OpenJSONColumnDef(Expression):
5674    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):
5677class OpenJSON(Func):
5678    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5681class JSONBContains(Binary, Func):
5682    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5685class JSONExtract(Binary, Func):
5686    arg_types = {
5687        "this": True,
5688        "expression": True,
5689        "only_json_types": False,
5690        "expressions": False,
5691        "variant_extract": False,
5692    }
5693    _sql_names = ["JSON_EXTRACT"]
5694    is_var_len_args = True
5695
5696    @property
5697    def output_name(self) -> str:
5698        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
5696    @property
5697    def output_name(self) -> str:
5698        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):
5701class JSONExtractScalar(Binary, Func):
5702    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5703    _sql_names = ["JSON_EXTRACT_SCALAR"]
5704    is_var_len_args = True
5705
5706    @property
5707    def output_name(self) -> str:
5708        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
5706    @property
5707    def output_name(self) -> str:
5708        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):
5711class JSONBExtract(Binary, Func):
5712    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5715class JSONBExtractScalar(Binary, Func):
5716    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5719class JSONFormat(Func):
5720    arg_types = {"this": False, "options": False}
5721    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5725class JSONArrayContains(Binary, Predicate, Func):
5726    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5729class ParseJSON(Func):
5730    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5731    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5732    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5733    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5736class Least(Func):
5737    arg_types = {"this": True, "expressions": False}
5738    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5741class Left(Func):
5742    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5749class Length(Func):
5750    arg_types = {"this": True, "binary": False}
5751    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5754class Levenshtein(Func):
5755    arg_types = {
5756        "this": True,
5757        "expression": False,
5758        "ins_cost": False,
5759        "del_cost": False,
5760        "sub_cost": False,
5761    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5764class Ln(Func):
5765    pass
key = 'ln'
class Log(Func):
5768class Log(Func):
5769    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5772class LogicalOr(AggFunc):
5773    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5776class LogicalAnd(AggFunc):
5777    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5780class Lower(Func):
5781    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5784class Map(Func):
5785    arg_types = {"keys": False, "values": False}
5786
5787    @property
5788    def keys(self) -> t.List[Expression]:
5789        keys = self.args.get("keys")
5790        return keys.expressions if keys else []
5791
5792    @property
5793    def values(self) -> t.List[Expression]:
5794        values = self.args.get("values")
5795        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5787    @property
5788    def keys(self) -> t.List[Expression]:
5789        keys = self.args.get("keys")
5790        return keys.expressions if keys else []
values: List[Expression]
5792    @property
5793    def values(self) -> t.List[Expression]:
5794        values = self.args.get("values")
5795        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5799class ToMap(Func):
5800    pass
key = 'tomap'
class MapFromEntries(Func):
5803class MapFromEntries(Func):
5804    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5808class ScopeResolution(Expression):
5809    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
5812class Stream(Expression):
5813    pass
key = 'stream'
class StarMap(Func):
5816class StarMap(Func):
5817    pass
key = 'starmap'
class VarMap(Func):
5820class VarMap(Func):
5821    arg_types = {"keys": True, "values": True}
5822    is_var_len_args = True
5823
5824    @property
5825    def keys(self) -> t.List[Expression]:
5826        return self.args["keys"].expressions
5827
5828    @property
5829    def values(self) -> t.List[Expression]:
5830        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5824    @property
5825    def keys(self) -> t.List[Expression]:
5826        return self.args["keys"].expressions
values: List[Expression]
5828    @property
5829    def values(self) -> t.List[Expression]:
5830        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5834class MatchAgainst(Func):
5835    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5838class Max(AggFunc):
5839    arg_types = {"this": True, "expressions": False}
5840    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5843class MD5(Func):
5844    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5848class MD5Digest(Func):
5849    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5852class Min(AggFunc):
5853    arg_types = {"this": True, "expressions": False}
5854    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5857class Month(Func):
5858    pass
key = 'month'
class AddMonths(Func):
5861class AddMonths(Func):
5862    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5865class Nvl2(Func):
5866    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
5869class Normalize(Func):
5870    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Predict(Func):
5874class Predict(Func):
5875    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5878class Pow(Binary, Func):
5879    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5882class PercentileCont(AggFunc):
5883    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5886class PercentileDisc(AggFunc):
5887    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5890class Quantile(AggFunc):
5891    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5894class ApproxQuantile(Quantile):
5895    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):
5898class Quarter(Func):
5899    pass
key = 'quarter'
class Rand(Func):
5904class Rand(Func):
5905    _sql_names = ["RAND", "RANDOM"]
5906    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5909class Randn(Func):
5910    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5913class RangeN(Func):
5914    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5917class ReadCSV(Func):
5918    _sql_names = ["READ_CSV"]
5919    is_var_len_args = True
5920    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5923class Reduce(Func):
5924    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):
5927class RegexpExtract(Func):
5928    arg_types = {
5929        "this": True,
5930        "expression": True,
5931        "position": False,
5932        "occurrence": False,
5933        "parameters": False,
5934        "group": False,
5935    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5938class RegexpReplace(Func):
5939    arg_types = {
5940        "this": True,
5941        "expression": True,
5942        "replacement": False,
5943        "position": False,
5944        "occurrence": False,
5945        "modifiers": False,
5946    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5949class RegexpLike(Binary, Func):
5950    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5953class RegexpILike(Binary, Func):
5954    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5959class RegexpSplit(Func):
5960    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
5963class Repeat(Func):
5964    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
5969class Round(Func):
5970    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
5973class RowNumber(Func):
5974    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
5977class SafeDivide(Func):
5978    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
5981class SHA(Func):
5982    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
5985class SHA2(Func):
5986    _sql_names = ["SHA2"]
5987    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
5990class Sign(Func):
5991    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
5994class SortArray(Func):
5995    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
5998class Split(Func):
5999    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
6004class Substring(Func):
6005    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6008class StandardHash(Func):
6009    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6012class StartsWith(Func):
6013    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6014    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6017class StrPosition(Func):
6018    arg_types = {
6019        "this": True,
6020        "substr": True,
6021        "position": False,
6022        "instance": False,
6023    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
6026class StrToDate(Func):
6027    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6030class StrToTime(Func):
6031    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):
6036class StrToUnix(Func):
6037    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6042class StrToMap(Func):
6043    arg_types = {
6044        "this": True,
6045        "pair_delim": False,
6046        "key_value_delim": False,
6047        "duplicate_resolution_callback": False,
6048    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6051class NumberToStr(Func):
6052    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6055class FromBase(Func):
6056    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6059class Struct(Func):
6060    arg_types = {"expressions": False}
6061    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6064class StructExtract(Func):
6065    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6070class Stuff(Func):
6071    _sql_names = ["STUFF", "INSERT"]
6072    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):
6075class Sum(AggFunc):
6076    pass
key = 'sum'
class Sqrt(Func):
6079class Sqrt(Func):
6080    pass
key = 'sqrt'
class Stddev(AggFunc):
6083class Stddev(AggFunc):
6084    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6087class StddevPop(AggFunc):
6088    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6091class StddevSamp(AggFunc):
6092    pass
key = 'stddevsamp'
class Time(Func):
6096class Time(Func):
6097    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6100class TimeToStr(Func):
6101    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):
6104class TimeToTimeStr(Func):
6105    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6108class TimeToUnix(Func):
6109    pass
key = 'timetounix'
class TimeStrToDate(Func):
6112class TimeStrToDate(Func):
6113    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6116class TimeStrToTime(Func):
6117    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6120class TimeStrToUnix(Func):
6121    pass
key = 'timestrtounix'
class Trim(Func):
6124class Trim(Func):
6125    arg_types = {
6126        "this": True,
6127        "expression": False,
6128        "position": False,
6129        "collation": False,
6130    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6133class TsOrDsAdd(Func, TimeUnit):
6134    # return_type is used to correctly cast the arguments of this expression when transpiling it
6135    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6136
6137    @property
6138    def return_type(self) -> DataType:
6139        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
6137    @property
6138    def return_type(self) -> DataType:
6139        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6142class TsOrDsDiff(Func, TimeUnit):
6143    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6146class TsOrDsToDateStr(Func):
6147    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6150class TsOrDsToDate(Func):
6151    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6154class TsOrDsToTime(Func):
6155    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6158class TsOrDsToTimestamp(Func):
6159    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6162class TsOrDiToDi(Func):
6163    pass
key = 'tsorditodi'
class Unhex(Func):
6166class Unhex(Func):
6167    pass
key = 'unhex'
class UnixDate(Func):
6171class UnixDate(Func):
6172    pass
key = 'unixdate'
class UnixToStr(Func):
6175class UnixToStr(Func):
6176    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6181class UnixToTime(Func):
6182    arg_types = {
6183        "this": True,
6184        "scale": False,
6185        "zone": False,
6186        "hours": False,
6187        "minutes": False,
6188        "format": False,
6189    }
6190
6191    SECONDS = Literal.number(0)
6192    DECIS = Literal.number(1)
6193    CENTIS = Literal.number(2)
6194    MILLIS = Literal.number(3)
6195    DECIMILLIS = Literal.number(4)
6196    CENTIMILLIS = Literal.number(5)
6197    MICROS = Literal.number(6)
6198    DECIMICROS = Literal.number(7)
6199    CENTIMICROS = Literal.number(8)
6200    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):
6203class UnixToTimeStr(Func):
6204    pass
key = 'unixtotimestr'
class UnpackColumns(Func):
6207class UnpackColumns(Func):
6208    pass
key = 'unpackcolumns'
class Uuid(Func):
6211class Uuid(Func):
6212    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6213
6214    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6217class TimestampFromParts(Func):
6218    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6219    arg_types = {
6220        "year": True,
6221        "month": True,
6222        "day": True,
6223        "hour": True,
6224        "min": True,
6225        "sec": True,
6226        "nano": False,
6227        "zone": False,
6228        "milli": False,
6229    }
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):
6232class Upper(Func):
6233    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6236class Corr(Binary, AggFunc):
6237    pass
key = 'corr'
class Variance(AggFunc):
6240class Variance(AggFunc):
6241    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6244class VariancePop(AggFunc):
6245    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6248class CovarSamp(Binary, AggFunc):
6249    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6252class CovarPop(Binary, AggFunc):
6253    pass
key = 'covarpop'
class Week(Func):
6256class Week(Func):
6257    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6260class XMLTable(Func):
6261    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):
6264class Year(Func):
6265    pass
key = 'year'
class Use(Expression):
6268class Use(Expression):
6269    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(Expression):
6272class Merge(Expression):
6273    arg_types = {
6274        "this": True,
6275        "using": True,
6276        "on": True,
6277        "expressions": True,
6278        "with": False,
6279        "returning": False,
6280    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False, 'returning': False}
key = 'merge'
class When(Func):
6283class When(Func):
6284    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):
6289class NextValueFor(Func):
6290    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6295class Semicolon(Expression):
6296    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:
6336def maybe_parse(
6337    sql_or_expression: ExpOrStr,
6338    *,
6339    into: t.Optional[IntoType] = None,
6340    dialect: DialectType = None,
6341    prefix: t.Optional[str] = None,
6342    copy: bool = False,
6343    **opts,
6344) -> Expression:
6345    """Gracefully handle a possible string or expression.
6346
6347    Example:
6348        >>> maybe_parse("1")
6349        Literal(this=1, is_string=False)
6350        >>> maybe_parse(to_identifier("x"))
6351        Identifier(this=x, quoted=False)
6352
6353    Args:
6354        sql_or_expression: the SQL code string or an expression
6355        into: the SQLGlot Expression to parse into
6356        dialect: the dialect used to parse the input expressions (in the case that an
6357            input expression is a SQL string).
6358        prefix: a string to prefix the sql with before it gets parsed
6359            (automatically includes a space)
6360        copy: whether to copy the expression.
6361        **opts: other options to use to parse the input expressions (again, in the case
6362            that an input expression is a SQL string).
6363
6364    Returns:
6365        Expression: the parsed or given expression.
6366    """
6367    if isinstance(sql_or_expression, Expression):
6368        if copy:
6369            return sql_or_expression.copy()
6370        return sql_or_expression
6371
6372    if sql_or_expression is None:
6373        raise ParseError("SQL cannot be None")
6374
6375    import sqlglot
6376
6377    sql = str(sql_or_expression)
6378    if prefix:
6379        sql = f"{prefix} {sql}"
6380
6381    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):
6392def maybe_copy(instance, copy=True):
6393    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:
6614def union(
6615    left: ExpOrStr,
6616    right: ExpOrStr,
6617    distinct: bool = True,
6618    dialect: DialectType = None,
6619    copy: bool = True,
6620    **opts,
6621) -> Union:
6622    """
6623    Initializes a syntax tree from one UNION expression.
6624
6625    Example:
6626        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6627        'SELECT * FROM foo UNION SELECT * FROM bla'
6628
6629    Args:
6630        left: the SQL code string corresponding to the left-hand side.
6631            If an `Expression` instance is passed, it will be used as-is.
6632        right: the SQL code string corresponding to the right-hand side.
6633            If an `Expression` instance is passed, it will be used as-is.
6634        distinct: set the DISTINCT flag if and only if this is true.
6635        dialect: the dialect used to parse the input expression.
6636        copy: whether to copy the expression.
6637        opts: other options to use to parse the input expressions.
6638
6639    Returns:
6640        The new Union instance.
6641    """
6642    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6643    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6644
6645    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:
6648def intersect(
6649    left: ExpOrStr,
6650    right: ExpOrStr,
6651    distinct: bool = True,
6652    dialect: DialectType = None,
6653    copy: bool = True,
6654    **opts,
6655) -> Intersect:
6656    """
6657    Initializes a syntax tree from one INTERSECT expression.
6658
6659    Example:
6660        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6661        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6662
6663    Args:
6664        left: the SQL code string corresponding to the left-hand side.
6665            If an `Expression` instance is passed, it will be used as-is.
6666        right: the SQL code string corresponding to the right-hand side.
6667            If an `Expression` instance is passed, it will be used as-is.
6668        distinct: set the DISTINCT flag if and only if this is true.
6669        dialect: the dialect used to parse the input expression.
6670        copy: whether to copy the expression.
6671        opts: other options to use to parse the input expressions.
6672
6673    Returns:
6674        The new Intersect instance.
6675    """
6676    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6677    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6678
6679    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:
6682def except_(
6683    left: ExpOrStr,
6684    right: ExpOrStr,
6685    distinct: bool = True,
6686    dialect: DialectType = None,
6687    copy: bool = True,
6688    **opts,
6689) -> Except:
6690    """
6691    Initializes a syntax tree from one EXCEPT expression.
6692
6693    Example:
6694        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6695        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6696
6697    Args:
6698        left: the SQL code string corresponding to the left-hand side.
6699            If an `Expression` instance is passed, it will be used as-is.
6700        right: the SQL code string corresponding to the right-hand side.
6701            If an `Expression` instance is passed, it will be used as-is.
6702        distinct: set the DISTINCT flag if and only if this is true.
6703        dialect: the dialect used to parse the input expression.
6704        copy: whether to copy the expression.
6705        opts: other options to use to parse the input expressions.
6706
6707    Returns:
6708        The new Except instance.
6709    """
6710    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6711    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6712
6713    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:
6716def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6717    """
6718    Initializes a syntax tree from one or multiple SELECT expressions.
6719
6720    Example:
6721        >>> select("col1", "col2").from_("tbl").sql()
6722        'SELECT col1, col2 FROM tbl'
6723
6724    Args:
6725        *expressions: the SQL code string to parse as the expressions of a
6726            SELECT statement. If an Expression instance is passed, this is used as-is.
6727        dialect: the dialect used to parse the input expressions (in the case that an
6728            input expression is a SQL string).
6729        **opts: other options to use to parse the input expressions (again, in the case
6730            that an input expression is a SQL string).
6731
6732    Returns:
6733        Select: the syntax tree for the SELECT statement.
6734    """
6735    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:
6738def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6739    """
6740    Initializes a syntax tree from a FROM expression.
6741
6742    Example:
6743        >>> from_("tbl").select("col1", "col2").sql()
6744        'SELECT col1, col2 FROM tbl'
6745
6746    Args:
6747        *expression: the SQL code string to parse as the FROM expressions of a
6748            SELECT statement. If an Expression instance is passed, this is used as-is.
6749        dialect: the dialect used to parse the input expression (in the case that the
6750            input expression is a SQL string).
6751        **opts: other options to use to parse the input expressions (again, in the case
6752            that the input expression is a SQL string).
6753
6754    Returns:
6755        Select: the syntax tree for the SELECT statement.
6756    """
6757    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:
6760def update(
6761    table: str | Table,
6762    properties: dict,
6763    where: t.Optional[ExpOrStr] = None,
6764    from_: t.Optional[ExpOrStr] = None,
6765    dialect: DialectType = None,
6766    **opts,
6767) -> Update:
6768    """
6769    Creates an update statement.
6770
6771    Example:
6772        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6773        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6774
6775    Args:
6776        *properties: dictionary of properties to set which are
6777            auto converted to sql objects eg None -> NULL
6778        where: sql conditional parsed into a WHERE statement
6779        from_: sql statement parsed into a FROM statement
6780        dialect: the dialect used to parse the input expressions.
6781        **opts: other options to use to parse the input expressions.
6782
6783    Returns:
6784        Update: the syntax tree for the UPDATE statement.
6785    """
6786    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6787    update_expr.set(
6788        "expressions",
6789        [
6790            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6791            for k, v in properties.items()
6792        ],
6793    )
6794    if from_:
6795        update_expr.set(
6796            "from",
6797            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6798        )
6799    if isinstance(where, Condition):
6800        where = Where(this=where)
6801    if where:
6802        update_expr.set(
6803            "where",
6804            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6805        )
6806    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:
6809def delete(
6810    table: ExpOrStr,
6811    where: t.Optional[ExpOrStr] = None,
6812    returning: t.Optional[ExpOrStr] = None,
6813    dialect: DialectType = None,
6814    **opts,
6815) -> Delete:
6816    """
6817    Builds a delete statement.
6818
6819    Example:
6820        >>> delete("my_table", where="id > 1").sql()
6821        'DELETE FROM my_table WHERE id > 1'
6822
6823    Args:
6824        where: sql conditional parsed into a WHERE statement
6825        returning: sql conditional parsed into a RETURNING statement
6826        dialect: the dialect used to parse the input expressions.
6827        **opts: other options to use to parse the input expressions.
6828
6829    Returns:
6830        Delete: the syntax tree for the DELETE statement.
6831    """
6832    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6833    if where:
6834        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6835    if returning:
6836        delete_expr = t.cast(
6837            Delete, delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6838        )
6839    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:
6842def insert(
6843    expression: ExpOrStr,
6844    into: ExpOrStr,
6845    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6846    overwrite: t.Optional[bool] = None,
6847    returning: t.Optional[ExpOrStr] = None,
6848    dialect: DialectType = None,
6849    copy: bool = True,
6850    **opts,
6851) -> Insert:
6852    """
6853    Builds an INSERT statement.
6854
6855    Example:
6856        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6857        'INSERT INTO tbl VALUES (1, 2, 3)'
6858
6859    Args:
6860        expression: the sql string or expression of the INSERT statement
6861        into: the tbl to insert data to.
6862        columns: optionally the table's column names.
6863        overwrite: whether to INSERT OVERWRITE or not.
6864        returning: sql conditional parsed into a RETURNING statement
6865        dialect: the dialect used to parse the input expressions.
6866        copy: whether to copy the expression.
6867        **opts: other options to use to parse the input expressions.
6868
6869    Returns:
6870        Insert: the syntax tree for the INSERT statement.
6871    """
6872    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6873    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6874
6875    if columns:
6876        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6877
6878    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6879
6880    if returning:
6881        insert = t.cast(Insert, insert.returning(returning, dialect=dialect, copy=False, **opts))
6882
6883    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], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
6886def merge(
6887    *when_exprs: ExpOrStr,
6888    into: ExpOrStr,
6889    using: ExpOrStr,
6890    on: ExpOrStr,
6891    dialect: DialectType = None,
6892    copy: bool = True,
6893    **opts,
6894) -> Merge:
6895    """
6896    Builds a MERGE statement.
6897
6898    Example:
6899        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
6900        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
6901        ...       into="my_table",
6902        ...       using="source_table",
6903        ...       on="my_table.id = source_table.id").sql()
6904        '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)'
6905
6906    Args:
6907        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
6908        into: The target table to merge data into.
6909        using: The source table to merge data from.
6910        on: The join condition for the merge.
6911        dialect: The dialect used to parse the input expressions.
6912        copy: Whether to copy the expression.
6913        **opts: Other options to use to parse the input expressions.
6914
6915    Returns:
6916        Merge: The syntax tree for the MERGE statement.
6917    """
6918    return Merge(
6919        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
6920        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
6921        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
6922        expressions=[
6923            maybe_parse(when_expr, dialect=dialect, copy=copy, into=When, **opts)
6924            for when_expr in when_exprs
6925        ],
6926    )

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.
  • 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:
6929def condition(
6930    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6931) -> Condition:
6932    """
6933    Initialize a logical condition expression.
6934
6935    Example:
6936        >>> condition("x=1").sql()
6937        'x = 1'
6938
6939        This is helpful for composing larger logical syntax trees:
6940        >>> where = condition("x=1")
6941        >>> where = where.and_("y=1")
6942        >>> Select().from_("tbl").select("*").where(where).sql()
6943        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6944
6945    Args:
6946        *expression: the SQL code string to parse.
6947            If an Expression instance is passed, this is used as-is.
6948        dialect: the dialect used to parse the input expression (in the case that the
6949            input expression is a SQL string).
6950        copy: Whether to copy `expression` (only applies to expressions).
6951        **opts: other options to use to parse the input expressions (again, in the case
6952            that the input expression is a SQL string).
6953
6954    Returns:
6955        The new Condition instance
6956    """
6957    return maybe_parse(
6958        expression,
6959        into=Condition,
6960        dialect=dialect,
6961        copy=copy,
6962        **opts,
6963    )

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:
6966def and_(
6967    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6968) -> Condition:
6969    """
6970    Combine multiple conditions with an AND logical operator.
6971
6972    Example:
6973        >>> and_("x=1", and_("y=1", "z=1")).sql()
6974        'x = 1 AND (y = 1 AND z = 1)'
6975
6976    Args:
6977        *expressions: the SQL code strings to parse.
6978            If an Expression instance is passed, this is used as-is.
6979        dialect: the dialect used to parse the input expression.
6980        copy: whether to copy `expressions` (only applies to Expressions).
6981        **opts: other options to use to parse the input expressions.
6982
6983    Returns:
6984        The new condition
6985    """
6986    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:
6989def or_(
6990    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
6991) -> Condition:
6992    """
6993    Combine multiple conditions with an OR logical operator.
6994
6995    Example:
6996        >>> or_("x=1", or_("y=1", "z=1")).sql()
6997        'x = 1 OR (y = 1 OR z = 1)'
6998
6999    Args:
7000        *expressions: the SQL code strings to parse.
7001            If an Expression instance is passed, this is used as-is.
7002        dialect: the dialect used to parse the input expression.
7003        copy: whether to copy `expressions` (only applies to Expressions).
7004        **opts: other options to use to parse the input expressions.
7005
7006    Returns:
7007        The new condition
7008    """
7009    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:
7012def xor(
7013    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7014) -> Condition:
7015    """
7016    Combine multiple conditions with an XOR logical operator.
7017
7018    Example:
7019        >>> xor("x=1", xor("y=1", "z=1")).sql()
7020        'x = 1 XOR (y = 1 XOR z = 1)'
7021
7022    Args:
7023        *expressions: the SQL code strings to parse.
7024            If an Expression instance is passed, this is used as-is.
7025        dialect: the dialect used to parse the input expression.
7026        copy: whether to copy `expressions` (only applies to Expressions).
7027        **opts: other options to use to parse the input expressions.
7028
7029    Returns:
7030        The new condition
7031    """
7032    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:
7035def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7036    """
7037    Wrap a condition with a NOT operator.
7038
7039    Example:
7040        >>> not_("this_suit='black'").sql()
7041        "NOT this_suit = 'black'"
7042
7043    Args:
7044        expression: the SQL code string 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 the expression or not.
7048        **opts: other options to use to parse the input expressions.
7049
7050    Returns:
7051        The new condition.
7052    """
7053    this = condition(
7054        expression,
7055        dialect=dialect,
7056        copy=copy,
7057        **opts,
7058    )
7059    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:
7062def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7063    """
7064    Wrap an expression in parentheses.
7065
7066    Example:
7067        >>> paren("5 + 3").sql()
7068        '(5 + 3)'
7069
7070    Args:
7071        expression: the SQL code string to parse.
7072            If an Expression instance is passed, this is used as-is.
7073        copy: whether to copy the expression or not.
7074
7075    Returns:
7076        The wrapped expression.
7077    """
7078    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):
7094def to_identifier(name, quoted=None, copy=True):
7095    """Builds an identifier.
7096
7097    Args:
7098        name: The name to turn into an identifier.
7099        quoted: Whether to force quote the identifier.
7100        copy: Whether to copy name if it's an Identifier.
7101
7102    Returns:
7103        The identifier ast node.
7104    """
7105
7106    if name is None:
7107        return None
7108
7109    if isinstance(name, Identifier):
7110        identifier = maybe_copy(name, copy)
7111    elif isinstance(name, str):
7112        identifier = Identifier(
7113            this=name,
7114            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7115        )
7116    else:
7117        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7118    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:
7121def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7122    """
7123    Parses a given string into an identifier.
7124
7125    Args:
7126        name: The name to parse into an identifier.
7127        dialect: The dialect to parse against.
7128
7129    Returns:
7130        The identifier ast node.
7131    """
7132    try:
7133        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7134    except (ParseError, TokenError):
7135        expression = to_identifier(name)
7136
7137    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:
7143def to_interval(interval: str | Literal) -> Interval:
7144    """Builds an interval expression from a string like '1 day' or '5 months'."""
7145    if isinstance(interval, Literal):
7146        if not interval.is_string:
7147            raise ValueError("Invalid interval string.")
7148
7149        interval = interval.this
7150
7151    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
7152
7153    if not interval_parts:
7154        raise ValueError("Invalid interval string.")
7155
7156    return Interval(
7157        this=Literal.string(interval_parts.group(1)),
7158        unit=Var(this=interval_parts.group(2).upper()),
7159    )

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

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:
7458def values(
7459    values: t.Iterable[t.Tuple[t.Any, ...]],
7460    alias: t.Optional[str] = None,
7461    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7462) -> Values:
7463    """Build VALUES statement.
7464
7465    Example:
7466        >>> values([(1, '2')]).sql()
7467        "VALUES (1, '2')"
7468
7469    Args:
7470        values: values statements that will be converted to SQL
7471        alias: optional alias
7472        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7473         If either are provided then an alias is also required.
7474
7475    Returns:
7476        Values: the Values expression object
7477    """
7478    if columns and not alias:
7479        raise ValueError("Alias is required when providing columns")
7480
7481    return Values(
7482        expressions=[convert(tup) for tup in values],
7483        alias=(
7484            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7485            if columns
7486            else (TableAlias(this=to_identifier(alias)) if alias else None)
7487        ),
7488    )

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:
7491def var(name: t.Optional[ExpOrStr]) -> Var:
7492    """Build a SQL variable.
7493
7494    Example:
7495        >>> repr(var('x'))
7496        'Var(this=x)'
7497
7498        >>> repr(var(column('x', table='y')))
7499        'Var(this=x)'
7500
7501    Args:
7502        name: The name of the var or an expression who's name will become the var.
7503
7504    Returns:
7505        The new variable node.
7506    """
7507    if not name:
7508        raise ValueError("Cannot convert empty name into var.")
7509
7510    if isinstance(name, Expression):
7511        name = name.name
7512    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:
7515def rename_table(
7516    old_name: str | Table,
7517    new_name: str | Table,
7518    dialect: DialectType = None,
7519) -> Alter:
7520    """Build ALTER TABLE... RENAME... expression
7521
7522    Args:
7523        old_name: The old name of the table
7524        new_name: The new name of the table
7525        dialect: The dialect to parse the table.
7526
7527    Returns:
7528        Alter table expression
7529    """
7530    old_table = to_table(old_name, dialect=dialect)
7531    new_table = to_table(new_name, dialect=dialect)
7532    return Alter(
7533        this=old_table,
7534        kind="TABLE",
7535        actions=[
7536            RenameTable(this=new_table),
7537        ],
7538    )

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:
7541def rename_column(
7542    table_name: str | Table,
7543    old_column_name: str | Column,
7544    new_column_name: str | Column,
7545    exists: t.Optional[bool] = None,
7546    dialect: DialectType = None,
7547) -> Alter:
7548    """Build ALTER TABLE... RENAME COLUMN... expression
7549
7550    Args:
7551        table_name: Name of the table
7552        old_column: The old name of the column
7553        new_column: The new name of the column
7554        exists: Whether to add the `IF EXISTS` clause
7555        dialect: The dialect to parse the table/column.
7556
7557    Returns:
7558        Alter table expression
7559    """
7560    table = to_table(table_name, dialect=dialect)
7561    old_column = to_column(old_column_name, dialect=dialect)
7562    new_column = to_column(new_column_name, dialect=dialect)
7563    return Alter(
7564        this=table,
7565        kind="TABLE",
7566        actions=[
7567            RenameColumn(this=old_column, to=new_column, exists=exists),
7568        ],
7569    )

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

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:
7706def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7707    """Get the full name of a table as a string.
7708
7709    Args:
7710        table: Table expression node or string.
7711        dialect: The dialect to generate the table name for.
7712        identify: Determines when an identifier should be quoted. Possible values are:
7713            False (default): Never quote, except in cases where it's mandatory by the dialect.
7714            True: Always quote.
7715
7716    Examples:
7717        >>> from sqlglot import exp, parse_one
7718        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7719        'a.b.c'
7720
7721    Returns:
7722        The table name.
7723    """
7724
7725    table = maybe_parse(table, into=Table, dialect=dialect)
7726
7727    if not table:
7728        raise ValueError(f"Cannot parse {table}")
7729
7730    return ".".join(
7731        (
7732            part.sql(dialect=dialect, identify=True, copy=False)
7733            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7734            else part.name
7735        )
7736        for part in table.parts
7737    )

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:
7740def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7741    """Returns a case normalized table name without quotes.
7742
7743    Args:
7744        table: the table to normalize
7745        dialect: the dialect to use for normalization rules
7746        copy: whether to copy the expression.
7747
7748    Examples:
7749        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7750        'A-B.c'
7751    """
7752    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7753
7754    return ".".join(
7755        p.name
7756        for p in normalize_identifiers(
7757            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7758        ).parts
7759    )

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

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:
7989def tuple_(
7990    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
7991) -> Tuple:
7992    """
7993    Returns an tuple.
7994
7995    Examples:
7996        >>> tuple_(1, 'x').sql()
7997        '(1, x)'
7998
7999    Args:
8000        expressions: the expressions to add to the tuple.
8001        copy: whether to copy the argument expressions.
8002        dialect: the source dialect.
8003        kwargs: the kwargs used to instantiate the function of interest.
8004
8005    Returns:
8006        A tuple expression.
8007    """
8008    return Tuple(
8009        expressions=[
8010            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8011            for expression in expressions
8012        ]
8013    )

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:
8016def true() -> Boolean:
8017    """
8018    Returns a true Boolean expression.
8019    """
8020    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8023def false() -> Boolean:
8024    """
8025    Returns a false Boolean expression.
8026    """
8027    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8030def null() -> Null:
8031    """
8032    Returns a Null expression.
8033    """
8034    return Null()

Returns a Null expression.

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