Edit on GitHub

Expressions

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

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


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

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

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

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

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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

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

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

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

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is an integer.

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

Checks whether an expression is a star.

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

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

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

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

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

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

Returns a deep copy of the expression.

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

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

Arguments:
  • arg_key (str): name of the list expression arg
  • value (Any): value to append to the list
def set( self, arg_key: str, value: Any, index: Optional[int] = None, overwrite: bool = True) -> None:
340    def set(
341        self,
342        arg_key: str,
343        value: t.Any,
344        index: t.Optional[int] = None,
345        overwrite: bool = True,
346    ) -> None:
347        """
348        Sets arg_key to value.
349
350        Args:
351            arg_key: name of the expression arg.
352            value: value to set the arg to.
353            index: if the arg is a list, this specifies what position to add the value in it.
354            overwrite: assuming an index is given, this determines whether to overwrite the
355                list entry instead of only inserting a new value (i.e., like list.insert).
356        """
357        if index is not None:
358            expressions = self.args.get(arg_key) or []
359
360            if seq_get(expressions, index) is None:
361                return
362            if value is None:
363                expressions.pop(index)
364                for v in expressions[index:]:
365                    v.index = v.index - 1
366                return
367
368            if isinstance(value, list):
369                expressions.pop(index)
370                expressions[index:index] = value
371            elif overwrite:
372                expressions[index] = value
373            else:
374                expressions.insert(index, value)
375
376            value = expressions
377        elif value is None:
378            self.args.pop(arg_key, None)
379            return
380
381        self.args[arg_key] = value
382        self._set_parent(arg_key, value, index)

Sets arg_key to value.

Arguments:
  • arg_key: name of the expression arg.
  • value: value to set the arg to.
  • index: if the arg is a list, this specifies what position to add the value in it.
  • overwrite: assuming an index is given, this determines whether to overwrite the list entry instead of only inserting a new value (i.e., like list.insert).
depth: int
396    @property
397    def depth(self) -> int:
398        """
399        Returns the depth of this tree.
400        """
401        if self.parent:
402            return self.parent.depth + 1
403        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
405    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
406        """Yields the key and expression for all arguments, exploding list args."""
407        # remove tuple when python 3.7 is deprecated
408        for vs in reversed(tuple(self.args.values())) if reverse else self.args.values():
409            if type(vs) is list:
410                for v in reversed(vs) if reverse else vs:
411                    if hasattr(v, "parent"):
412                        yield v
413            else:
414                if hasattr(vs, "parent"):
415                    yield vs

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

def find(self, *expression_types: Type[~E], bfs: bool = True) -> Optional[~E]:
417    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
418        """
419        Returns the first node in this tree which matches at least one of
420        the specified types.
421
422        Args:
423            expression_types: the expression type(s) to match.
424            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
425
426        Returns:
427            The node which matches the criteria or None if no such node was found.
428        """
429        return next(self.find_all(*expression_types, bfs=bfs), None)

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

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

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

def find_all(self, *expression_types: Type[~E], bfs: bool = True) -> Iterator[~E]:
431    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
432        """
433        Returns a generator object which visits all nodes in this tree and only
434        yields those that match at least one of the specified expression types.
435
436        Args:
437            expression_types: the expression type(s) to match.
438            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
439
440        Returns:
441            The generator object.
442        """
443        for expression in self.walk(bfs=bfs):
444            if isinstance(expression, expression_types):
445                yield expression

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

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

The generator object.

def find_ancestor(self, *expression_types: Type[~E]) -> Optional[~E]:
447    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
448        """
449        Returns a nearest parent matching expression_types.
450
451        Args:
452            expression_types: the expression type(s) to match.
453
454        Returns:
455            The parent node.
456        """
457        ancestor = self.parent
458        while ancestor and not isinstance(ancestor, expression_types):
459            ancestor = ancestor.parent
460        return ancestor  # type: ignore

Returns a nearest parent matching expression_types.

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

The parent node.

parent_select: Optional[Select]
462    @property
463    def parent_select(self) -> t.Optional[Select]:
464        """
465        Returns the parent select statement.
466        """
467        return self.find_ancestor(Select)

Returns the parent select statement.

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

Returns if the parent is the same class as itself.

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

Returns the root expression of this tree.

def walk( self, bfs: bool = True, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
483    def walk(
484        self, bfs: bool = True, prune: t.Optional[t.Callable[[Expression], bool]] = None
485    ) -> t.Iterator[Expression]:
486        """
487        Returns a generator object which visits all nodes in this tree.
488
489        Args:
490            bfs: if set to True the BFS traversal order will be applied,
491                otherwise the DFS traversal will be used instead.
492            prune: callable that returns True if the generator should stop traversing
493                this branch of the tree.
494
495        Returns:
496            the generator object.
497        """
498        if bfs:
499            yield from self.bfs(prune=prune)
500        else:
501            yield from self.dfs(prune=prune)

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

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

the generator object.

def dfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
503    def dfs(
504        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
505    ) -> t.Iterator[Expression]:
506        """
507        Returns a generator object which visits all nodes in this tree in
508        the DFS (Depth-first) order.
509
510        Returns:
511            The generator object.
512        """
513        stack = [self]
514
515        while stack:
516            node = stack.pop()
517
518            yield node
519
520            if prune and prune(node):
521                continue
522
523            for v in node.iter_expressions(reverse=True):
524                stack.append(v)

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

Returns:

The generator object.

def bfs( self, prune: Optional[Callable[[Expression], bool]] = None) -> Iterator[Expression]:
526    def bfs(
527        self, prune: t.Optional[t.Callable[[Expression], bool]] = None
528    ) -> t.Iterator[Expression]:
529        """
530        Returns a generator object which visits all nodes in this tree in
531        the BFS (Breadth-first) order.
532
533        Returns:
534            The generator object.
535        """
536        queue = deque([self])
537
538        while queue:
539            node = queue.popleft()
540
541            yield node
542
543            if prune and prune(node):
544                continue
545
546            for v in node.iter_expressions():
547                queue.append(v)

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

Returns:

The generator object.

def unnest(self):
549    def unnest(self):
550        """
551        Returns the first non parenthesis child or self.
552        """
553        expression = self
554        while type(expression) is Paren:
555            expression = expression.this
556        return expression

Returns the first non parenthesis child or self.

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

Returns the inner expression if this is an Alias.

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

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
572    def flatten(self, unnest=True):
573        """
574        Returns a generator which yields child nodes whose parents are the same class.
575
576        A AND B AND C -> [A, B, C]
577        """
578        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
579            if type(node) is not self.__class__:
580                yield node.unnest() if unnest and not isinstance(node, Subquery) else node

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

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

def to_s(self) -> str:
588    def to_s(self) -> str:
589        """
590        Same as __repr__, but includes additional information which can be useful
591        for debugging, like empty or missing args and the AST nodes' object IDs.
592        """
593        return _to_s(self, verbose=True)

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

def sql( self, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> str:
595    def sql(self, dialect: DialectType = None, **opts) -> str:
596        """
597        Returns SQL string representation of this tree.
598
599        Args:
600            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
601            opts: other `sqlglot.generator.Generator` options.
602
603        Returns:
604            The SQL string.
605        """
606        from sqlglot.dialects import Dialect
607
608        return Dialect.get_or_raise(dialect).generate(self, **opts)

Returns SQL string representation of this tree.

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

The SQL string.

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

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

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

The transformed tree.

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

Swap out this expression with a new expression.

For example::

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

The new expression or expressions.

def pop(self: ~E) -> ~E:
687    def pop(self: E) -> E:
688        """
689        Remove this expression from its AST.
690
691        Returns:
692            The popped expression.
693        """
694        self.replace(None)
695        return self

Remove this expression from its AST.

Returns:

The popped expression.

def assert_is(self, type_: Type[~E]) -> ~E:
697    def assert_is(self, type_: t.Type[E]) -> E:
698        """
699        Assert that this `Expression` is an instance of `type_`.
700
701        If it is NOT an instance of `type_`, this raises an assertion error.
702        Otherwise, this returns this expression.
703
704        Examples:
705            This is useful for type security in chained expressions:
706
707            >>> import sqlglot
708            >>> sqlglot.parse_one("SELECT x from y").assert_is(Select).select("z").sql()
709            'SELECT x, z FROM y'
710        """
711        if not isinstance(self, type_):
712            raise AssertionError(f"{self} is not {type_}.")
713        return self

Assert that this Expression is an instance of type_.

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

Examples:

This is useful for type security in chained expressions:

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

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

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

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

def dump(self):
749    def dump(self):
750        """
751        Dump this Expression to a JSON-serializable dict.
752        """
753        from sqlglot.serde import dump
754
755        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
757    @classmethod
758    def load(cls, obj):
759        """
760        Load a dict (as returned by `Expression.dump`) into an Expression instance.
761        """
762        from sqlglot.serde import load
763
764        return load(obj)

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

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

AND this condition with one or multiple expressions.

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

The new And condition.

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

OR this condition with one or multiple expressions.

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

The new Or condition.

def not_(self, copy: bool = True):
818    def not_(self, copy: bool = True):
819        """
820        Wrap this condition with NOT.
821
822        Example:
823            >>> condition("x=1").not_().sql()
824            'NOT x = 1'
825
826        Args:
827            copy: whether to copy this object.
828
829        Returns:
830            The new Not instance.
831        """
832        return not_(self, copy=copy)

Wrap this condition with NOT.

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

The new Not instance.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
834    def as_(
835        self,
836        alias: str | Identifier,
837        quoted: t.Optional[bool] = None,
838        dialect: DialectType = None,
839        copy: bool = True,
840        **opts,
841    ) -> Alias:
842        return alias_(self, alias, quoted=quoted, dialect=dialect, copy=copy, **opts)
def isin( self, *expressions: Any, query: Union[str, Expression, NoneType] = None, unnest: Union[str, Expression, NoneType, Collection[Union[str, Expression]]] = None, copy: bool = True, **opts) -> In:
867    def isin(
868        self,
869        *expressions: t.Any,
870        query: t.Optional[ExpOrStr] = None,
871        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
872        copy: bool = True,
873        **opts,
874    ) -> In:
875        subquery = maybe_parse(query, copy=copy, **opts) if query else None
876        if subquery and not isinstance(subquery, Subquery):
877            subquery = subquery.subquery(copy=False)
878
879        return In(
880            this=maybe_copy(self, copy),
881            expressions=[convert(e, copy=copy) for e in expressions],
882            query=subquery,
883            unnest=(
884                Unnest(
885                    expressions=[
886                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
887                        for e in ensure_list(unnest)
888                    ]
889                )
890                if unnest
891                else None
892            ),
893        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
895    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
896        return Between(
897            this=maybe_copy(self, copy),
898            low=convert(low, copy=copy, **opts),
899            high=convert(high, copy=copy, **opts),
900        )
def is_( self, other: Union[str, Expression]) -> Is:
902    def is_(self, other: ExpOrStr) -> Is:
903        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
905    def like(self, other: ExpOrStr) -> Like:
906        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
908    def ilike(self, other: ExpOrStr) -> ILike:
909        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
911    def eq(self, other: t.Any) -> EQ:
912        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
914    def neq(self, other: t.Any) -> NEQ:
915        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
917    def rlike(self, other: ExpOrStr) -> RegexpLike:
918        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
920    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
921        div = self._binop(Div, other)
922        div.args["typed"] = typed
923        div.args["safe"] = safe
924        return div
def asc(self, nulls_first: bool = True) -> Ordered:
926    def asc(self, nulls_first: bool = True) -> Ordered:
927        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
929    def desc(self, nulls_first: bool = False) -> Ordered:
930        return Ordered(this=self.copy(), desc=True, nulls_first=nulls_first)
IntoType = typing.Union[str, typing.Type[Expression], typing.Collection[typing.Union[str, typing.Type[Expression]]]]
ExpOrStr = typing.Union[str, Expression]
class Condition(Expression):
1013class Condition(Expression):
1014    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

Returns a Subquery that wraps around this query.

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

Adds a LIMIT clause to this query.

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

A limited Select expression.

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

Set the OFFSET expression.

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

The modified Select expression.

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

Set the ORDER BY expression.

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

The modified Select expression.

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

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

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

Returns the query's projections.

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

Returns the output names of the query's projections.

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

Append to or set the SELECT expressions.

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

The modified Query expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1204    def with_(
1205        self: Q,
1206        alias: ExpOrStr,
1207        as_: ExpOrStr,
1208        recursive: t.Optional[bool] = None,
1209        materialized: t.Optional[bool] = None,
1210        append: bool = True,
1211        dialect: DialectType = None,
1212        copy: bool = True,
1213        **opts,
1214    ) -> Q:
1215        """
1216        Append to or set the common table expressions.
1217
1218        Example:
1219            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1220            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1221
1222        Args:
1223            alias: the SQL code string to parse as the table name.
1224                If an `Expression` instance is passed, this is used as-is.
1225            as_: the SQL code string to parse as the table expression.
1226                If an `Expression` instance is passed, it will be used as-is.
1227            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1228            materialized: set the MATERIALIZED part of the expression.
1229            append: if `True`, add to any existing expressions.
1230                Otherwise, this resets the expressions.
1231            dialect: the dialect used to parse the input expression.
1232            copy: if `False`, modify this expression instance in-place.
1233            opts: other options to use to parse the input expressions.
1234
1235        Returns:
1236            The modified expression.
1237        """
1238        return _apply_cte_builder(
1239            self,
1240            alias,
1241            as_,
1242            recursive=recursive,
1243            materialized=materialized,
1244            append=append,
1245            dialect=dialect,
1246            copy=copy,
1247            **opts,
1248        )

Append to or set the common table expressions.

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

The modified expression.

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

Builds a UNION expression.

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

The new Union expression.

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

Builds an INTERSECT expression.

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

The new Intersect expression.

def except_( self, expression: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Except:
1296    def except_(
1297        self, expression: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1298    ) -> Except:
1299        """
1300        Builds an EXCEPT expression.
1301
1302        Example:
1303            >>> import sqlglot
1304            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1305            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1306
1307        Args:
1308            expression: the SQL code string.
1309                If an `Expression` instance is passed, it will be used as-is.
1310            distinct: set the DISTINCT flag if and only if this is true.
1311            dialect: the dialect used to parse the input expression.
1312            opts: other options to use to parse the input expressions.
1313
1314        Returns:
1315            The new Except expression.
1316        """
1317        return except_(left=self, right=expression, distinct=distinct, dialect=dialect, **opts)

Builds an EXCEPT expression.

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

The new Except expression.

key = 'query'
class UDTF(DerivedTable):
1320class UDTF(DerivedTable):
1321    @property
1322    def selects(self) -> t.List[Expression]:
1323        alias = self.args.get("alias")
1324        return alias.columns if alias else []
selects: List[Expression]
1321    @property
1322    def selects(self) -> t.List[Expression]:
1323        alias = self.args.get("alias")
1324        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1327class Cache(Expression):
1328    arg_types = {
1329        "this": True,
1330        "lazy": False,
1331        "options": False,
1332        "expression": False,
1333    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1336class Uncache(Expression):
1337    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1340class Refresh(Expression):
1341    pass
key = 'refresh'
class DDL(Expression):
1344class DDL(Expression):
1345    @property
1346    def ctes(self) -> t.List[CTE]:
1347        """Returns a list of all the CTEs attached to this statement."""
1348        with_ = self.args.get("with")
1349        return with_.expressions if with_ else []
1350
1351    @property
1352    def selects(self) -> t.List[Expression]:
1353        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1354        return self.expression.selects if isinstance(self.expression, Query) else []
1355
1356    @property
1357    def named_selects(self) -> t.List[str]:
1358        """
1359        If this statement contains a query (e.g. a CTAS), this returns the output
1360        names of the query's projections.
1361        """
1362        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1345    @property
1346    def ctes(self) -> t.List[CTE]:
1347        """Returns a list of all the CTEs attached to this statement."""
1348        with_ = self.args.get("with")
1349        return with_.expressions if with_ else []

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

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

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

named_selects: List[str]
1356    @property
1357    def named_selects(self) -> t.List[str]:
1358        """
1359        If this statement contains a query (e.g. a CTAS), this returns the output
1360        names of the query's projections.
1361        """
1362        return self.expression.named_selects if isinstance(self.expression, Query) else []

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

key = 'ddl'
class DML(Expression):
1365class DML(Expression):
1366    def returning(
1367        self,
1368        expression: ExpOrStr,
1369        dialect: DialectType = None,
1370        copy: bool = True,
1371        **opts,
1372    ) -> "Self":
1373        """
1374        Set the RETURNING expression. Not supported by all dialects.
1375
1376        Example:
1377            >>> delete("tbl").returning("*", dialect="postgres").sql()
1378            'DELETE FROM tbl RETURNING *'
1379
1380        Args:
1381            expression: the SQL code strings to parse.
1382                If an `Expression` instance is passed, it will be used as-is.
1383            dialect: the dialect used to parse the input expressions.
1384            copy: if `False`, modify this expression instance in-place.
1385            opts: other options to use to parse the input expressions.
1386
1387        Returns:
1388            Delete: the modified expression.
1389        """
1390        return _apply_builder(
1391            expression=expression,
1392            instance=self,
1393            arg="returning",
1394            prefix="RETURNING",
1395            dialect=dialect,
1396            copy=copy,
1397            into=Returning,
1398            **opts,
1399        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> typing_extensions.Self:
1366    def returning(
1367        self,
1368        expression: ExpOrStr,
1369        dialect: DialectType = None,
1370        copy: bool = True,
1371        **opts,
1372    ) -> "Self":
1373        """
1374        Set the RETURNING expression. Not supported by all dialects.
1375
1376        Example:
1377            >>> delete("tbl").returning("*", dialect="postgres").sql()
1378            'DELETE FROM tbl RETURNING *'
1379
1380        Args:
1381            expression: the SQL code strings to parse.
1382                If an `Expression` instance is passed, it will be used as-is.
1383            dialect: the dialect used to parse the input expressions.
1384            copy: if `False`, modify this expression instance in-place.
1385            opts: other options to use to parse the input expressions.
1386
1387        Returns:
1388            Delete: the modified expression.
1389        """
1390        return _apply_builder(
1391            expression=expression,
1392            instance=self,
1393            arg="returning",
1394            prefix="RETURNING",
1395            dialect=dialect,
1396            copy=copy,
1397            into=Returning,
1398            **opts,
1399        )

Set the RETURNING expression. Not supported by all dialects.

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

Delete: the modified expression.

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

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
parts: List[Identifier]
1617    @property
1618    def parts(self) -> t.List[Identifier]:
1619        """Return the parts of a column in order catalog, db, table, name."""
1620        return [
1621            t.cast(Identifier, self.args[part])
1622            for part in ("catalog", "db", "table", "this")
1623            if self.args.get(part)
1624        ]

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

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

Converts the column into a dot expression.

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

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

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

Delete: the modified expression.

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

Append to or set the WHERE expressions.

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

Delete: the modified expression.

key = 'delete'
class Drop(Expression):
2018class Drop(Expression):
2019    arg_types = {
2020        "this": False,
2021        "kind": False,
2022        "expressions": False,
2023        "exists": False,
2024        "temporary": False,
2025        "materialized": False,
2026        "cascade": False,
2027        "constraints": False,
2028        "purge": False,
2029        "cluster": False,
2030        "concurrently": False,
2031    }
2032
2033    @property
2034    def kind(self) -> t.Optional[str]:
2035        kind = self.args.get("kind")
2036        return kind and kind.upper()
arg_types = {'this': False, 'kind': False, 'expressions': False, 'exists': False, 'temporary': False, 'materialized': False, 'cascade': False, 'constraints': False, 'purge': False, 'cluster': False, 'concurrently': False}
kind: Optional[str]
2033    @property
2034    def kind(self) -> t.Optional[str]:
2035        kind = self.args.get("kind")
2036        return kind and kind.upper()
key = 'drop'
class Filter(Expression):
2039class Filter(Expression):
2040    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2043class Check(Expression):
2044    pass
key = 'check'
class Changes(Expression):
2047class Changes(Expression):
2048    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2052class Connect(Expression):
2053    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2056class CopyParameter(Expression):
2057    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2060class Copy(DML):
2061    arg_types = {
2062        "this": True,
2063        "kind": True,
2064        "files": True,
2065        "credentials": False,
2066        "format": False,
2067        "params": False,
2068    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2071class Credentials(Expression):
2072    arg_types = {
2073        "credentials": False,
2074        "encryption": False,
2075        "storage": False,
2076        "iam_role": False,
2077        "region": False,
2078    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2081class Prior(Expression):
2082    pass
key = 'prior'
class Directory(Expression):
2085class Directory(Expression):
2086    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2087    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2090class ForeignKey(Expression):
2091    arg_types = {
2092        "expressions": True,
2093        "reference": False,
2094        "delete": False,
2095        "update": False,
2096    }
arg_types = {'expressions': True, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2099class ColumnPrefix(Expression):
2100    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2103class PrimaryKey(Expression):
2104    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2109class Into(Expression):
2110    arg_types = {"this": True, "temporary": False, "unlogged": False}
arg_types = {'this': True, 'temporary': False, 'unlogged': False}
key = 'into'
class From(Expression):
2113class From(Expression):
2114    @property
2115    def name(self) -> str:
2116        return self.this.name
2117
2118    @property
2119    def alias_or_name(self) -> str:
2120        return self.this.alias_or_name
name: str
2114    @property
2115    def name(self) -> str:
2116        return self.this.name
alias_or_name: str
2118    @property
2119    def alias_or_name(self) -> str:
2120        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2123class Having(Expression):
2124    pass
key = 'having'
class Hint(Expression):
2127class Hint(Expression):
2128    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2131class JoinHint(Expression):
2132    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2135class Identifier(Expression):
2136    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2137
2138    @property
2139    def quoted(self) -> bool:
2140        return bool(self.args.get("quoted"))
2141
2142    @property
2143    def hashable_args(self) -> t.Any:
2144        return (self.this, self.quoted)
2145
2146    @property
2147    def output_name(self) -> str:
2148        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2138    @property
2139    def quoted(self) -> bool:
2140        return bool(self.args.get("quoted"))
hashable_args: Any
2142    @property
2143    def hashable_args(self) -> t.Any:
2144        return (self.this, self.quoted)
output_name: str
2146    @property
2147    def output_name(self) -> str:
2148        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
key = 'identifier'
class Opclass(Expression):
2152class Opclass(Expression):
2153    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2156class Index(Expression):
2157    arg_types = {
2158        "this": False,
2159        "table": False,
2160        "unique": False,
2161        "primary": False,
2162        "amp": False,  # teradata
2163        "params": False,
2164    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2167class IndexParameters(Expression):
2168    arg_types = {
2169        "using": False,
2170        "include": False,
2171        "columns": False,
2172        "with_storage": False,
2173        "partition_by": False,
2174        "tablespace": False,
2175        "where": False,
2176        "on": False,
2177    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False, 'on': False}
key = 'indexparameters'
class Insert(DDL, DML):
2180class Insert(DDL, DML):
2181    arg_types = {
2182        "hint": False,
2183        "with": False,
2184        "is_function": False,
2185        "this": False,
2186        "expression": False,
2187        "conflict": False,
2188        "returning": False,
2189        "overwrite": False,
2190        "exists": False,
2191        "alternative": False,
2192        "where": False,
2193        "ignore": False,
2194        "by_name": False,
2195        "stored": False,
2196        "partition": False,
2197        "settings": False,
2198        "source": False,
2199    }
2200
2201    def with_(
2202        self,
2203        alias: ExpOrStr,
2204        as_: ExpOrStr,
2205        recursive: t.Optional[bool] = None,
2206        materialized: t.Optional[bool] = None,
2207        append: bool = True,
2208        dialect: DialectType = None,
2209        copy: bool = True,
2210        **opts,
2211    ) -> Insert:
2212        """
2213        Append to or set the common table expressions.
2214
2215        Example:
2216            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2217            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2218
2219        Args:
2220            alias: the SQL code string to parse as the table name.
2221                If an `Expression` instance is passed, this is used as-is.
2222            as_: the SQL code string to parse as the table expression.
2223                If an `Expression` instance is passed, it will be used as-is.
2224            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2225            materialized: set the MATERIALIZED part of the expression.
2226            append: if `True`, add to any existing expressions.
2227                Otherwise, this resets the expressions.
2228            dialect: the dialect used to parse the input expression.
2229            copy: if `False`, modify this expression instance in-place.
2230            opts: other options to use to parse the input expressions.
2231
2232        Returns:
2233            The modified expression.
2234        """
2235        return _apply_cte_builder(
2236            self,
2237            alias,
2238            as_,
2239            recursive=recursive,
2240            materialized=materialized,
2241            append=append,
2242            dialect=dialect,
2243            copy=copy,
2244            **opts,
2245        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False, 'partition': False, 'settings': False, 'source': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2201    def with_(
2202        self,
2203        alias: ExpOrStr,
2204        as_: ExpOrStr,
2205        recursive: t.Optional[bool] = None,
2206        materialized: t.Optional[bool] = None,
2207        append: bool = True,
2208        dialect: DialectType = None,
2209        copy: bool = True,
2210        **opts,
2211    ) -> Insert:
2212        """
2213        Append to or set the common table expressions.
2214
2215        Example:
2216            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2217            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2218
2219        Args:
2220            alias: the SQL code string to parse as the table name.
2221                If an `Expression` instance is passed, this is used as-is.
2222            as_: the SQL code string to parse as the table expression.
2223                If an `Expression` instance is passed, it will be used as-is.
2224            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2225            materialized: set the MATERIALIZED part of the expression.
2226            append: if `True`, add to any existing expressions.
2227                Otherwise, this resets the expressions.
2228            dialect: the dialect used to parse the input expression.
2229            copy: if `False`, modify this expression instance in-place.
2230            opts: other options to use to parse the input expressions.
2231
2232        Returns:
2233            The modified expression.
2234        """
2235        return _apply_cte_builder(
2236            self,
2237            alias,
2238            as_,
2239            recursive=recursive,
2240            materialized=materialized,
2241            append=append,
2242            dialect=dialect,
2243            copy=copy,
2244            **opts,
2245        )

Append to or set the common table expressions.

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

The modified expression.

key = 'insert'
class ConditionalInsert(Expression):
2248class ConditionalInsert(Expression):
2249    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2252class MultitableInserts(Expression):
2253    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2256class OnConflict(Expression):
2257    arg_types = {
2258        "duplicate": False,
2259        "expressions": False,
2260        "action": False,
2261        "conflict_keys": False,
2262        "constraint": False,
2263    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class OnCondition(Expression):
2266class OnCondition(Expression):
2267    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2270class Returning(Expression):
2271    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2275class Introducer(Expression):
2276    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2280class National(Expression):
2281    pass
key = 'national'
class LoadData(Expression):
2284class LoadData(Expression):
2285    arg_types = {
2286        "this": True,
2287        "local": False,
2288        "overwrite": False,
2289        "inpath": True,
2290        "partition": False,
2291        "input_format": False,
2292        "serde": False,
2293    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2296class Partition(Expression):
2297    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2300class PartitionRange(Expression):
2301    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2305class PartitionId(Expression):
2306    pass
key = 'partitionid'
class Fetch(Expression):
2309class Fetch(Expression):
2310    arg_types = {
2311        "direction": False,
2312        "count": False,
2313        "percent": False,
2314        "with_ties": False,
2315    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Grant(Expression):
2318class Grant(Expression):
2319    arg_types = {
2320        "privileges": True,
2321        "kind": False,
2322        "securable": True,
2323        "principals": True,
2324        "grant_option": False,
2325    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2328class Group(Expression):
2329    arg_types = {
2330        "expressions": False,
2331        "grouping_sets": False,
2332        "cube": False,
2333        "rollup": False,
2334        "totals": False,
2335        "all": False,
2336    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2339class Cube(Expression):
2340    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2343class Rollup(Expression):
2344    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2347class GroupingSets(Expression):
2348    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2351class Lambda(Expression):
2352    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2355class Limit(Expression):
2356    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):
2359class Literal(Condition):
2360    arg_types = {"this": True, "is_string": True}
2361
2362    @property
2363    def hashable_args(self) -> t.Any:
2364        return (self.this, self.args.get("is_string"))
2365
2366    @classmethod
2367    def number(cls, number) -> Literal:
2368        return cls(this=str(number), is_string=False)
2369
2370    @classmethod
2371    def string(cls, string) -> Literal:
2372        return cls(this=str(string), is_string=True)
2373
2374    @property
2375    def output_name(self) -> str:
2376        return self.name
2377
2378    def to_py(self) -> int | str | Decimal:
2379        if self.is_number:
2380            try:
2381                return int(self.this)
2382            except ValueError:
2383                return Decimal(self.this)
2384        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2362    @property
2363    def hashable_args(self) -> t.Any:
2364        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2366    @classmethod
2367    def number(cls, number) -> Literal:
2368        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2370    @classmethod
2371    def string(cls, string) -> Literal:
2372        return cls(this=str(string), is_string=True)
output_name: str
2374    @property
2375    def output_name(self) -> str:
2376        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:
2378    def to_py(self) -> int | str | Decimal:
2379        if self.is_number:
2380            try:
2381                return int(self.this)
2382            except ValueError:
2383                return Decimal(self.this)
2384        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2387class Join(Expression):
2388    arg_types = {
2389        "this": True,
2390        "on": False,
2391        "side": False,
2392        "kind": False,
2393        "using": False,
2394        "method": False,
2395        "global": False,
2396        "hint": False,
2397        "match_condition": False,  # Snowflake
2398    }
2399
2400    @property
2401    def method(self) -> str:
2402        return self.text("method").upper()
2403
2404    @property
2405    def kind(self) -> str:
2406        return self.text("kind").upper()
2407
2408    @property
2409    def side(self) -> str:
2410        return self.text("side").upper()
2411
2412    @property
2413    def hint(self) -> str:
2414        return self.text("hint").upper()
2415
2416    @property
2417    def alias_or_name(self) -> str:
2418        return self.this.alias_or_name
2419
2420    def on(
2421        self,
2422        *expressions: t.Optional[ExpOrStr],
2423        append: bool = True,
2424        dialect: DialectType = None,
2425        copy: bool = True,
2426        **opts,
2427    ) -> Join:
2428        """
2429        Append to or set the ON expressions.
2430
2431        Example:
2432            >>> import sqlglot
2433            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2434            'JOIN x ON y = 1'
2435
2436        Args:
2437            *expressions: the SQL code strings to parse.
2438                If an `Expression` instance is passed, it will be used as-is.
2439                Multiple expressions are combined with an AND operator.
2440            append: if `True`, AND the new expressions to any existing expression.
2441                Otherwise, this resets the expression.
2442            dialect: the dialect used to parse the input expressions.
2443            copy: if `False`, modify this expression instance in-place.
2444            opts: other options to use to parse the input expressions.
2445
2446        Returns:
2447            The modified Join expression.
2448        """
2449        join = _apply_conjunction_builder(
2450            *expressions,
2451            instance=self,
2452            arg="on",
2453            append=append,
2454            dialect=dialect,
2455            copy=copy,
2456            **opts,
2457        )
2458
2459        if join.kind == "CROSS":
2460            join.set("kind", None)
2461
2462        return join
2463
2464    def using(
2465        self,
2466        *expressions: t.Optional[ExpOrStr],
2467        append: bool = True,
2468        dialect: DialectType = None,
2469        copy: bool = True,
2470        **opts,
2471    ) -> Join:
2472        """
2473        Append to or set the USING expressions.
2474
2475        Example:
2476            >>> import sqlglot
2477            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2478            'JOIN x USING (foo, bla)'
2479
2480        Args:
2481            *expressions: the SQL code strings to parse.
2482                If an `Expression` instance is passed, it will be used as-is.
2483            append: if `True`, concatenate the new expressions to the existing "using" list.
2484                Otherwise, this resets the expression.
2485            dialect: the dialect used to parse the input expressions.
2486            copy: if `False`, modify this expression instance in-place.
2487            opts: other options to use to parse the input expressions.
2488
2489        Returns:
2490            The modified Join expression.
2491        """
2492        join = _apply_list_builder(
2493            *expressions,
2494            instance=self,
2495            arg="using",
2496            append=append,
2497            dialect=dialect,
2498            copy=copy,
2499            **opts,
2500        )
2501
2502        if join.kind == "CROSS":
2503            join.set("kind", None)
2504
2505        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
2400    @property
2401    def method(self) -> str:
2402        return self.text("method").upper()
kind: str
2404    @property
2405    def kind(self) -> str:
2406        return self.text("kind").upper()
side: str
2408    @property
2409    def side(self) -> str:
2410        return self.text("side").upper()
hint: str
2412    @property
2413    def hint(self) -> str:
2414        return self.text("hint").upper()
alias_or_name: str
2416    @property
2417    def alias_or_name(self) -> str:
2418        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:
2420    def on(
2421        self,
2422        *expressions: t.Optional[ExpOrStr],
2423        append: bool = True,
2424        dialect: DialectType = None,
2425        copy: bool = True,
2426        **opts,
2427    ) -> Join:
2428        """
2429        Append to or set the ON expressions.
2430
2431        Example:
2432            >>> import sqlglot
2433            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2434            'JOIN x ON y = 1'
2435
2436        Args:
2437            *expressions: the SQL code strings to parse.
2438                If an `Expression` instance is passed, it will be used as-is.
2439                Multiple expressions are combined with an AND operator.
2440            append: if `True`, AND the new expressions to any existing expression.
2441                Otherwise, this resets the expression.
2442            dialect: the dialect used to parse the input expressions.
2443            copy: if `False`, modify this expression instance in-place.
2444            opts: other options to use to parse the input expressions.
2445
2446        Returns:
2447            The modified Join expression.
2448        """
2449        join = _apply_conjunction_builder(
2450            *expressions,
2451            instance=self,
2452            arg="on",
2453            append=append,
2454            dialect=dialect,
2455            copy=copy,
2456            **opts,
2457        )
2458
2459        if join.kind == "CROSS":
2460            join.set("kind", None)
2461
2462        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:
2464    def using(
2465        self,
2466        *expressions: t.Optional[ExpOrStr],
2467        append: bool = True,
2468        dialect: DialectType = None,
2469        copy: bool = True,
2470        **opts,
2471    ) -> Join:
2472        """
2473        Append to or set the USING expressions.
2474
2475        Example:
2476            >>> import sqlglot
2477            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2478            'JOIN x USING (foo, bla)'
2479
2480        Args:
2481            *expressions: the SQL code strings to parse.
2482                If an `Expression` instance is passed, it will be used as-is.
2483            append: if `True`, concatenate the new expressions to the existing "using" list.
2484                Otherwise, this resets the expression.
2485            dialect: the dialect used to parse the input expressions.
2486            copy: if `False`, modify this expression instance in-place.
2487            opts: other options to use to parse the input expressions.
2488
2489        Returns:
2490            The modified Join expression.
2491        """
2492        join = _apply_list_builder(
2493            *expressions,
2494            instance=self,
2495            arg="using",
2496            append=append,
2497            dialect=dialect,
2498            copy=copy,
2499            **opts,
2500        )
2501
2502        if join.kind == "CROSS":
2503            join.set("kind", None)
2504
2505        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):
2508class Lateral(UDTF):
2509    arg_types = {
2510        "this": True,
2511        "view": False,
2512        "outer": False,
2513        "alias": False,
2514        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2515    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2518class MatchRecognizeMeasure(Expression):
2519    arg_types = {
2520        "this": True,
2521        "window_frame": False,
2522    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2525class MatchRecognize(Expression):
2526    arg_types = {
2527        "partition_by": False,
2528        "order": False,
2529        "measures": False,
2530        "rows": False,
2531        "after": False,
2532        "pattern": False,
2533        "define": False,
2534        "alias": False,
2535    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2540class Final(Expression):
2541    pass
key = 'final'
class Offset(Expression):
2544class Offset(Expression):
2545    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2548class Order(Expression):
2549    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2553class WithFill(Expression):
2554    arg_types = {
2555        "from": False,
2556        "to": False,
2557        "step": False,
2558        "interpolate": False,
2559    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2564class Cluster(Order):
2565    pass
key = 'cluster'
class Distribute(Order):
2568class Distribute(Order):
2569    pass
key = 'distribute'
class Sort(Order):
2572class Sort(Order):
2573    pass
key = 'sort'
class Ordered(Expression):
2576class Ordered(Expression):
2577    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):
2580class Property(Expression):
2581    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2584class GrantPrivilege(Expression):
2585    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2588class GrantPrincipal(Expression):
2589    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2592class AllowedValuesProperty(Expression):
2593    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2596class AlgorithmProperty(Property):
2597    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2600class AutoIncrementProperty(Property):
2601    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2605class AutoRefreshProperty(Property):
2606    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2609class BackupProperty(Property):
2610    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2613class BlockCompressionProperty(Property):
2614    arg_types = {
2615        "autotemp": False,
2616        "always": False,
2617        "default": False,
2618        "manual": False,
2619        "never": False,
2620    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2623class CharacterSetProperty(Property):
2624    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2627class ChecksumProperty(Property):
2628    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2631class CollateProperty(Property):
2632    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2635class CopyGrantsProperty(Property):
2636    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2639class DataBlocksizeProperty(Property):
2640    arg_types = {
2641        "size": False,
2642        "units": False,
2643        "minimum": False,
2644        "maximum": False,
2645        "default": False,
2646    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2649class DataDeletionProperty(Property):
2650    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):
2653class DefinerProperty(Property):
2654    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2657class DistKeyProperty(Property):
2658    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2663class DistributedByProperty(Property):
2664    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):
2667class DistStyleProperty(Property):
2668    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2671class DuplicateKeyProperty(Property):
2672    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2675class EngineProperty(Property):
2676    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2679class HeapProperty(Property):
2680    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2683class ToTableProperty(Property):
2684    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2687class ExecuteAsProperty(Property):
2688    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2691class ExternalProperty(Property):
2692    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2695class FallbackProperty(Property):
2696    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2699class FileFormatProperty(Property):
2700    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2703class FreespaceProperty(Property):
2704    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2707class GlobalProperty(Property):
2708    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2711class IcebergProperty(Property):
2712    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2715class InheritsProperty(Property):
2716    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2719class InputModelProperty(Property):
2720    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2723class OutputModelProperty(Property):
2724    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2727class IsolatedLoadingProperty(Property):
2728    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2731class JournalProperty(Property):
2732    arg_types = {
2733        "no": False,
2734        "dual": False,
2735        "before": False,
2736        "local": False,
2737        "after": False,
2738    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2741class LanguageProperty(Property):
2742    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2746class ClusteredByProperty(Property):
2747    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2750class DictProperty(Property):
2751    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2754class DictSubProperty(Property):
2755    pass
key = 'dictsubproperty'
class DictRange(Property):
2758class DictRange(Property):
2759    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2762class DynamicProperty(Property):
2763    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2768class OnCluster(Property):
2769    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2773class EmptyProperty(Property):
2774    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2777class LikeProperty(Property):
2778    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2781class LocationProperty(Property):
2782    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2785class LockProperty(Property):
2786    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2789class LockingProperty(Property):
2790    arg_types = {
2791        "this": False,
2792        "kind": True,
2793        "for_or_in": False,
2794        "lock_type": True,
2795        "override": False,
2796    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2799class LogProperty(Property):
2800    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2803class MaterializedProperty(Property):
2804    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2807class MergeBlockRatioProperty(Property):
2808    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):
2811class NoPrimaryIndexProperty(Property):
2812    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2815class OnProperty(Property):
2816    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2819class OnCommitProperty(Property):
2820    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2823class PartitionedByProperty(Property):
2824    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2828class PartitionBoundSpec(Expression):
2829    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2830    arg_types = {
2831        "this": False,
2832        "expression": False,
2833        "from_expressions": False,
2834        "to_expressions": False,
2835    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2838class PartitionedOfProperty(Property):
2839    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2840    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2843class StreamingTableProperty(Property):
2844    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2847class RemoteWithConnectionModelProperty(Property):
2848    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2851class ReturnsProperty(Property):
2852    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):
2855class StrictProperty(Property):
2856    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2859class RowFormatProperty(Property):
2860    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2863class RowFormatDelimitedProperty(Property):
2864    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2865    arg_types = {
2866        "fields": False,
2867        "escaped": False,
2868        "collection_items": False,
2869        "map_keys": False,
2870        "lines": False,
2871        "null": False,
2872        "serde": False,
2873    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2876class RowFormatSerdeProperty(Property):
2877    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2881class QueryTransform(Expression):
2882    arg_types = {
2883        "expressions": True,
2884        "command_script": True,
2885        "schema": False,
2886        "row_format_before": False,
2887        "record_writer": False,
2888        "row_format_after": False,
2889        "record_reader": False,
2890    }
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):
2893class SampleProperty(Property):
2894    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2898class SecurityProperty(Property):
2899    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2902class SchemaCommentProperty(Property):
2903    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2906class SerdeProperties(Property):
2907    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2910class SetProperty(Property):
2911    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2914class SharingProperty(Property):
2915    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2918class SetConfigProperty(Property):
2919    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2922class SettingsProperty(Property):
2923    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2926class SortKeyProperty(Property):
2927    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2930class SqlReadWriteProperty(Property):
2931    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2934class SqlSecurityProperty(Property):
2935    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2938class StabilityProperty(Property):
2939    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2942class TemporaryProperty(Property):
2943    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2946class SecureProperty(Property):
2947    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2950class TransformModelProperty(Property):
2951    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2954class TransientProperty(Property):
2955    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2958class UnloggedProperty(Property):
2959    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2963class ViewAttributeProperty(Property):
2964    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2967class VolatileProperty(Property):
2968    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2971class WithDataProperty(Property):
2972    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2975class WithJournalTableProperty(Property):
2976    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2979class WithSchemaBindingProperty(Property):
2980    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2983class WithSystemVersioningProperty(Property):
2984    arg_types = {
2985        "on": False,
2986        "this": False,
2987        "data_consistency": False,
2988        "retention_period": False,
2989        "with": True,
2990    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2993class Properties(Expression):
2994    arg_types = {"expressions": True}
2995
2996    NAME_TO_PROPERTY = {
2997        "ALGORITHM": AlgorithmProperty,
2998        "AUTO_INCREMENT": AutoIncrementProperty,
2999        "CHARACTER SET": CharacterSetProperty,
3000        "CLUSTERED_BY": ClusteredByProperty,
3001        "COLLATE": CollateProperty,
3002        "COMMENT": SchemaCommentProperty,
3003        "DEFINER": DefinerProperty,
3004        "DISTKEY": DistKeyProperty,
3005        "DISTRIBUTED_BY": DistributedByProperty,
3006        "DISTSTYLE": DistStyleProperty,
3007        "ENGINE": EngineProperty,
3008        "EXECUTE AS": ExecuteAsProperty,
3009        "FORMAT": FileFormatProperty,
3010        "LANGUAGE": LanguageProperty,
3011        "LOCATION": LocationProperty,
3012        "LOCK": LockProperty,
3013        "PARTITIONED_BY": PartitionedByProperty,
3014        "RETURNS": ReturnsProperty,
3015        "ROW_FORMAT": RowFormatProperty,
3016        "SORTKEY": SortKeyProperty,
3017    }
3018
3019    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3020
3021    # CREATE property locations
3022    # Form: schema specified
3023    #   create [POST_CREATE]
3024    #     table a [POST_NAME]
3025    #     (b int) [POST_SCHEMA]
3026    #     with ([POST_WITH])
3027    #     index (b) [POST_INDEX]
3028    #
3029    # Form: alias selection
3030    #   create [POST_CREATE]
3031    #     table a [POST_NAME]
3032    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3033    #     index (c) [POST_INDEX]
3034    class Location(AutoName):
3035        POST_CREATE = auto()
3036        POST_NAME = auto()
3037        POST_SCHEMA = auto()
3038        POST_WITH = auto()
3039        POST_ALIAS = auto()
3040        POST_EXPRESSION = auto()
3041        POST_INDEX = auto()
3042        UNSUPPORTED = auto()
3043
3044    @classmethod
3045    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3046        expressions = []
3047        for key, value in properties_dict.items():
3048            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3049            if property_cls:
3050                expressions.append(property_cls(this=convert(value)))
3051            else:
3052                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3053
3054        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:
3044    @classmethod
3045    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3046        expressions = []
3047        for key, value in properties_dict.items():
3048            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3049            if property_cls:
3050                expressions.append(property_cls(this=convert(value)))
3051            else:
3052                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3053
3054        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3034    class Location(AutoName):
3035        POST_CREATE = auto()
3036        POST_NAME = auto()
3037        POST_SCHEMA = auto()
3038        POST_WITH = auto()
3039        POST_ALIAS = auto()
3040        POST_EXPRESSION = auto()
3041        POST_INDEX = auto()
3042        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):
3057class Qualify(Expression):
3058    pass
key = 'qualify'
class InputOutputFormat(Expression):
3061class InputOutputFormat(Expression):
3062    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3066class Return(Expression):
3067    pass
key = 'return'
class Reference(Expression):
3070class Reference(Expression):
3071    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3074class Tuple(Expression):
3075    arg_types = {"expressions": False}
3076
3077    def isin(
3078        self,
3079        *expressions: t.Any,
3080        query: t.Optional[ExpOrStr] = None,
3081        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3082        copy: bool = True,
3083        **opts,
3084    ) -> In:
3085        return In(
3086            this=maybe_copy(self, copy),
3087            expressions=[convert(e, copy=copy) for e in expressions],
3088            query=maybe_parse(query, copy=copy, **opts) if query else None,
3089            unnest=(
3090                Unnest(
3091                    expressions=[
3092                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3093                        for e in ensure_list(unnest)
3094                    ]
3095                )
3096                if unnest
3097                else None
3098            ),
3099        )
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:
3077    def isin(
3078        self,
3079        *expressions: t.Any,
3080        query: t.Optional[ExpOrStr] = None,
3081        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3082        copy: bool = True,
3083        **opts,
3084    ) -> In:
3085        return In(
3086            this=maybe_copy(self, copy),
3087            expressions=[convert(e, copy=copy) for e in expressions],
3088            query=maybe_parse(query, copy=copy, **opts) if query else None,
3089            unnest=(
3090                Unnest(
3091                    expressions=[
3092                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3093                        for e in ensure_list(unnest)
3094                    ]
3095                )
3096                if unnest
3097                else None
3098            ),
3099        )
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):
3130class QueryOption(Expression):
3131    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3135class WithTableHint(Expression):
3136    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3140class IndexTableHint(Expression):
3141    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3145class HistoricalData(Expression):
3146    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3149class Table(Expression):
3150    arg_types = {
3151        "this": False,
3152        "alias": False,
3153        "db": False,
3154        "catalog": False,
3155        "laterals": False,
3156        "joins": False,
3157        "pivots": False,
3158        "hints": False,
3159        "system_time": False,
3160        "version": False,
3161        "format": False,
3162        "pattern": False,
3163        "ordinality": False,
3164        "when": False,
3165        "only": False,
3166        "partition": False,
3167        "changes": False,
3168        "rows_from": False,
3169        "sample": False,
3170    }
3171
3172    @property
3173    def name(self) -> str:
3174        if isinstance(self.this, Func):
3175            return ""
3176        return self.this.name
3177
3178    @property
3179    def db(self) -> str:
3180        return self.text("db")
3181
3182    @property
3183    def catalog(self) -> str:
3184        return self.text("catalog")
3185
3186    @property
3187    def selects(self) -> t.List[Expression]:
3188        return []
3189
3190    @property
3191    def named_selects(self) -> t.List[str]:
3192        return []
3193
3194    @property
3195    def parts(self) -> t.List[Expression]:
3196        """Return the parts of a table in order catalog, db, table."""
3197        parts: t.List[Expression] = []
3198
3199        for arg in ("catalog", "db", "this"):
3200            part = self.args.get(arg)
3201
3202            if isinstance(part, Dot):
3203                parts.extend(part.flatten())
3204            elif isinstance(part, Expression):
3205                parts.append(part)
3206
3207        return parts
3208
3209    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3210        parts = self.parts
3211        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3212        alias = self.args.get("alias")
3213        if alias:
3214            col = alias_(col, alias.this, copy=copy)
3215        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
3172    @property
3173    def name(self) -> str:
3174        if isinstance(self.this, Func):
3175            return ""
3176        return self.this.name
db: str
3178    @property
3179    def db(self) -> str:
3180        return self.text("db")
catalog: str
3182    @property
3183    def catalog(self) -> str:
3184        return self.text("catalog")
selects: List[Expression]
3186    @property
3187    def selects(self) -> t.List[Expression]:
3188        return []
named_selects: List[str]
3190    @property
3191    def named_selects(self) -> t.List[str]:
3192        return []
parts: List[Expression]
3194    @property
3195    def parts(self) -> t.List[Expression]:
3196        """Return the parts of a table in order catalog, db, table."""
3197        parts: t.List[Expression] = []
3198
3199        for arg in ("catalog", "db", "this"):
3200            part = self.args.get(arg)
3201
3202            if isinstance(part, Dot):
3203                parts.extend(part.flatten())
3204            elif isinstance(part, Expression):
3205                parts.append(part)
3206
3207        return parts

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

def to_column( self, copy: bool = True) -> Alias | Column | Dot:
3209    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3210        parts = self.parts
3211        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3212        alias = self.args.get("alias")
3213        if alias:
3214            col = alias_(col, alias.this, copy=copy)
3215        return col
key = 'table'
class SetOperation(Query):
3218class SetOperation(Query):
3219    arg_types = {
3220        "with": False,
3221        "this": True,
3222        "expression": True,
3223        "distinct": False,
3224        "by_name": False,
3225        **QUERY_MODIFIERS,
3226    }
3227
3228    def select(
3229        self: S,
3230        *expressions: t.Optional[ExpOrStr],
3231        append: bool = True,
3232        dialect: DialectType = None,
3233        copy: bool = True,
3234        **opts,
3235    ) -> S:
3236        this = maybe_copy(self, copy)
3237        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3238        this.expression.unnest().select(
3239            *expressions, append=append, dialect=dialect, copy=False, **opts
3240        )
3241        return this
3242
3243    @property
3244    def named_selects(self) -> t.List[str]:
3245        return self.this.unnest().named_selects
3246
3247    @property
3248    def is_star(self) -> bool:
3249        return self.this.is_star or self.expression.is_star
3250
3251    @property
3252    def selects(self) -> t.List[Expression]:
3253        return self.this.unnest().selects
3254
3255    @property
3256    def left(self) -> Query:
3257        return self.this
3258
3259    @property
3260    def right(self) -> Query:
3261        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:
3228    def select(
3229        self: S,
3230        *expressions: t.Optional[ExpOrStr],
3231        append: bool = True,
3232        dialect: DialectType = None,
3233        copy: bool = True,
3234        **opts,
3235    ) -> S:
3236        this = maybe_copy(self, copy)
3237        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3238        this.expression.unnest().select(
3239            *expressions, append=append, dialect=dialect, copy=False, **opts
3240        )
3241        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]
3243    @property
3244    def named_selects(self) -> t.List[str]:
3245        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3247    @property
3248    def is_star(self) -> bool:
3249        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3251    @property
3252    def selects(self) -> t.List[Expression]:
3253        return self.this.unnest().selects

Returns the query's projections.

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

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:
3365    def group_by(
3366        self,
3367        *expressions: t.Optional[ExpOrStr],
3368        append: bool = True,
3369        dialect: DialectType = None,
3370        copy: bool = True,
3371        **opts,
3372    ) -> Select:
3373        """
3374        Set the GROUP BY expression.
3375
3376        Example:
3377            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3378            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3379
3380        Args:
3381            *expressions: the SQL code strings to parse.
3382                If a `Group` instance is passed, this is used as-is.
3383                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3384                If nothing is passed in then a group by is not applied to the expression
3385            append: if `True`, add to any existing expressions.
3386                Otherwise, this flattens all the `Group` expression into a single expression.
3387            dialect: the dialect used to parse the input expression.
3388            copy: if `False`, modify this expression instance in-place.
3389            opts: other options to use to parse the input expressions.
3390
3391        Returns:
3392            The modified Select expression.
3393        """
3394        if not expressions:
3395            return self if not copy else self.copy()
3396
3397        return _apply_child_list_builder(
3398            *expressions,
3399            instance=self,
3400            arg="group",
3401            append=append,
3402            copy=copy,
3403            prefix="GROUP BY",
3404            into=Group,
3405            dialect=dialect,
3406            **opts,
3407        )

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:
3409    def sort_by(
3410        self,
3411        *expressions: t.Optional[ExpOrStr],
3412        append: bool = True,
3413        dialect: DialectType = None,
3414        copy: bool = True,
3415        **opts,
3416    ) -> Select:
3417        """
3418        Set the SORT BY expression.
3419
3420        Example:
3421            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3422            'SELECT x FROM tbl SORT BY x DESC'
3423
3424        Args:
3425            *expressions: the SQL code strings to parse.
3426                If a `Group` instance is passed, this is used as-is.
3427                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3428            append: if `True`, add to any existing expressions.
3429                Otherwise, this flattens all the `Order` expression into a single expression.
3430            dialect: the dialect used to parse the input expression.
3431            copy: if `False`, modify this expression instance in-place.
3432            opts: other options to use to parse the input expressions.
3433
3434        Returns:
3435            The modified Select expression.
3436        """
3437        return _apply_child_list_builder(
3438            *expressions,
3439            instance=self,
3440            arg="sort",
3441            append=append,
3442            copy=copy,
3443            prefix="SORT BY",
3444            into=Sort,
3445            dialect=dialect,
3446            **opts,
3447        )

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:
3449    def cluster_by(
3450        self,
3451        *expressions: t.Optional[ExpOrStr],
3452        append: bool = True,
3453        dialect: DialectType = None,
3454        copy: bool = True,
3455        **opts,
3456    ) -> Select:
3457        """
3458        Set the CLUSTER BY expression.
3459
3460        Example:
3461            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3462            'SELECT x FROM tbl CLUSTER BY x DESC'
3463
3464        Args:
3465            *expressions: the SQL code strings to parse.
3466                If a `Group` instance is passed, this is used as-is.
3467                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3468            append: if `True`, add to any existing expressions.
3469                Otherwise, this flattens all the `Order` expression into a single expression.
3470            dialect: the dialect used to parse the input expression.
3471            copy: if `False`, modify this expression instance in-place.
3472            opts: other options to use to parse the input expressions.
3473
3474        Returns:
3475            The modified Select expression.
3476        """
3477        return _apply_child_list_builder(
3478            *expressions,
3479            instance=self,
3480            arg="cluster",
3481            append=append,
3482            copy=copy,
3483            prefix="CLUSTER BY",
3484            into=Cluster,
3485            dialect=dialect,
3486            **opts,
3487        )

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:
3489    def select(
3490        self,
3491        *expressions: t.Optional[ExpOrStr],
3492        append: bool = True,
3493        dialect: DialectType = None,
3494        copy: bool = True,
3495        **opts,
3496    ) -> Select:
3497        return _apply_list_builder(
3498            *expressions,
3499            instance=self,
3500            arg="expressions",
3501            append=append,
3502            dialect=dialect,
3503            into=Expression,
3504            copy=copy,
3505            **opts,
3506        )

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:
3508    def lateral(
3509        self,
3510        *expressions: t.Optional[ExpOrStr],
3511        append: bool = True,
3512        dialect: DialectType = None,
3513        copy: bool = True,
3514        **opts,
3515    ) -> Select:
3516        """
3517        Append to or set the LATERAL expressions.
3518
3519        Example:
3520            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3521            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3522
3523        Args:
3524            *expressions: the SQL code strings to parse.
3525                If an `Expression` instance is passed, it will be used as-is.
3526            append: if `True`, add to any existing expressions.
3527                Otherwise, this resets the expressions.
3528            dialect: the dialect used to parse the input expressions.
3529            copy: if `False`, modify this expression instance in-place.
3530            opts: other options to use to parse the input expressions.
3531
3532        Returns:
3533            The modified Select expression.
3534        """
3535        return _apply_list_builder(
3536            *expressions,
3537            instance=self,
3538            arg="laterals",
3539            append=append,
3540            into=Lateral,
3541            prefix="LATERAL VIEW",
3542            dialect=dialect,
3543            copy=copy,
3544            **opts,
3545        )

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

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:
3645    def where(
3646        self,
3647        *expressions: t.Optional[ExpOrStr],
3648        append: bool = True,
3649        dialect: DialectType = None,
3650        copy: bool = True,
3651        **opts,
3652    ) -> Select:
3653        """
3654        Append to or set the WHERE expressions.
3655
3656        Example:
3657            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3658            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3659
3660        Args:
3661            *expressions: the SQL code strings to parse.
3662                If an `Expression` instance is passed, it will be used as-is.
3663                Multiple expressions are combined with an AND operator.
3664            append: if `True`, AND the new expressions to any existing expression.
3665                Otherwise, this resets the expression.
3666            dialect: the dialect used to parse the input expressions.
3667            copy: if `False`, modify this expression instance in-place.
3668            opts: other options to use to parse the input expressions.
3669
3670        Returns:
3671            Select: the modified expression.
3672        """
3673        return _apply_conjunction_builder(
3674            *expressions,
3675            instance=self,
3676            arg="where",
3677            append=append,
3678            into=Where,
3679            dialect=dialect,
3680            copy=copy,
3681            **opts,
3682        )

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:
3684    def having(
3685        self,
3686        *expressions: t.Optional[ExpOrStr],
3687        append: bool = True,
3688        dialect: DialectType = None,
3689        copy: bool = True,
3690        **opts,
3691    ) -> Select:
3692        """
3693        Append to or set the HAVING expressions.
3694
3695        Example:
3696            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3697            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3698
3699        Args:
3700            *expressions: the SQL code strings to parse.
3701                If an `Expression` instance is passed, it will be used as-is.
3702                Multiple expressions are combined with an AND operator.
3703            append: if `True`, AND the new expressions to any existing expression.
3704                Otherwise, this resets the expression.
3705            dialect: the dialect used to parse the input expressions.
3706            copy: if `False`, modify this expression instance in-place.
3707            opts: other options to use to parse the input expressions.
3708
3709        Returns:
3710            The modified Select expression.
3711        """
3712        return _apply_conjunction_builder(
3713            *expressions,
3714            instance=self,
3715            arg="having",
3716            append=append,
3717            into=Having,
3718            dialect=dialect,
3719            copy=copy,
3720            **opts,
3721        )

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:
3723    def window(
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_list_builder(
3732            *expressions,
3733            instance=self,
3734            arg="windows",
3735            append=append,
3736            into=Window,
3737            dialect=dialect,
3738            copy=copy,
3739            **opts,
3740        )
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:
3742    def qualify(
3743        self,
3744        *expressions: t.Optional[ExpOrStr],
3745        append: bool = True,
3746        dialect: DialectType = None,
3747        copy: bool = True,
3748        **opts,
3749    ) -> Select:
3750        return _apply_conjunction_builder(
3751            *expressions,
3752            instance=self,
3753            arg="qualify",
3754            append=append,
3755            into=Qualify,
3756            dialect=dialect,
3757            copy=copy,
3758            **opts,
3759        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
3761    def distinct(
3762        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
3763    ) -> Select:
3764        """
3765        Set the OFFSET expression.
3766
3767        Example:
3768            >>> Select().from_("tbl").select("x").distinct().sql()
3769            'SELECT DISTINCT x FROM tbl'
3770
3771        Args:
3772            ons: the expressions to distinct on
3773            distinct: whether the Select should be distinct
3774            copy: if `False`, modify this expression instance in-place.
3775
3776        Returns:
3777            Select: the modified expression.
3778        """
3779        instance = maybe_copy(self, copy)
3780        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
3781        instance.set("distinct", Distinct(on=on) if distinct else None)
3782        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:
3784    def ctas(
3785        self,
3786        table: ExpOrStr,
3787        properties: t.Optional[t.Dict] = None,
3788        dialect: DialectType = None,
3789        copy: bool = True,
3790        **opts,
3791    ) -> Create:
3792        """
3793        Convert this expression to a CREATE TABLE AS statement.
3794
3795        Example:
3796            >>> Select().select("*").from_("tbl").ctas("x").sql()
3797            'CREATE TABLE x AS SELECT * FROM tbl'
3798
3799        Args:
3800            table: the SQL code string to parse as the table name.
3801                If another `Expression` instance is passed, it will be used as-is.
3802            properties: an optional mapping of table properties
3803            dialect: the dialect used to parse the input table.
3804            copy: if `False`, modify this expression instance in-place.
3805            opts: other options to use to parse the input table.
3806
3807        Returns:
3808            The new Create expression.
3809        """
3810        instance = maybe_copy(self, copy)
3811        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
3812
3813        properties_expression = None
3814        if properties:
3815            properties_expression = Properties.from_dict(properties)
3816
3817        return Create(
3818            this=table_expression,
3819            kind="TABLE",
3820            expression=instance,
3821            properties=properties_expression,
3822        )

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:
3824    def lock(self, update: bool = True, copy: bool = True) -> Select:
3825        """
3826        Set the locking read mode for this expression.
3827
3828        Examples:
3829            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
3830            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
3831
3832            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
3833            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
3834
3835        Args:
3836            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
3837            copy: if `False`, modify this expression instance in-place.
3838
3839        Returns:
3840            The modified expression.
3841        """
3842        inst = maybe_copy(self, copy)
3843        inst.set("locks", [Lock(update=update)])
3844
3845        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:
3847    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
3848        """
3849        Set hints for this expression.
3850
3851        Examples:
3852            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
3853            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
3854
3855        Args:
3856            hints: The SQL code strings to parse as the hints.
3857                If an `Expression` instance is passed, it will be used as-is.
3858            dialect: The dialect used to parse the hints.
3859            copy: If `False`, modify this expression instance in-place.
3860
3861        Returns:
3862            The modified expression.
3863        """
3864        inst = maybe_copy(self, copy)
3865        inst.set(
3866            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
3867        )
3868
3869        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]
3871    @property
3872    def named_selects(self) -> t.List[str]:
3873        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
3875    @property
3876    def is_star(self) -> bool:
3877        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
3879    @property
3880    def selects(self) -> t.List[Expression]:
3881        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
3887class Subquery(DerivedTable, Query):
3888    arg_types = {
3889        "this": True,
3890        "alias": False,
3891        "with": False,
3892        **QUERY_MODIFIERS,
3893    }
3894
3895    def unnest(self):
3896        """Returns the first non subquery."""
3897        expression = self
3898        while isinstance(expression, Subquery):
3899            expression = expression.this
3900        return expression
3901
3902    def unwrap(self) -> Subquery:
3903        expression = self
3904        while expression.same_parent and expression.is_wrapper:
3905            expression = t.cast(Subquery, expression.parent)
3906        return expression
3907
3908    def select(
3909        self,
3910        *expressions: t.Optional[ExpOrStr],
3911        append: bool = True,
3912        dialect: DialectType = None,
3913        copy: bool = True,
3914        **opts,
3915    ) -> Subquery:
3916        this = maybe_copy(self, copy)
3917        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3918        return this
3919
3920    @property
3921    def is_wrapper(self) -> bool:
3922        """
3923        Whether this Subquery acts as a simple wrapper around another expression.
3924
3925        SELECT * FROM (((SELECT * FROM t)))
3926                      ^
3927                      This corresponds to a "wrapper" Subquery node
3928        """
3929        return all(v is None for k, v in self.args.items() if k != "this")
3930
3931    @property
3932    def is_star(self) -> bool:
3933        return self.this.is_star
3934
3935    @property
3936    def output_name(self) -> str:
3937        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):
3895    def unnest(self):
3896        """Returns the first non subquery."""
3897        expression = self
3898        while isinstance(expression, Subquery):
3899            expression = expression.this
3900        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
3902    def unwrap(self) -> Subquery:
3903        expression = self
3904        while expression.same_parent and expression.is_wrapper:
3905            expression = t.cast(Subquery, expression.parent)
3906        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:
3908    def select(
3909        self,
3910        *expressions: t.Optional[ExpOrStr],
3911        append: bool = True,
3912        dialect: DialectType = None,
3913        copy: bool = True,
3914        **opts,
3915    ) -> Subquery:
3916        this = maybe_copy(self, copy)
3917        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3918        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
3920    @property
3921    def is_wrapper(self) -> bool:
3922        """
3923        Whether this Subquery acts as a simple wrapper around another expression.
3924
3925        SELECT * FROM (((SELECT * FROM t)))
3926                      ^
3927                      This corresponds to a "wrapper" Subquery node
3928        """
3929        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
3931    @property
3932    def is_star(self) -> bool:
3933        return self.this.is_star

Checks whether an expression is a star.

output_name: str
3935    @property
3936    def output_name(self) -> str:
3937        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):
3940class TableSample(Expression):
3941    arg_types = {
3942        "expressions": False,
3943        "method": False,
3944        "bucket_numerator": False,
3945        "bucket_denominator": False,
3946        "bucket_field": False,
3947        "percent": False,
3948        "rows": False,
3949        "size": False,
3950        "seed": False,
3951    }
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):
3954class Tag(Expression):
3955    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
3956
3957    arg_types = {
3958        "this": False,
3959        "prefix": False,
3960        "postfix": False,
3961    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3966class Pivot(Expression):
3967    arg_types = {
3968        "this": False,
3969        "alias": False,
3970        "expressions": False,
3971        "field": False,
3972        "unpivot": False,
3973        "using": False,
3974        "group": False,
3975        "columns": False,
3976        "include_nulls": False,
3977        "default_on_null": False,
3978    }
3979
3980    @property
3981    def unpivot(self) -> bool:
3982        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
3980    @property
3981    def unpivot(self) -> bool:
3982        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3985class Window(Condition):
3986    arg_types = {
3987        "this": True,
3988        "partition_by": False,
3989        "order": False,
3990        "spec": False,
3991        "alias": False,
3992        "over": False,
3993        "first": False,
3994    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
3997class WindowSpec(Expression):
3998    arg_types = {
3999        "kind": False,
4000        "start": False,
4001        "start_side": False,
4002        "end": False,
4003        "end_side": False,
4004    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4007class PreWhere(Expression):
4008    pass
key = 'prewhere'
class Where(Expression):
4011class Where(Expression):
4012    pass
key = 'where'
class Star(Expression):
4015class Star(Expression):
4016    arg_types = {"except": False, "replace": False, "rename": False}
4017
4018    @property
4019    def name(self) -> str:
4020        return "*"
4021
4022    @property
4023    def output_name(self) -> str:
4024        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4018    @property
4019    def name(self) -> str:
4020        return "*"
output_name: str
4022    @property
4023    def output_name(self) -> str:
4024        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):
4027class Parameter(Condition):
4028    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4031class SessionParameter(Condition):
4032    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4035class Placeholder(Condition):
4036    arg_types = {"this": False, "kind": False}
4037
4038    @property
4039    def name(self) -> str:
4040        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4038    @property
4039    def name(self) -> str:
4040        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4043class Null(Condition):
4044    arg_types: t.Dict[str, t.Any] = {}
4045
4046    @property
4047    def name(self) -> str:
4048        return "NULL"
4049
4050    def to_py(self) -> Lit[None]:
4051        return None
arg_types: Dict[str, Any] = {}
name: str
4046    @property
4047    def name(self) -> str:
4048        return "NULL"
def to_py(self) -> Literal[None]:
4050    def to_py(self) -> Lit[None]:
4051        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4054class Boolean(Condition):
4055    def to_py(self) -> bool:
4056        return self.this
def to_py(self) -> bool:
4055    def to_py(self) -> bool:
4056        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

name: str
4506    @property
4507    def name(self) -> str:
4508        return self.expression.name
output_name: str
4510    @property
4511    def output_name(self) -> str:
4512        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:
4514    @classmethod
4515    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4516        """Build a Dot object with a sequence of expressions."""
4517        if len(expressions) < 2:
4518            raise ValueError("Dot requires >= 2 expressions.")
4519
4520        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]
4522    @property
4523    def parts(self) -> t.List[Expression]:
4524        """Return the parts of a table / column in order catalog, db, table."""
4525        this, *parts = self.flatten()
4526
4527        parts.reverse()
4528
4529        for arg in COLUMN_PARTS:
4530            part = this.args.get(arg)
4531
4532            if isinstance(part, Expression):
4533                parts.append(part)
4534
4535        parts.reverse()
4536        return parts

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

key = 'dot'
class DPipe(Binary):
4539class DPipe(Binary):
4540    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4543class EQ(Binary, Predicate):
4544    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4547class NullSafeEQ(Binary, Predicate):
4548    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4551class NullSafeNEQ(Binary, Predicate):
4552    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4556class PropertyEQ(Binary):
4557    pass
key = 'propertyeq'
class Distance(Binary):
4560class Distance(Binary):
4561    pass
key = 'distance'
class Escape(Binary):
4564class Escape(Binary):
4565    pass
key = 'escape'
class Glob(Binary, Predicate):
4568class Glob(Binary, Predicate):
4569    pass
key = 'glob'
class GT(Binary, Predicate):
4572class GT(Binary, Predicate):
4573    pass
key = 'gt'
class GTE(Binary, Predicate):
4576class GTE(Binary, Predicate):
4577    pass
key = 'gte'
class ILike(Binary, Predicate):
4580class ILike(Binary, Predicate):
4581    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4584class ILikeAny(Binary, Predicate):
4585    pass
key = 'ilikeany'
class IntDiv(Binary):
4588class IntDiv(Binary):
4589    pass
key = 'intdiv'
class Is(Binary, Predicate):
4592class Is(Binary, Predicate):
4593    pass
key = 'is'
class Kwarg(Binary):
4596class Kwarg(Binary):
4597    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4600class Like(Binary, Predicate):
4601    pass
key = 'like'
class LikeAny(Binary, Predicate):
4604class LikeAny(Binary, Predicate):
4605    pass
key = 'likeany'
class LT(Binary, Predicate):
4608class LT(Binary, Predicate):
4609    pass
key = 'lt'
class LTE(Binary, Predicate):
4612class LTE(Binary, Predicate):
4613    pass
key = 'lte'
class Mod(Binary):
4616class Mod(Binary):
4617    pass
key = 'mod'
class Mul(Binary):
4620class Mul(Binary):
4621    pass
key = 'mul'
class NEQ(Binary, Predicate):
4624class NEQ(Binary, Predicate):
4625    pass
key = 'neq'
class Operator(Binary):
4629class Operator(Binary):
4630    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4633class SimilarTo(Binary, Predicate):
4634    pass
key = 'similarto'
class Slice(Binary):
4637class Slice(Binary):
4638    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4641class Sub(Binary):
4642    pass
key = 'sub'
class Unary(Condition):
4647class Unary(Condition):
4648    pass
key = 'unary'
class BitwiseNot(Unary):
4651class BitwiseNot(Unary):
4652    pass
key = 'bitwisenot'
class Not(Unary):
4655class Not(Unary):
4656    pass
key = 'not'
class Paren(Unary):
4659class Paren(Unary):
4660    @property
4661    def output_name(self) -> str:
4662        return self.this.name
output_name: str
4660    @property
4661    def output_name(self) -> str:
4662        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):
4665class Neg(Unary):
4666    def to_py(self) -> int | Decimal:
4667        if self.is_number:
4668            return self.this.to_py() * -1
4669        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4666    def to_py(self) -> int | Decimal:
4667        if self.is_number:
4668            return self.this.to_py() * -1
4669        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4672class Alias(Expression):
4673    arg_types = {"this": True, "alias": False}
4674
4675    @property
4676    def output_name(self) -> str:
4677        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4675    @property
4676    def output_name(self) -> str:
4677        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):
4682class PivotAlias(Alias):
4683    pass
key = 'pivotalias'
class PivotAny(Expression):
4688class PivotAny(Expression):
4689    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4692class Aliases(Expression):
4693    arg_types = {"this": True, "expressions": True}
4694
4695    @property
4696    def aliases(self):
4697        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4695    @property
4696    def aliases(self):
4697        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4701class AtIndex(Expression):
4702    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4705class AtTimeZone(Expression):
4706    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4709class FromTimeZone(Expression):
4710    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4713class Between(Predicate):
4714    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4717class Bracket(Condition):
4718    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4719    arg_types = {
4720        "this": True,
4721        "expressions": True,
4722        "offset": False,
4723        "safe": False,
4724        "returns_list_for_maps": False,
4725    }
4726
4727    @property
4728    def output_name(self) -> str:
4729        if len(self.expressions) == 1:
4730            return self.expressions[0].output_name
4731
4732        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4727    @property
4728    def output_name(self) -> str:
4729        if len(self.expressions) == 1:
4730            return self.expressions[0].output_name
4731
4732        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):
4735class Distinct(Expression):
4736    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4739class In(Predicate):
4740    arg_types = {
4741        "this": True,
4742        "expressions": False,
4743        "query": False,
4744        "unnest": False,
4745        "field": False,
4746        "is_global": False,
4747    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4751class ForIn(Expression):
4752    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4755class TimeUnit(Expression):
4756    """Automatically converts unit arg into a var."""
4757
4758    arg_types = {"unit": False}
4759
4760    UNABBREVIATED_UNIT_NAME = {
4761        "D": "DAY",
4762        "H": "HOUR",
4763        "M": "MINUTE",
4764        "MS": "MILLISECOND",
4765        "NS": "NANOSECOND",
4766        "Q": "QUARTER",
4767        "S": "SECOND",
4768        "US": "MICROSECOND",
4769        "W": "WEEK",
4770        "Y": "YEAR",
4771    }
4772
4773    VAR_LIKE = (Column, Literal, Var)
4774
4775    def __init__(self, **args):
4776        unit = args.get("unit")
4777        if isinstance(unit, self.VAR_LIKE):
4778            args["unit"] = Var(
4779                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4780            )
4781        elif isinstance(unit, Week):
4782            unit.set("this", Var(this=unit.this.name.upper()))
4783
4784        super().__init__(**args)
4785
4786    @property
4787    def unit(self) -> t.Optional[Var | IntervalSpan]:
4788        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4775    def __init__(self, **args):
4776        unit = args.get("unit")
4777        if isinstance(unit, self.VAR_LIKE):
4778            args["unit"] = Var(
4779                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4780            )
4781        elif isinstance(unit, Week):
4782            unit.set("this", Var(this=unit.this.name.upper()))
4783
4784        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]
4786    @property
4787    def unit(self) -> t.Optional[Var | IntervalSpan]:
4788        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4791class IntervalOp(TimeUnit):
4792    arg_types = {"unit": False, "expression": True}
4793
4794    def interval(self):
4795        return Interval(
4796            this=self.expression.copy(),
4797            unit=self.unit.copy() if self.unit else None,
4798        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
4794    def interval(self):
4795        return Interval(
4796            this=self.expression.copy(),
4797            unit=self.unit.copy() if self.unit else None,
4798        )
key = 'intervalop'
class IntervalSpan(DataType):
4804class IntervalSpan(DataType):
4805    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4808class Interval(TimeUnit):
4809    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4812class IgnoreNulls(Expression):
4813    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4816class RespectNulls(Expression):
4817    pass
key = 'respectnulls'
class HavingMax(Expression):
4821class HavingMax(Expression):
4822    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4826class Func(Condition):
4827    """
4828    The base class for all function expressions.
4829
4830    Attributes:
4831        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4832            treated as a variable length argument and the argument's value will be stored as a list.
4833        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4834            function expression. These values are used to map this node to a name during parsing as
4835            well as to provide the function's name during SQL string generation. By default the SQL
4836            name is set to the expression's class name transformed to snake case.
4837    """
4838
4839    is_var_len_args = False
4840
4841    @classmethod
4842    def from_arg_list(cls, args):
4843        if cls.is_var_len_args:
4844            all_arg_keys = list(cls.arg_types)
4845            # If this function supports variable length argument treat the last argument as such.
4846            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4847            num_non_var = len(non_var_len_arg_keys)
4848
4849            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4850            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4851        else:
4852            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4853
4854        return cls(**args_dict)
4855
4856    @classmethod
4857    def sql_names(cls):
4858        if cls is Func:
4859            raise NotImplementedError(
4860                "SQL name is only supported by concrete function implementations"
4861            )
4862        if "_sql_names" not in cls.__dict__:
4863            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4864        return cls._sql_names
4865
4866    @classmethod
4867    def sql_name(cls):
4868        return cls.sql_names()[0]
4869
4870    @classmethod
4871    def default_parser_mappings(cls):
4872        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):
4841    @classmethod
4842    def from_arg_list(cls, args):
4843        if cls.is_var_len_args:
4844            all_arg_keys = list(cls.arg_types)
4845            # If this function supports variable length argument treat the last argument as such.
4846            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4847            num_non_var = len(non_var_len_arg_keys)
4848
4849            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4850            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4851        else:
4852            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4853
4854        return cls(**args_dict)
@classmethod
def sql_names(cls):
4856    @classmethod
4857    def sql_names(cls):
4858        if cls is Func:
4859            raise NotImplementedError(
4860                "SQL name is only supported by concrete function implementations"
4861            )
4862        if "_sql_names" not in cls.__dict__:
4863            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4864        return cls._sql_names
@classmethod
def sql_name(cls):
4866    @classmethod
4867    def sql_name(cls):
4868        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4870    @classmethod
4871    def default_parser_mappings(cls):
4872        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4875class AggFunc(Func):
4876    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4879class ParameterizedAgg(AggFunc):
4880    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4883class Abs(Func):
4884    pass
key = 'abs'
class ArgMax(AggFunc):
4887class ArgMax(AggFunc):
4888    arg_types = {"this": True, "expression": True, "count": False}
4889    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4892class ArgMin(AggFunc):
4893    arg_types = {"this": True, "expression": True, "count": False}
4894    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4897class ApproxTopK(AggFunc):
4898    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4901class Flatten(Func):
4902    pass
key = 'flatten'
class Transform(Func):
4906class Transform(Func):
4907    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4910class Anonymous(Func):
4911    arg_types = {"this": True, "expressions": False}
4912    is_var_len_args = True
4913
4914    @property
4915    def name(self) -> str:
4916        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
4914    @property
4915    def name(self) -> str:
4916        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4919class AnonymousAggFunc(AggFunc):
4920    arg_types = {"this": True, "expressions": False}
4921    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4925class CombinedAggFunc(AnonymousAggFunc):
4926    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4929class CombinedParameterizedAgg(ParameterizedAgg):
4930    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):
4935class Hll(AggFunc):
4936    arg_types = {"this": True, "expressions": False}
4937    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4940class ApproxDistinct(AggFunc):
4941    arg_types = {"this": True, "accuracy": False}
4942    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
4945class Apply(Func):
4946    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
4949class Array(Func):
4950    arg_types = {"expressions": False, "bracket_notation": False}
4951    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4955class ToArray(Func):
4956    pass
key = 'toarray'
class List(Func):
4960class List(Func):
4961    arg_types = {"expressions": False}
4962    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4966class Pad(Func):
4967    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):
4972class ToChar(Func):
4973    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4978class ToNumber(Func):
4979    arg_types = {
4980        "this": True,
4981        "format": False,
4982        "nlsparam": False,
4983        "precision": False,
4984        "scale": False,
4985    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Convert(Func):
4989class Convert(Func):
4990    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
4993class ConvertTimezone(Func):
4994    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):
4997class GenerateSeries(Func):
4998    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):
5004class ExplodingGenerateSeries(GenerateSeries):
5005    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5008class ArrayAgg(AggFunc):
5009    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5012class ArrayUniqueAgg(AggFunc):
5013    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5016class ArrayAll(Func):
5017    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5021class ArrayAny(Func):
5022    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5025class ArrayConcat(Func):
5026    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5027    arg_types = {"this": True, "expressions": False}
5028    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5031class ArrayConstructCompact(Func):
5032    arg_types = {"expressions": True}
5033    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5036class ArrayContains(Binary, Func):
5037    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5040class ArrayContainsAll(Binary, Func):
5041    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5044class ArrayFilter(Func):
5045    arg_types = {"this": True, "expression": True}
5046    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5049class ArrayToString(Func):
5050    arg_types = {"this": True, "expression": True, "null": False}
5051    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
5054class StringToArray(Func):
5055    arg_types = {"this": True, "expression": True, "null": False}
5056    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5059class ArrayOverlaps(Binary, Func):
5060    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5063class ArraySize(Func):
5064    arg_types = {"this": True, "expression": False}
5065    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5068class ArraySort(Func):
5069    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5072class ArraySum(Func):
5073    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5076class ArrayUnionAgg(AggFunc):
5077    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5080class Avg(AggFunc):
5081    pass
key = 'avg'
class AnyValue(AggFunc):
5084class AnyValue(AggFunc):
5085    pass
key = 'anyvalue'
class Lag(AggFunc):
5088class Lag(AggFunc):
5089    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5092class Lead(AggFunc):
5093    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5098class First(AggFunc):
5099    pass
key = 'first'
class Last(AggFunc):
5102class Last(AggFunc):
5103    pass
key = 'last'
class FirstValue(AggFunc):
5106class FirstValue(AggFunc):
5107    pass
key = 'firstvalue'
class LastValue(AggFunc):
5110class LastValue(AggFunc):
5111    pass
key = 'lastvalue'
class NthValue(AggFunc):
5114class NthValue(AggFunc):
5115    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5118class Case(Func):
5119    arg_types = {"this": False, "ifs": True, "default": False}
5120
5121    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5122        instance = maybe_copy(self, copy)
5123        instance.append(
5124            "ifs",
5125            If(
5126                this=maybe_parse(condition, copy=copy, **opts),
5127                true=maybe_parse(then, copy=copy, **opts),
5128            ),
5129        )
5130        return instance
5131
5132    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5133        instance = maybe_copy(self, copy)
5134        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5135        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:
5121    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5122        instance = maybe_copy(self, copy)
5123        instance.append(
5124            "ifs",
5125            If(
5126                this=maybe_parse(condition, copy=copy, **opts),
5127                true=maybe_parse(then, copy=copy, **opts),
5128            ),
5129        )
5130        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5132    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5133        instance = maybe_copy(self, copy)
5134        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5135        return instance
key = 'case'
class Cast(Func):
5138class Cast(Func):
5139    arg_types = {
5140        "this": True,
5141        "to": True,
5142        "format": False,
5143        "safe": False,
5144        "action": False,
5145    }
5146
5147    @property
5148    def name(self) -> str:
5149        return self.this.name
5150
5151    @property
5152    def to(self) -> DataType:
5153        return self.args["to"]
5154
5155    @property
5156    def output_name(self) -> str:
5157        return self.name
5158
5159    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5160        """
5161        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5162        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5163        array<int> != array<float>.
5164
5165        Args:
5166            dtypes: the data types to compare this Cast's DataType to.
5167
5168        Returns:
5169            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5170        """
5171        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5147    @property
5148    def name(self) -> str:
5149        return self.this.name
to: DataType
5151    @property
5152    def to(self) -> DataType:
5153        return self.args["to"]
output_name: str
5155    @property
5156    def output_name(self) -> str:
5157        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:
5159    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5160        """
5161        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5162        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5163        array<int> != array<float>.
5164
5165        Args:
5166            dtypes: the data types to compare this Cast's DataType to.
5167
5168        Returns:
5169            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5170        """
5171        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):
5174class TryCast(Cast):
5175    pass
key = 'trycast'
class Try(Func):
5178class Try(Func):
5179    pass
key = 'try'
class CastToStrType(Func):
5182class CastToStrType(Func):
5183    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5186class Collate(Binary, Func):
5187    pass
key = 'collate'
class Ceil(Func):
5190class Ceil(Func):
5191    arg_types = {"this": True, "decimals": False}
5192    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5195class Coalesce(Func):
5196    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5197    is_var_len_args = True
5198    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5201class Chr(Func):
5202    arg_types = {"expressions": True, "charset": False}
5203    is_var_len_args = True
5204    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5207class Concat(Func):
5208    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5209    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5212class ConcatWs(Concat):
5213    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5217class ConnectByRoot(Func):
5218    pass
key = 'connectbyroot'
class Count(AggFunc):
5221class Count(AggFunc):
5222    arg_types = {"this": False, "expressions": False, "big_int": False}
5223    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5226class CountIf(AggFunc):
5227    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5231class Cbrt(Func):
5232    pass
key = 'cbrt'
class CurrentDate(Func):
5235class CurrentDate(Func):
5236    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5239class CurrentDatetime(Func):
5240    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5243class CurrentTime(Func):
5244    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5247class CurrentTimestamp(Func):
5248    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5251class CurrentUser(Func):
5252    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5255class DateAdd(Func, IntervalOp):
5256    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5259class DateSub(Func, IntervalOp):
5260    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5263class DateDiff(Func, TimeUnit):
5264    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5265    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5268class DateTrunc(Func):
5269    arg_types = {"unit": True, "this": True, "zone": False}
5270
5271    def __init__(self, **args):
5272        unit = args.get("unit")
5273        if isinstance(unit, TimeUnit.VAR_LIKE):
5274            args["unit"] = Literal.string(
5275                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5276            )
5277        elif isinstance(unit, Week):
5278            unit.set("this", Literal.string(unit.this.name.upper()))
5279
5280        super().__init__(**args)
5281
5282    @property
5283    def unit(self) -> Expression:
5284        return self.args["unit"]
DateTrunc(**args)
5271    def __init__(self, **args):
5272        unit = args.get("unit")
5273        if isinstance(unit, TimeUnit.VAR_LIKE):
5274            args["unit"] = Literal.string(
5275                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5276            )
5277        elif isinstance(unit, Week):
5278            unit.set("this", Literal.string(unit.this.name.upper()))
5279
5280        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5282    @property
5283    def unit(self) -> Expression:
5284        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5289class Datetime(Func):
5290    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5293class DatetimeAdd(Func, IntervalOp):
5294    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5297class DatetimeSub(Func, IntervalOp):
5298    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5301class DatetimeDiff(Func, TimeUnit):
5302    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5305class DatetimeTrunc(Func, TimeUnit):
5306    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5309class DayOfWeek(Func):
5310    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5315class DayOfWeekIso(Func):
5316    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5319class DayOfMonth(Func):
5320    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5323class DayOfYear(Func):
5324    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5327class ToDays(Func):
5328    pass
key = 'todays'
class WeekOfYear(Func):
5331class WeekOfYear(Func):
5332    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5335class MonthsBetween(Func):
5336    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5339class LastDay(Func, TimeUnit):
5340    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5341    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5344class Extract(Func):
5345    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5348class Timestamp(Func):
5349    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5352class TimestampAdd(Func, TimeUnit):
5353    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5356class TimestampSub(Func, TimeUnit):
5357    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5360class TimestampDiff(Func, TimeUnit):
5361    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5362    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5365class TimestampTrunc(Func, TimeUnit):
5366    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5369class TimeAdd(Func, TimeUnit):
5370    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5373class TimeSub(Func, TimeUnit):
5374    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5377class TimeDiff(Func, TimeUnit):
5378    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5381class TimeTrunc(Func, TimeUnit):
5382    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5385class DateFromParts(Func):
5386    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5387    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5390class TimeFromParts(Func):
5391    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5392    arg_types = {
5393        "hour": True,
5394        "min": True,
5395        "sec": True,
5396        "nano": False,
5397        "fractions": False,
5398        "precision": False,
5399    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5402class DateStrToDate(Func):
5403    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5406class DateToDateStr(Func):
5407    pass
key = 'datetodatestr'
class DateToDi(Func):
5410class DateToDi(Func):
5411    pass
key = 'datetodi'
class Date(Func):
5415class Date(Func):
5416    arg_types = {"this": False, "zone": False, "expressions": False}
5417    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5420class Day(Func):
5421    pass
key = 'day'
class Decode(Func):
5424class Decode(Func):
5425    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5428class DiToDate(Func):
5429    pass
key = 'ditodate'
class Encode(Func):
5432class Encode(Func):
5433    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5436class Exp(Func):
5437    pass
key = 'exp'
class Explode(Func):
5441class Explode(Func):
5442    arg_types = {"this": True, "expressions": False}
5443    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5447class Inline(Func):
5448    pass
key = 'inline'
class ExplodeOuter(Explode):
5451class ExplodeOuter(Explode):
5452    pass
key = 'explodeouter'
class Posexplode(Explode):
5455class Posexplode(Explode):
5456    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5459class PosexplodeOuter(Posexplode, ExplodeOuter):
5460    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5463class Unnest(Func, UDTF):
5464    arg_types = {
5465        "expressions": True,
5466        "alias": False,
5467        "offset": False,
5468        "explode_array": False,
5469    }
5470
5471    @property
5472    def selects(self) -> t.List[Expression]:
5473        columns = super().selects
5474        offset = self.args.get("offset")
5475        if offset:
5476            columns = columns + [to_identifier("offset") if offset is True else offset]
5477        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5471    @property
5472    def selects(self) -> t.List[Expression]:
5473        columns = super().selects
5474        offset = self.args.get("offset")
5475        if offset:
5476            columns = columns + [to_identifier("offset") if offset is True else offset]
5477        return columns
key = 'unnest'
class Floor(Func):
5480class Floor(Func):
5481    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5484class FromBase64(Func):
5485    pass
key = 'frombase64'
class ToBase64(Func):
5488class ToBase64(Func):
5489    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5493class FromISO8601Timestamp(Func):
5494    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5497class GapFill(Func):
5498    arg_types = {
5499        "this": True,
5500        "ts_column": True,
5501        "bucket_width": True,
5502        "partitioning_columns": False,
5503        "value_columns": False,
5504        "origin": False,
5505        "ignore_nulls": False,
5506    }
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):
5510class GenerateDateArray(Func):
5511    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5515class GenerateTimestampArray(Func):
5516    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5519class Greatest(Func):
5520    arg_types = {"this": True, "expressions": False}
5521    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5524class GroupConcat(AggFunc):
5525    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5528class Hex(Func):
5529    pass
key = 'hex'
class LowerHex(Hex):
5532class LowerHex(Hex):
5533    pass
key = 'lowerhex'
class Xor(Connector, Func):
5536class Xor(Connector, Func):
5537    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5540class If(Func):
5541    arg_types = {"this": True, "true": True, "false": False}
5542    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5545class Nullif(Func):
5546    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5549class Initcap(Func):
5550    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5553class IsNan(Func):
5554    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5557class IsInf(Func):
5558    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5562class JSON(Expression):
5563    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5566class JSONPath(Expression):
5567    arg_types = {"expressions": True, "escape": False}
5568
5569    @property
5570    def output_name(self) -> str:
5571        last_segment = self.expressions[-1].this
5572        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5569    @property
5570    def output_name(self) -> str:
5571        last_segment = self.expressions[-1].this
5572        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):
5575class JSONPathPart(Expression):
5576    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5579class JSONPathFilter(JSONPathPart):
5580    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5583class JSONPathKey(JSONPathPart):
5584    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5587class JSONPathRecursive(JSONPathPart):
5588    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5591class JSONPathRoot(JSONPathPart):
5592    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5595class JSONPathScript(JSONPathPart):
5596    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5599class JSONPathSlice(JSONPathPart):
5600    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5603class JSONPathSelector(JSONPathPart):
5604    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5607class JSONPathSubscript(JSONPathPart):
5608    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5611class JSONPathUnion(JSONPathPart):
5612    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5615class JSONPathWildcard(JSONPathPart):
5616    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5619class FormatJson(Expression):
5620    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5623class JSONKeyValue(Expression):
5624    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5627class JSONObject(Func):
5628    arg_types = {
5629        "expressions": False,
5630        "null_handling": False,
5631        "unique_keys": False,
5632        "return_type": False,
5633        "encoding": False,
5634    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5637class JSONObjectAgg(AggFunc):
5638    arg_types = {
5639        "expressions": False,
5640        "null_handling": False,
5641        "unique_keys": False,
5642        "return_type": False,
5643        "encoding": False,
5644    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5648class JSONArray(Func):
5649    arg_types = {
5650        "expressions": True,
5651        "null_handling": False,
5652        "return_type": False,
5653        "strict": False,
5654    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5658class JSONArrayAgg(Func):
5659    arg_types = {
5660        "this": True,
5661        "order": False,
5662        "null_handling": False,
5663        "return_type": False,
5664        "strict": False,
5665    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
5668class JSONExists(Func):
5669    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):
5674class JSONColumnDef(Expression):
5675    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):
5678class JSONSchema(Expression):
5679    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
5683class JSONValue(Expression):
5684    arg_types = {
5685        "this": True,
5686        "path": True,
5687        "returning": False,
5688        "on_condition": False,
5689    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONTable(Func):
5693class JSONTable(Func):
5694    arg_types = {
5695        "this": True,
5696        "schema": True,
5697        "path": False,
5698        "error_handling": False,
5699        "empty_handling": False,
5700    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5704class ObjectInsert(Func):
5705    arg_types = {
5706        "this": True,
5707        "key": True,
5708        "value": True,
5709        "update_flag": False,
5710    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5713class OpenJSONColumnDef(Expression):
5714    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):
5717class OpenJSON(Func):
5718    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5721class JSONBContains(Binary, Func):
5722    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5725class JSONExtract(Binary, Func):
5726    arg_types = {
5727        "this": True,
5728        "expression": True,
5729        "only_json_types": False,
5730        "expressions": False,
5731        "variant_extract": False,
5732    }
5733    _sql_names = ["JSON_EXTRACT"]
5734    is_var_len_args = True
5735
5736    @property
5737    def output_name(self) -> str:
5738        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
5736    @property
5737    def output_name(self) -> str:
5738        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):
5741class JSONExtractScalar(Binary, Func):
5742    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5743    _sql_names = ["JSON_EXTRACT_SCALAR"]
5744    is_var_len_args = True
5745
5746    @property
5747    def output_name(self) -> str:
5748        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
5746    @property
5747    def output_name(self) -> str:
5748        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):
5751class JSONBExtract(Binary, Func):
5752    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5755class JSONBExtractScalar(Binary, Func):
5756    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5759class JSONFormat(Func):
5760    arg_types = {"this": False, "options": False}
5761    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5765class JSONArrayContains(Binary, Predicate, Func):
5766    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5769class ParseJSON(Func):
5770    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5771    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5772    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5773    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5776class Least(Func):
5777    arg_types = {"this": True, "expressions": False}
5778    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5781class Left(Func):
5782    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5789class Length(Func):
5790    arg_types = {"this": True, "binary": False}
5791    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5794class Levenshtein(Func):
5795    arg_types = {
5796        "this": True,
5797        "expression": False,
5798        "ins_cost": False,
5799        "del_cost": False,
5800        "sub_cost": False,
5801    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5804class Ln(Func):
5805    pass
key = 'ln'
class Log(Func):
5808class Log(Func):
5809    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5812class LogicalOr(AggFunc):
5813    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5816class LogicalAnd(AggFunc):
5817    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5820class Lower(Func):
5821    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5824class Map(Func):
5825    arg_types = {"keys": False, "values": False}
5826
5827    @property
5828    def keys(self) -> t.List[Expression]:
5829        keys = self.args.get("keys")
5830        return keys.expressions if keys else []
5831
5832    @property
5833    def values(self) -> t.List[Expression]:
5834        values = self.args.get("values")
5835        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5827    @property
5828    def keys(self) -> t.List[Expression]:
5829        keys = self.args.get("keys")
5830        return keys.expressions if keys else []
values: List[Expression]
5832    @property
5833    def values(self) -> t.List[Expression]:
5834        values = self.args.get("values")
5835        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5839class ToMap(Func):
5840    pass
key = 'tomap'
class MapFromEntries(Func):
5843class MapFromEntries(Func):
5844    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5848class ScopeResolution(Expression):
5849    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
5852class Stream(Expression):
5853    pass
key = 'stream'
class StarMap(Func):
5856class StarMap(Func):
5857    pass
key = 'starmap'
class VarMap(Func):
5860class VarMap(Func):
5861    arg_types = {"keys": True, "values": True}
5862    is_var_len_args = True
5863
5864    @property
5865    def keys(self) -> t.List[Expression]:
5866        return self.args["keys"].expressions
5867
5868    @property
5869    def values(self) -> t.List[Expression]:
5870        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5864    @property
5865    def keys(self) -> t.List[Expression]:
5866        return self.args["keys"].expressions
values: List[Expression]
5868    @property
5869    def values(self) -> t.List[Expression]:
5870        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5874class MatchAgainst(Func):
5875    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5878class Max(AggFunc):
5879    arg_types = {"this": True, "expressions": False}
5880    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5883class MD5(Func):
5884    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5888class MD5Digest(Func):
5889    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5892class Min(AggFunc):
5893    arg_types = {"this": True, "expressions": False}
5894    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5897class Month(Func):
5898    pass
key = 'month'
class AddMonths(Func):
5901class AddMonths(Func):
5902    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5905class Nvl2(Func):
5906    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
5909class Normalize(Func):
5910    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Predict(Func):
5914class Predict(Func):
5915    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5918class Pow(Binary, Func):
5919    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5922class PercentileCont(AggFunc):
5923    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5926class PercentileDisc(AggFunc):
5927    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5930class Quantile(AggFunc):
5931    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5934class ApproxQuantile(Quantile):
5935    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):
5938class Quarter(Func):
5939    pass
key = 'quarter'
class Rand(Func):
5944class Rand(Func):
5945    _sql_names = ["RAND", "RANDOM"]
5946    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5949class Randn(Func):
5950    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5953class RangeN(Func):
5954    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5957class ReadCSV(Func):
5958    _sql_names = ["READ_CSV"]
5959    is_var_len_args = True
5960    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5963class Reduce(Func):
5964    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):
5967class RegexpExtract(Func):
5968    arg_types = {
5969        "this": True,
5970        "expression": True,
5971        "position": False,
5972        "occurrence": False,
5973        "parameters": False,
5974        "group": False,
5975    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5978class RegexpReplace(Func):
5979    arg_types = {
5980        "this": True,
5981        "expression": True,
5982        "replacement": False,
5983        "position": False,
5984        "occurrence": False,
5985        "modifiers": False,
5986    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5989class RegexpLike(Binary, Func):
5990    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
5993class RegexpILike(Binary, Func):
5994    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
5999class RegexpSplit(Func):
6000    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6003class Repeat(Func):
6004    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6009class Round(Func):
6010    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6013class RowNumber(Func):
6014    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
6017class SafeDivide(Func):
6018    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6021class SHA(Func):
6022    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6025class SHA2(Func):
6026    _sql_names = ["SHA2"]
6027    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6030class Sign(Func):
6031    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6034class SortArray(Func):
6035    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6038class Split(Func):
6039    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
6044class Substring(Func):
6045    _sql_names = ["SUBSTRING", "SUBSTR"]
6046    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6049class StandardHash(Func):
6050    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6053class StartsWith(Func):
6054    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6055    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6058class StrPosition(Func):
6059    arg_types = {
6060        "this": True,
6061        "substr": True,
6062        "position": False,
6063        "instance": False,
6064    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
6067class StrToDate(Func):
6068    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6071class StrToTime(Func):
6072    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):
6077class StrToUnix(Func):
6078    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6083class StrToMap(Func):
6084    arg_types = {
6085        "this": True,
6086        "pair_delim": False,
6087        "key_value_delim": False,
6088        "duplicate_resolution_callback": False,
6089    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6092class NumberToStr(Func):
6093    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6096class FromBase(Func):
6097    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6100class Struct(Func):
6101    arg_types = {"expressions": False}
6102    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6105class StructExtract(Func):
6106    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6111class Stuff(Func):
6112    _sql_names = ["STUFF", "INSERT"]
6113    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):
6116class Sum(AggFunc):
6117    pass
key = 'sum'
class Sqrt(Func):
6120class Sqrt(Func):
6121    pass
key = 'sqrt'
class Stddev(AggFunc):
6124class Stddev(AggFunc):
6125    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6128class StddevPop(AggFunc):
6129    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6132class StddevSamp(AggFunc):
6133    pass
key = 'stddevsamp'
class Time(Func):
6137class Time(Func):
6138    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6141class TimeToStr(Func):
6142    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):
6145class TimeToTimeStr(Func):
6146    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6149class TimeToUnix(Func):
6150    pass
key = 'timetounix'
class TimeStrToDate(Func):
6153class TimeStrToDate(Func):
6154    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6157class TimeStrToTime(Func):
6158    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6161class TimeStrToUnix(Func):
6162    pass
key = 'timestrtounix'
class Trim(Func):
6165class Trim(Func):
6166    arg_types = {
6167        "this": True,
6168        "expression": False,
6169        "position": False,
6170        "collation": False,
6171    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6174class TsOrDsAdd(Func, TimeUnit):
6175    # return_type is used to correctly cast the arguments of this expression when transpiling it
6176    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6177
6178    @property
6179    def return_type(self) -> DataType:
6180        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
6178    @property
6179    def return_type(self) -> DataType:
6180        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6183class TsOrDsDiff(Func, TimeUnit):
6184    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6187class TsOrDsToDateStr(Func):
6188    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6191class TsOrDsToDate(Func):
6192    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6195class TsOrDsToTime(Func):
6196    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6199class TsOrDsToTimestamp(Func):
6200    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6203class TsOrDiToDi(Func):
6204    pass
key = 'tsorditodi'
class Unhex(Func):
6207class Unhex(Func):
6208    pass
key = 'unhex'
class UnixDate(Func):
6212class UnixDate(Func):
6213    pass
key = 'unixdate'
class UnixToStr(Func):
6216class UnixToStr(Func):
6217    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6222class UnixToTime(Func):
6223    arg_types = {
6224        "this": True,
6225        "scale": False,
6226        "zone": False,
6227        "hours": False,
6228        "minutes": False,
6229        "format": False,
6230    }
6231
6232    SECONDS = Literal.number(0)
6233    DECIS = Literal.number(1)
6234    CENTIS = Literal.number(2)
6235    MILLIS = Literal.number(3)
6236    DECIMILLIS = Literal.number(4)
6237    CENTIMILLIS = Literal.number(5)
6238    MICROS = Literal.number(6)
6239    DECIMICROS = Literal.number(7)
6240    CENTIMICROS = Literal.number(8)
6241    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):
6244class UnixToTimeStr(Func):
6245    pass
key = 'unixtotimestr'
class UnpackColumns(Func):
6248class UnpackColumns(Func):
6249    pass
key = 'unpackcolumns'
class Uuid(Func):
6252class Uuid(Func):
6253    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6254
6255    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6258class TimestampFromParts(Func):
6259    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6260    arg_types = {
6261        "year": True,
6262        "month": True,
6263        "day": True,
6264        "hour": True,
6265        "min": True,
6266        "sec": True,
6267        "nano": False,
6268        "zone": False,
6269        "milli": False,
6270    }
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):
6273class Upper(Func):
6274    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6277class Corr(Binary, AggFunc):
6278    pass
key = 'corr'
class Variance(AggFunc):
6281class Variance(AggFunc):
6282    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6285class VariancePop(AggFunc):
6286    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6289class CovarSamp(Binary, AggFunc):
6290    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6293class CovarPop(Binary, AggFunc):
6294    pass
key = 'covarpop'
class Week(Func):
6297class Week(Func):
6298    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6301class XMLTable(Func):
6302    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):
6305class Year(Func):
6306    pass
key = 'year'
class Use(Expression):
6309class Use(Expression):
6310    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(DML):
6313class Merge(DML):
6314    arg_types = {
6315        "this": True,
6316        "using": True,
6317        "on": True,
6318        "expressions": True,
6319        "with": False,
6320        "returning": False,
6321    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False, 'returning': False}
key = 'merge'
class When(Func):
6324class When(Func):
6325    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):
6330class NextValueFor(Func):
6331    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6336class Semicolon(Expression):
6337    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <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'>, 'APPLY': <class 'Apply'>, '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'>, 'SUBSTR': <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:
6377def maybe_parse(
6378    sql_or_expression: ExpOrStr,
6379    *,
6380    into: t.Optional[IntoType] = None,
6381    dialect: DialectType = None,
6382    prefix: t.Optional[str] = None,
6383    copy: bool = False,
6384    **opts,
6385) -> Expression:
6386    """Gracefully handle a possible string or expression.
6387
6388    Example:
6389        >>> maybe_parse("1")
6390        Literal(this=1, is_string=False)
6391        >>> maybe_parse(to_identifier("x"))
6392        Identifier(this=x, quoted=False)
6393
6394    Args:
6395        sql_or_expression: the SQL code string or an expression
6396        into: the SQLGlot Expression to parse into
6397        dialect: the dialect used to parse the input expressions (in the case that an
6398            input expression is a SQL string).
6399        prefix: a string to prefix the sql with before it gets parsed
6400            (automatically includes a space)
6401        copy: whether to copy the expression.
6402        **opts: other options to use to parse the input expressions (again, in the case
6403            that an input expression is a SQL string).
6404
6405    Returns:
6406        Expression: the parsed or given expression.
6407    """
6408    if isinstance(sql_or_expression, Expression):
6409        if copy:
6410            return sql_or_expression.copy()
6411        return sql_or_expression
6412
6413    if sql_or_expression is None:
6414        raise ParseError("SQL cannot be None")
6415
6416    import sqlglot
6417
6418    sql = str(sql_or_expression)
6419    if prefix:
6420        sql = f"{prefix} {sql}"
6421
6422    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):
6433def maybe_copy(instance, copy=True):
6434    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:
6655def union(
6656    left: ExpOrStr,
6657    right: ExpOrStr,
6658    distinct: bool = True,
6659    dialect: DialectType = None,
6660    copy: bool = True,
6661    **opts,
6662) -> Union:
6663    """
6664    Initializes a syntax tree from one UNION expression.
6665
6666    Example:
6667        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6668        'SELECT * FROM foo UNION SELECT * FROM bla'
6669
6670    Args:
6671        left: the SQL code string corresponding to the left-hand side.
6672            If an `Expression` instance is passed, it will be used as-is.
6673        right: the SQL code string corresponding to the right-hand side.
6674            If an `Expression` instance is passed, it will be used as-is.
6675        distinct: set the DISTINCT flag if and only if this is true.
6676        dialect: the dialect used to parse the input expression.
6677        copy: whether to copy the expression.
6678        opts: other options to use to parse the input expressions.
6679
6680    Returns:
6681        The new Union instance.
6682    """
6683    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6684    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6685
6686    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:
6689def intersect(
6690    left: ExpOrStr,
6691    right: ExpOrStr,
6692    distinct: bool = True,
6693    dialect: DialectType = None,
6694    copy: bool = True,
6695    **opts,
6696) -> Intersect:
6697    """
6698    Initializes a syntax tree from one INTERSECT expression.
6699
6700    Example:
6701        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6702        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6703
6704    Args:
6705        left: the SQL code string corresponding to the left-hand side.
6706            If an `Expression` instance is passed, it will be used as-is.
6707        right: the SQL code string corresponding to the right-hand side.
6708            If an `Expression` instance is passed, it will be used as-is.
6709        distinct: set the DISTINCT flag if and only if this is true.
6710        dialect: the dialect used to parse the input expression.
6711        copy: whether to copy the expression.
6712        opts: other options to use to parse the input expressions.
6713
6714    Returns:
6715        The new Intersect instance.
6716    """
6717    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6718    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6719
6720    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:
6723def except_(
6724    left: ExpOrStr,
6725    right: ExpOrStr,
6726    distinct: bool = True,
6727    dialect: DialectType = None,
6728    copy: bool = True,
6729    **opts,
6730) -> Except:
6731    """
6732    Initializes a syntax tree from one EXCEPT expression.
6733
6734    Example:
6735        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6736        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6737
6738    Args:
6739        left: the SQL code string corresponding to the left-hand side.
6740            If an `Expression` instance is passed, it will be used as-is.
6741        right: the SQL code string corresponding to the right-hand side.
6742            If an `Expression` instance is passed, it will be used as-is.
6743        distinct: set the DISTINCT flag if and only if this is true.
6744        dialect: the dialect used to parse the input expression.
6745        copy: whether to copy the expression.
6746        opts: other options to use to parse the input expressions.
6747
6748    Returns:
6749        The new Except instance.
6750    """
6751    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6752    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6753
6754    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:
6757def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6758    """
6759    Initializes a syntax tree from one or multiple SELECT expressions.
6760
6761    Example:
6762        >>> select("col1", "col2").from_("tbl").sql()
6763        'SELECT col1, col2 FROM tbl'
6764
6765    Args:
6766        *expressions: the SQL code string to parse as the expressions of a
6767            SELECT statement. If an Expression instance is passed, this is used as-is.
6768        dialect: the dialect used to parse the input expressions (in the case that an
6769            input expression is a SQL string).
6770        **opts: other options to use to parse the input expressions (again, in the case
6771            that an input expression is a SQL string).
6772
6773    Returns:
6774        Select: the syntax tree for the SELECT statement.
6775    """
6776    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:
6779def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6780    """
6781    Initializes a syntax tree from a FROM expression.
6782
6783    Example:
6784        >>> from_("tbl").select("col1", "col2").sql()
6785        'SELECT col1, col2 FROM tbl'
6786
6787    Args:
6788        *expression: the SQL code string to parse as the FROM expressions of a
6789            SELECT statement. If an Expression instance is passed, this is used as-is.
6790        dialect: the dialect used to parse the input expression (in the case that the
6791            input expression is a SQL string).
6792        **opts: other options to use to parse the input expressions (again, in the case
6793            that the input expression is a SQL string).
6794
6795    Returns:
6796        Select: the syntax tree for the SELECT statement.
6797    """
6798    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:
6801def update(
6802    table: str | Table,
6803    properties: dict,
6804    where: t.Optional[ExpOrStr] = None,
6805    from_: t.Optional[ExpOrStr] = None,
6806    dialect: DialectType = None,
6807    **opts,
6808) -> Update:
6809    """
6810    Creates an update statement.
6811
6812    Example:
6813        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6814        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6815
6816    Args:
6817        *properties: dictionary of properties to set which are
6818            auto converted to sql objects eg None -> NULL
6819        where: sql conditional parsed into a WHERE statement
6820        from_: sql statement parsed into a FROM statement
6821        dialect: the dialect used to parse the input expressions.
6822        **opts: other options to use to parse the input expressions.
6823
6824    Returns:
6825        Update: the syntax tree for the UPDATE statement.
6826    """
6827    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6828    update_expr.set(
6829        "expressions",
6830        [
6831            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6832            for k, v in properties.items()
6833        ],
6834    )
6835    if from_:
6836        update_expr.set(
6837            "from",
6838            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6839        )
6840    if isinstance(where, Condition):
6841        where = Where(this=where)
6842    if where:
6843        update_expr.set(
6844            "where",
6845            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6846        )
6847    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:
6850def delete(
6851    table: ExpOrStr,
6852    where: t.Optional[ExpOrStr] = None,
6853    returning: t.Optional[ExpOrStr] = None,
6854    dialect: DialectType = None,
6855    **opts,
6856) -> Delete:
6857    """
6858    Builds a delete statement.
6859
6860    Example:
6861        >>> delete("my_table", where="id > 1").sql()
6862        'DELETE FROM my_table WHERE id > 1'
6863
6864    Args:
6865        where: sql conditional parsed into a WHERE statement
6866        returning: sql conditional parsed into a RETURNING statement
6867        dialect: the dialect used to parse the input expressions.
6868        **opts: other options to use to parse the input expressions.
6869
6870    Returns:
6871        Delete: the syntax tree for the DELETE statement.
6872    """
6873    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6874    if where:
6875        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6876    if returning:
6877        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6878    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:
6881def insert(
6882    expression: ExpOrStr,
6883    into: ExpOrStr,
6884    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6885    overwrite: t.Optional[bool] = None,
6886    returning: t.Optional[ExpOrStr] = None,
6887    dialect: DialectType = None,
6888    copy: bool = True,
6889    **opts,
6890) -> Insert:
6891    """
6892    Builds an INSERT statement.
6893
6894    Example:
6895        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6896        'INSERT INTO tbl VALUES (1, 2, 3)'
6897
6898    Args:
6899        expression: the sql string or expression of the INSERT statement
6900        into: the tbl to insert data to.
6901        columns: optionally the table's column names.
6902        overwrite: whether to INSERT OVERWRITE or not.
6903        returning: sql conditional parsed into a RETURNING statement
6904        dialect: the dialect used to parse the input expressions.
6905        copy: whether to copy the expression.
6906        **opts: other options to use to parse the input expressions.
6907
6908    Returns:
6909        Insert: the syntax tree for the INSERT statement.
6910    """
6911    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6912    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6913
6914    if columns:
6915        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6916
6917    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6918
6919    if returning:
6920        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
6921
6922    return insert

Builds an INSERT statement.

Example:
>>> insert("VALUES (1, 2, 3)", "tbl").sql()
'INSERT INTO tbl VALUES (1, 2, 3)'
Arguments:
  • expression: the sql string or expression of the INSERT statement
  • into: the tbl to insert data to.
  • columns: optionally the table's column names.
  • overwrite: whether to INSERT OVERWRITE or not.
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • copy: whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Insert: the syntax tree for the INSERT statement.

def merge( *when_exprs: Union[str, Expression], into: Union[str, Expression], using: Union[str, Expression], on: Union[str, Expression], returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
6925def merge(
6926    *when_exprs: ExpOrStr,
6927    into: ExpOrStr,
6928    using: ExpOrStr,
6929    on: ExpOrStr,
6930    returning: t.Optional[ExpOrStr] = None,
6931    dialect: DialectType = None,
6932    copy: bool = True,
6933    **opts,
6934) -> Merge:
6935    """
6936    Builds a MERGE statement.
6937
6938    Example:
6939        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
6940        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
6941        ...       into="my_table",
6942        ...       using="source_table",
6943        ...       on="my_table.id = source_table.id").sql()
6944        '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)'
6945
6946    Args:
6947        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
6948        into: The target table to merge data into.
6949        using: The source table to merge data from.
6950        on: The join condition for the merge.
6951        returning: The columns to return from the merge.
6952        dialect: The dialect used to parse the input expressions.
6953        copy: Whether to copy the expression.
6954        **opts: Other options to use to parse the input expressions.
6955
6956    Returns:
6957        Merge: The syntax tree for the MERGE statement.
6958    """
6959    merge = Merge(
6960        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
6961        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
6962        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
6963        expressions=[
6964            maybe_parse(when_expr, dialect=dialect, copy=copy, into=When, **opts)
6965            for when_expr in when_exprs
6966        ],
6967    )
6968    if returning:
6969        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
6970
6971    return merge

Builds a MERGE statement.

Example:
>>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
...       into="my_table",
...       using="source_table",
...       on="my_table.id = source_table.id").sql()
'MERGE INTO my_table USING source_table ON my_table.id = source_table.id WHEN MATCHED THEN UPDATE SET col1 = source_table.col1 WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)'
Arguments:
  • *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
  • into: The target table to merge data into.
  • using: The source table to merge data from.
  • on: The join condition for the merge.
  • returning: The columns to return from the merge.
  • dialect: The dialect used to parse the input expressions.
  • copy: Whether to copy the expression.
  • **opts: Other options to use to parse the input expressions.
Returns:

Merge: The syntax tree for the MERGE statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
6974def condition(
6975    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6976) -> Condition:
6977    """
6978    Initialize a logical condition expression.
6979
6980    Example:
6981        >>> condition("x=1").sql()
6982        'x = 1'
6983
6984        This is helpful for composing larger logical syntax trees:
6985        >>> where = condition("x=1")
6986        >>> where = where.and_("y=1")
6987        >>> Select().from_("tbl").select("*").where(where).sql()
6988        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6989
6990    Args:
6991        *expression: the SQL code string to parse.
6992            If an Expression instance is passed, this is used as-is.
6993        dialect: the dialect used to parse the input expression (in the case that the
6994            input expression is a SQL string).
6995        copy: Whether to copy `expression` (only applies to expressions).
6996        **opts: other options to use to parse the input expressions (again, in the case
6997            that the input expression is a SQL string).
6998
6999    Returns:
7000        The new Condition instance
7001    """
7002    return maybe_parse(
7003        expression,
7004        into=Condition,
7005        dialect=dialect,
7006        copy=copy,
7007        **opts,
7008    )

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:
7011def and_(
7012    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7013) -> Condition:
7014    """
7015    Combine multiple conditions with an AND logical operator.
7016
7017    Example:
7018        >>> and_("x=1", and_("y=1", "z=1")).sql()
7019        'x = 1 AND (y = 1 AND 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, 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:
7034def or_(
7035    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7036) -> Condition:
7037    """
7038    Combine multiple conditions with an OR logical operator.
7039
7040    Example:
7041        >>> or_("x=1", or_("y=1", "z=1")).sql()
7042        'x = 1 OR (y = 1 OR z = 1)'
7043
7044    Args:
7045        *expressions: the SQL code strings to parse.
7046            If an Expression instance is passed, this is used as-is.
7047        dialect: the dialect used to parse the input expression.
7048        copy: whether to copy `expressions` (only applies to Expressions).
7049        **opts: other options to use to parse the input expressions.
7050
7051    Returns:
7052        The new condition
7053    """
7054    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:
7057def xor(
7058    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7059) -> Condition:
7060    """
7061    Combine multiple conditions with an XOR logical operator.
7062
7063    Example:
7064        >>> xor("x=1", xor("y=1", "z=1")).sql()
7065        'x = 1 XOR (y = 1 XOR z = 1)'
7066
7067    Args:
7068        *expressions: the SQL code strings to parse.
7069            If an Expression instance is passed, this is used as-is.
7070        dialect: the dialect used to parse the input expression.
7071        copy: whether to copy `expressions` (only applies to Expressions).
7072        **opts: other options to use to parse the input expressions.
7073
7074    Returns:
7075        The new condition
7076    """
7077    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:
7080def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7081    """
7082    Wrap a condition with a NOT operator.
7083
7084    Example:
7085        >>> not_("this_suit='black'").sql()
7086        "NOT this_suit = 'black'"
7087
7088    Args:
7089        expression: the SQL code string to parse.
7090            If an Expression instance is passed, this is used as-is.
7091        dialect: the dialect used to parse the input expression.
7092        copy: whether to copy the expression or not.
7093        **opts: other options to use to parse the input expressions.
7094
7095    Returns:
7096        The new condition.
7097    """
7098    this = condition(
7099        expression,
7100        dialect=dialect,
7101        copy=copy,
7102        **opts,
7103    )
7104    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:
7107def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7108    """
7109    Wrap an expression in parentheses.
7110
7111    Example:
7112        >>> paren("5 + 3").sql()
7113        '(5 + 3)'
7114
7115    Args:
7116        expression: the SQL code string to parse.
7117            If an Expression instance is passed, this is used as-is.
7118        copy: whether to copy the expression or not.
7119
7120    Returns:
7121        The wrapped expression.
7122    """
7123    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):
7139def to_identifier(name, quoted=None, copy=True):
7140    """Builds an identifier.
7141
7142    Args:
7143        name: The name to turn into an identifier.
7144        quoted: Whether to force quote the identifier.
7145        copy: Whether to copy name if it's an Identifier.
7146
7147    Returns:
7148        The identifier ast node.
7149    """
7150
7151    if name is None:
7152        return None
7153
7154    if isinstance(name, Identifier):
7155        identifier = maybe_copy(name, copy)
7156    elif isinstance(name, str):
7157        identifier = Identifier(
7158            this=name,
7159            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7160        )
7161    else:
7162        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7163    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:
7166def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7167    """
7168    Parses a given string into an identifier.
7169
7170    Args:
7171        name: The name to parse into an identifier.
7172        dialect: The dialect to parse against.
7173
7174    Returns:
7175        The identifier ast node.
7176    """
7177    try:
7178        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7179    except (ParseError, TokenError):
7180        expression = to_identifier(name)
7181
7182    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:
7188def to_interval(interval: str | Literal) -> Interval:
7189    """Builds an interval expression from a string like '1 day' or '5 months'."""
7190    if isinstance(interval, Literal):
7191        if not interval.is_string:
7192            raise ValueError("Invalid interval string.")
7193
7194        interval = interval.this
7195
7196    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
7197
7198    if not interval_parts:
7199        raise ValueError("Invalid interval string.")
7200
7201    return Interval(
7202        this=Literal.string(interval_parts.group(1)),
7203        unit=Var(this=interval_parts.group(2).upper()),
7204    )

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:
7207def to_table(
7208    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7209) -> Table:
7210    """
7211    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7212    If a table is passed in then that table is returned.
7213
7214    Args:
7215        sql_path: a `[catalog].[schema].[table]` string.
7216        dialect: the source dialect according to which the table name will be parsed.
7217        copy: Whether to copy a table if it is passed in.
7218        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7219
7220    Returns:
7221        A table expression.
7222    """
7223    if isinstance(sql_path, Table):
7224        return maybe_copy(sql_path, copy=copy)
7225
7226    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7227
7228    for k, v in kwargs.items():
7229        table.set(k, v)
7230
7231    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:
7234def to_column(
7235    sql_path: str | Column,
7236    quoted: t.Optional[bool] = None,
7237    dialect: DialectType = None,
7238    copy: bool = True,
7239    **kwargs,
7240) -> Column:
7241    """
7242    Create a column from a `[table].[column]` sql path. Table is optional.
7243    If a column is passed in then that column is returned.
7244
7245    Args:
7246        sql_path: a `[table].[column]` string.
7247        quoted: Whether or not to force quote identifiers.
7248        dialect: the source dialect according to which the column name will be parsed.
7249        copy: Whether to copy a column if it is passed in.
7250        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7251
7252    Returns:
7253        A column expression.
7254    """
7255    if isinstance(sql_path, Column):
7256        return maybe_copy(sql_path, copy=copy)
7257
7258    try:
7259        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7260    except ParseError:
7261        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7262
7263    for k, v in kwargs.items():
7264        col.set(k, v)
7265
7266    if quoted:
7267        for i in col.find_all(Identifier):
7268            i.set("quoted", True)
7269
7270    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):
7273def alias_(
7274    expression: ExpOrStr,
7275    alias: t.Optional[str | Identifier],
7276    table: bool | t.Sequence[str | Identifier] = False,
7277    quoted: t.Optional[bool] = None,
7278    dialect: DialectType = None,
7279    copy: bool = True,
7280    **opts,
7281):
7282    """Create an Alias expression.
7283
7284    Example:
7285        >>> alias_('foo', 'bar').sql()
7286        'foo AS bar'
7287
7288        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7289        '(SELECT 1, 2) AS bar(a, b)'
7290
7291    Args:
7292        expression: the SQL code strings to parse.
7293            If an Expression instance is passed, this is used as-is.
7294        alias: the alias name to use. If the name has
7295            special characters it is quoted.
7296        table: Whether to create a table alias, can also be a list of columns.
7297        quoted: whether to quote the alias
7298        dialect: the dialect used to parse the input expression.
7299        copy: Whether to copy the expression.
7300        **opts: other options to use to parse the input expressions.
7301
7302    Returns:
7303        Alias: the aliased expression
7304    """
7305    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7306    alias = to_identifier(alias, quoted=quoted)
7307
7308    if table:
7309        table_alias = TableAlias(this=alias)
7310        exp.set("alias", table_alias)
7311
7312        if not isinstance(table, bool):
7313            for column in table:
7314                table_alias.append("columns", to_identifier(column, quoted=quoted))
7315
7316        return exp
7317
7318    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7319    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7320    # for the complete Window expression.
7321    #
7322    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7323
7324    if "alias" in exp.arg_types and not isinstance(exp, Window):
7325        exp.set("alias", alias)
7326        return exp
7327    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:
7330def subquery(
7331    expression: ExpOrStr,
7332    alias: t.Optional[Identifier | str] = None,
7333    dialect: DialectType = None,
7334    **opts,
7335) -> Select:
7336    """
7337    Build a subquery expression that's selected from.
7338
7339    Example:
7340        >>> subquery('select x from tbl', 'bar').select('x').sql()
7341        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7342
7343    Args:
7344        expression: the SQL code strings to parse.
7345            If an Expression instance is passed, this is used as-is.
7346        alias: the alias name to use.
7347        dialect: the dialect used to parse the input expression.
7348        **opts: other options to use to parse the input expressions.
7349
7350    Returns:
7351        A new Select instance with the subquery expression included.
7352    """
7353
7354    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7355    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):
7386def column(
7387    col,
7388    table=None,
7389    db=None,
7390    catalog=None,
7391    *,
7392    fields=None,
7393    quoted=None,
7394    copy=True,
7395):
7396    """
7397    Build a Column.
7398
7399    Args:
7400        col: Column name.
7401        table: Table name.
7402        db: Database name.
7403        catalog: Catalog name.
7404        fields: Additional fields using dots.
7405        quoted: Whether to force quotes on the column's identifiers.
7406        copy: Whether to copy identifiers if passed in.
7407
7408    Returns:
7409        The new Column instance.
7410    """
7411    this = Column(
7412        this=to_identifier(col, quoted=quoted, copy=copy),
7413        table=to_identifier(table, quoted=quoted, copy=copy),
7414        db=to_identifier(db, quoted=quoted, copy=copy),
7415        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7416    )
7417
7418    if fields:
7419        this = Dot.build(
7420            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7421        )
7422    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:
7425def cast(
7426    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7427) -> Cast:
7428    """Cast an expression to a data type.
7429
7430    Example:
7431        >>> cast('x + 1', 'int').sql()
7432        'CAST(x + 1 AS INT)'
7433
7434    Args:
7435        expression: The expression to cast.
7436        to: The datatype to cast to.
7437        copy: Whether to copy the supplied expressions.
7438        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7439            - The expression to be cast is already a exp.Cast expression
7440            - The existing cast is to a type that is logically equivalent to new type
7441
7442            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7443            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7444            and instead just return the original expression `CAST(x as DATETIME)`.
7445
7446            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7447            mapping is applied in the target dialect generator.
7448
7449    Returns:
7450        The new Cast instance.
7451    """
7452    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
7453    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
7454
7455    # dont re-cast if the expression is already a cast to the correct type
7456    if isinstance(expr, Cast):
7457        from sqlglot.dialects.dialect import Dialect
7458
7459        target_dialect = Dialect.get_or_raise(dialect)
7460        type_mapping = target_dialect.generator_class.TYPE_MAPPING
7461
7462        existing_cast_type: DataType.Type = expr.to.this
7463        new_cast_type: DataType.Type = data_type.this
7464        types_are_equivalent = type_mapping.get(
7465            existing_cast_type, existing_cast_type
7466        ) == type_mapping.get(new_cast_type, new_cast_type)
7467        if expr.is_type(data_type) or types_are_equivalent:
7468            return expr
7469
7470    expr = Cast(this=expr, to=data_type)
7471    expr.type = data_type
7472
7473    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:
7476def table_(
7477    table: Identifier | str,
7478    db: t.Optional[Identifier | str] = None,
7479    catalog: t.Optional[Identifier | str] = None,
7480    quoted: t.Optional[bool] = None,
7481    alias: t.Optional[Identifier | str] = None,
7482) -> Table:
7483    """Build a Table.
7484
7485    Args:
7486        table: Table name.
7487        db: Database name.
7488        catalog: Catalog name.
7489        quote: Whether to force quotes on the table's identifiers.
7490        alias: Table's alias.
7491
7492    Returns:
7493        The new Table instance.
7494    """
7495    return Table(
7496        this=to_identifier(table, quoted=quoted) if table else None,
7497        db=to_identifier(db, quoted=quoted) if db else None,
7498        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7499        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7500    )

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:
7503def values(
7504    values: t.Iterable[t.Tuple[t.Any, ...]],
7505    alias: t.Optional[str] = None,
7506    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7507) -> Values:
7508    """Build VALUES statement.
7509
7510    Example:
7511        >>> values([(1, '2')]).sql()
7512        "VALUES (1, '2')"
7513
7514    Args:
7515        values: values statements that will be converted to SQL
7516        alias: optional alias
7517        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7518         If either are provided then an alias is also required.
7519
7520    Returns:
7521        Values: the Values expression object
7522    """
7523    if columns and not alias:
7524        raise ValueError("Alias is required when providing columns")
7525
7526    return Values(
7527        expressions=[convert(tup) for tup in values],
7528        alias=(
7529            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7530            if columns
7531            else (TableAlias(this=to_identifier(alias)) if alias else None)
7532        ),
7533    )

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:
7536def var(name: t.Optional[ExpOrStr]) -> Var:
7537    """Build a SQL variable.
7538
7539    Example:
7540        >>> repr(var('x'))
7541        'Var(this=x)'
7542
7543        >>> repr(var(column('x', table='y')))
7544        'Var(this=x)'
7545
7546    Args:
7547        name: The name of the var or an expression who's name will become the var.
7548
7549    Returns:
7550        The new variable node.
7551    """
7552    if not name:
7553        raise ValueError("Cannot convert empty name into var.")
7554
7555    if isinstance(name, Expression):
7556        name = name.name
7557    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:
7560def rename_table(
7561    old_name: str | Table,
7562    new_name: str | Table,
7563    dialect: DialectType = None,
7564) -> Alter:
7565    """Build ALTER TABLE... RENAME... expression
7566
7567    Args:
7568        old_name: The old name of the table
7569        new_name: The new name of the table
7570        dialect: The dialect to parse the table.
7571
7572    Returns:
7573        Alter table expression
7574    """
7575    old_table = to_table(old_name, dialect=dialect)
7576    new_table = to_table(new_name, dialect=dialect)
7577    return Alter(
7578        this=old_table,
7579        kind="TABLE",
7580        actions=[
7581            RenameTable(this=new_table),
7582        ],
7583    )

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:
7586def rename_column(
7587    table_name: str | Table,
7588    old_column_name: str | Column,
7589    new_column_name: str | Column,
7590    exists: t.Optional[bool] = None,
7591    dialect: DialectType = None,
7592) -> Alter:
7593    """Build ALTER TABLE... RENAME COLUMN... expression
7594
7595    Args:
7596        table_name: Name of the table
7597        old_column: The old name of the column
7598        new_column: The new name of the column
7599        exists: Whether to add the `IF EXISTS` clause
7600        dialect: The dialect to parse the table/column.
7601
7602    Returns:
7603        Alter table expression
7604    """
7605    table = to_table(table_name, dialect=dialect)
7606    old_column = to_column(old_column_name, dialect=dialect)
7607    new_column = to_column(new_column_name, dialect=dialect)
7608    return Alter(
7609        this=table,
7610        kind="TABLE",
7611        actions=[
7612            RenameColumn(this=old_column, to=new_column, exists=exists),
7613        ],
7614    )

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

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:
7751def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7752    """Get the full name of a table as a string.
7753
7754    Args:
7755        table: Table expression node or string.
7756        dialect: The dialect to generate the table name for.
7757        identify: Determines when an identifier should be quoted. Possible values are:
7758            False (default): Never quote, except in cases where it's mandatory by the dialect.
7759            True: Always quote.
7760
7761    Examples:
7762        >>> from sqlglot import exp, parse_one
7763        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7764        'a.b.c'
7765
7766    Returns:
7767        The table name.
7768    """
7769
7770    table = maybe_parse(table, into=Table, dialect=dialect)
7771
7772    if not table:
7773        raise ValueError(f"Cannot parse {table}")
7774
7775    return ".".join(
7776        (
7777            part.sql(dialect=dialect, identify=True, copy=False)
7778            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7779            else part.name
7780        )
7781        for part in table.parts
7782    )

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:
7785def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7786    """Returns a case normalized table name without quotes.
7787
7788    Args:
7789        table: the table to normalize
7790        dialect: the dialect to use for normalization rules
7791        copy: whether to copy the expression.
7792
7793    Examples:
7794        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7795        'A-B.c'
7796    """
7797    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7798
7799    return ".".join(
7800        p.name
7801        for p in normalize_identifiers(
7802            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7803        ).parts
7804    )

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:
7807def replace_tables(
7808    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7809) -> E:
7810    """Replace all tables in expression according to the mapping.
7811
7812    Args:
7813        expression: expression node to be transformed and replaced.
7814        mapping: mapping of table names.
7815        dialect: the dialect of the mapping table
7816        copy: whether to copy the expression.
7817
7818    Examples:
7819        >>> from sqlglot import exp, parse_one
7820        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7821        'SELECT * FROM c /* a.b */'
7822
7823    Returns:
7824        The mapped expression.
7825    """
7826
7827    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7828
7829    def _replace_tables(node: Expression) -> Expression:
7830        if isinstance(node, Table):
7831            original = normalize_table_name(node, dialect=dialect)
7832            new_name = mapping.get(original)
7833
7834            if new_name:
7835                table = to_table(
7836                    new_name,
7837                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7838                    dialect=dialect,
7839                )
7840                table.add_comments([original])
7841                return table
7842        return node
7843
7844    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:
7847def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7848    """Replace placeholders in an expression.
7849
7850    Args:
7851        expression: expression node to be transformed and replaced.
7852        args: positional names that will substitute unnamed placeholders in the given order.
7853        kwargs: keyword arguments that will substitute named placeholders.
7854
7855    Examples:
7856        >>> from sqlglot import exp, parse_one
7857        >>> replace_placeholders(
7858        ...     parse_one("select * from :tbl where ? = ?"),
7859        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7860        ... ).sql()
7861        "SELECT * FROM foo WHERE str_col = 'b'"
7862
7863    Returns:
7864        The mapped expression.
7865    """
7866
7867    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7868        if isinstance(node, Placeholder):
7869            if node.this:
7870                new_name = kwargs.get(node.this)
7871                if new_name is not None:
7872                    return convert(new_name)
7873            else:
7874                try:
7875                    return convert(next(args))
7876                except StopIteration:
7877                    pass
7878        return node
7879
7880    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:
7883def expand(
7884    expression: Expression,
7885    sources: t.Dict[str, Query],
7886    dialect: DialectType = None,
7887    copy: bool = True,
7888) -> Expression:
7889    """Transforms an expression by expanding all referenced sources into subqueries.
7890
7891    Examples:
7892        >>> from sqlglot import parse_one
7893        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7894        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7895
7896        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7897        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7898
7899    Args:
7900        expression: The expression to expand.
7901        sources: A dictionary of name to Queries.
7902        dialect: The dialect of the sources dict.
7903        copy: Whether to copy the expression during transformation. Defaults to True.
7904
7905    Returns:
7906        The transformed expression.
7907    """
7908    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7909
7910    def _expand(node: Expression):
7911        if isinstance(node, Table):
7912            name = normalize_table_name(node, dialect=dialect)
7913            source = sources.get(name)
7914            if source:
7915                subquery = source.subquery(node.alias or name)
7916                subquery.comments = [f"source: {name}"]
7917                return subquery.transform(_expand, copy=False)
7918        return node
7919
7920    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:
7923def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7924    """
7925    Returns a Func expression.
7926
7927    Examples:
7928        >>> func("abs", 5).sql()
7929        'ABS(5)'
7930
7931        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7932        'CAST(5 AS DOUBLE)'
7933
7934    Args:
7935        name: the name of the function to build.
7936        args: the args used to instantiate the function of interest.
7937        copy: whether to copy the argument expressions.
7938        dialect: the source dialect.
7939        kwargs: the kwargs used to instantiate the function of interest.
7940
7941    Note:
7942        The arguments `args` and `kwargs` are mutually exclusive.
7943
7944    Returns:
7945        An instance of the function of interest, or an anonymous function, if `name` doesn't
7946        correspond to an existing `sqlglot.expressions.Func` class.
7947    """
7948    if args and kwargs:
7949        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7950
7951    from sqlglot.dialects.dialect import Dialect
7952
7953    dialect = Dialect.get_or_raise(dialect)
7954
7955    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7956    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7957
7958    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7959    if constructor:
7960        if converted:
7961            if "dialect" in constructor.__code__.co_varnames:
7962                function = constructor(converted, dialect=dialect)
7963            else:
7964                function = constructor(converted)
7965        elif constructor.__name__ == "from_arg_list":
7966            function = constructor.__self__(**kwargs)  # type: ignore
7967        else:
7968            constructor = FUNCTION_BY_NAME.get(name.upper())
7969            if constructor:
7970                function = constructor(**kwargs)
7971            else:
7972                raise ValueError(
7973                    f"Unable to convert '{name}' into a Func. Either manually construct "
7974                    "the Func expression of interest or parse the function call."
7975                )
7976    else:
7977        kwargs = kwargs or {"expressions": converted}
7978        function = Anonymous(this=name, **kwargs)
7979
7980    for error_message in function.error_messages(converted):
7981        raise ValueError(error_message)
7982
7983    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:
7986def case(
7987    expression: t.Optional[ExpOrStr] = None,
7988    **opts,
7989) -> Case:
7990    """
7991    Initialize a CASE statement.
7992
7993    Example:
7994        case().when("a = 1", "foo").else_("bar")
7995
7996    Args:
7997        expression: Optionally, the input expression (not all dialects support this)
7998        **opts: Extra keyword arguments for parsing `expression`
7999    """
8000    if expression is not None:
8001        this = maybe_parse(expression, **opts)
8002    else:
8003        this = None
8004    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:
8007def array(
8008    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8009) -> Array:
8010    """
8011    Returns an array.
8012
8013    Examples:
8014        >>> array(1, 'x').sql()
8015        'ARRAY(1, x)'
8016
8017    Args:
8018        expressions: the expressions to add to the array.
8019        copy: whether to copy the argument expressions.
8020        dialect: the source dialect.
8021        kwargs: the kwargs used to instantiate the function of interest.
8022
8023    Returns:
8024        An array expression.
8025    """
8026    return Array(
8027        expressions=[
8028            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8029            for expression in expressions
8030        ]
8031    )

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:
8034def tuple_(
8035    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8036) -> Tuple:
8037    """
8038    Returns an tuple.
8039
8040    Examples:
8041        >>> tuple_(1, 'x').sql()
8042        '(1, x)'
8043
8044    Args:
8045        expressions: the expressions to add to the tuple.
8046        copy: whether to copy the argument expressions.
8047        dialect: the source dialect.
8048        kwargs: the kwargs used to instantiate the function of interest.
8049
8050    Returns:
8051        A tuple expression.
8052    """
8053    return Tuple(
8054        expressions=[
8055            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8056            for expression in expressions
8057        ]
8058    )

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:
8061def true() -> Boolean:
8062    """
8063    Returns a true Boolean expression.
8064    """
8065    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8068def false() -> Boolean:
8069    """
8070    Returns a false Boolean expression.
8071    """
8072    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8075def null() -> Null:
8076    """
8077    Returns a Null expression.
8078    """
8079    return Null()

Returns a Null expression.

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