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
4987class Columns(Func):
4988    arg_types = {"this": True, "unpack": False}
4989
4990
4991# https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#syntax
4992class Convert(Func):
4993    arg_types = {"this": True, "expression": True, "style": False}
4994
4995
4996class ConvertTimezone(Func):
4997    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
4998
4999
5000class GenerateSeries(Func):
5001    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
5002
5003
5004# Postgres' GENERATE_SERIES function returns a row set, i.e. it implicitly explodes when it's
5005# used in a projection, so this expression is a helper that facilitates transpilation to other
5006# dialects. For example, we'd generate UNNEST(GENERATE_SERIES(...)) in DuckDB
5007class ExplodingGenerateSeries(GenerateSeries):
5008    pass
5009
5010
5011class ArrayAgg(AggFunc):
5012    arg_types = {"this": True, "nulls_excluded": False}
5013
5014
5015class ArrayUniqueAgg(AggFunc):
5016    pass
5017
5018
5019class ArrayAll(Func):
5020    arg_types = {"this": True, "expression": True}
5021
5022
5023# Represents Python's `any(f(x) for x in array)`, where `array` is `this` and `f` is `expression`
5024class ArrayAny(Func):
5025    arg_types = {"this": True, "expression": True}
5026
5027
5028class ArrayConcat(Func):
5029    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5030    arg_types = {"this": True, "expressions": False}
5031    is_var_len_args = True
5032
5033
5034class ArrayConstructCompact(Func):
5035    arg_types = {"expressions": True}
5036    is_var_len_args = True
5037
5038
5039class ArrayContains(Binary, Func):
5040    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
5041
5042
5043class ArrayContainsAll(Binary, Func):
5044    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
5045
5046
5047class ArrayFilter(Func):
5048    arg_types = {"this": True, "expression": True}
5049    _sql_names = ["FILTER", "ARRAY_FILTER"]
5050
5051
5052class ArrayToString(Func):
5053    arg_types = {"this": True, "expression": True, "null": False}
5054    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
5055
5056
5057class StringToArray(Func):
5058    arg_types = {"this": True, "expression": True, "null": False}
5059    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
5060
5061
5062class ArrayOverlaps(Binary, Func):
5063    pass
5064
5065
5066class ArraySize(Func):
5067    arg_types = {"this": True, "expression": False}
5068    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
5069
5070
5071class ArraySort(Func):
5072    arg_types = {"this": True, "expression": False}
5073
5074
5075class ArraySum(Func):
5076    arg_types = {"this": True, "expression": False}
5077
5078
5079class ArrayUnionAgg(AggFunc):
5080    pass
5081
5082
5083class Avg(AggFunc):
5084    pass
5085
5086
5087class AnyValue(AggFunc):
5088    pass
5089
5090
5091class Lag(AggFunc):
5092    arg_types = {"this": True, "offset": False, "default": False}
5093
5094
5095class Lead(AggFunc):
5096    arg_types = {"this": True, "offset": False, "default": False}
5097
5098
5099# some dialects have a distinction between first and first_value, usually first is an aggregate func
5100# and first_value is a window func
5101class First(AggFunc):
5102    pass
5103
5104
5105class Last(AggFunc):
5106    pass
5107
5108
5109class FirstValue(AggFunc):
5110    pass
5111
5112
5113class LastValue(AggFunc):
5114    pass
5115
5116
5117class NthValue(AggFunc):
5118    arg_types = {"this": True, "offset": True}
5119
5120
5121class Case(Func):
5122    arg_types = {"this": False, "ifs": True, "default": False}
5123
5124    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5125        instance = maybe_copy(self, copy)
5126        instance.append(
5127            "ifs",
5128            If(
5129                this=maybe_parse(condition, copy=copy, **opts),
5130                true=maybe_parse(then, copy=copy, **opts),
5131            ),
5132        )
5133        return instance
5134
5135    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5136        instance = maybe_copy(self, copy)
5137        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5138        return instance
5139
5140
5141class Cast(Func):
5142    arg_types = {
5143        "this": True,
5144        "to": True,
5145        "format": False,
5146        "safe": False,
5147        "action": False,
5148    }
5149
5150    @property
5151    def name(self) -> str:
5152        return self.this.name
5153
5154    @property
5155    def to(self) -> DataType:
5156        return self.args["to"]
5157
5158    @property
5159    def output_name(self) -> str:
5160        return self.name
5161
5162    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5163        """
5164        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5165        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5166        array<int> != array<float>.
5167
5168        Args:
5169            dtypes: the data types to compare this Cast's DataType to.
5170
5171        Returns:
5172            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5173        """
5174        return self.to.is_type(*dtypes)
5175
5176
5177class TryCast(Cast):
5178    pass
5179
5180
5181class Try(Func):
5182    pass
5183
5184
5185class CastToStrType(Func):
5186    arg_types = {"this": True, "to": True}
5187
5188
5189class Collate(Binary, Func):
5190    pass
5191
5192
5193class Ceil(Func):
5194    arg_types = {"this": True, "decimals": False}
5195    _sql_names = ["CEIL", "CEILING"]
5196
5197
5198class Coalesce(Func):
5199    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5200    is_var_len_args = True
5201    _sql_names = ["COALESCE", "IFNULL", "NVL"]
5202
5203
5204class Chr(Func):
5205    arg_types = {"expressions": True, "charset": False}
5206    is_var_len_args = True
5207    _sql_names = ["CHR", "CHAR"]
5208
5209
5210class Concat(Func):
5211    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5212    is_var_len_args = True
5213
5214
5215class ConcatWs(Concat):
5216    _sql_names = ["CONCAT_WS"]
5217
5218
5219# https://docs.oracle.com/cd/B13789_01/server.101/b10759/operators004.htm#i1035022
5220class ConnectByRoot(Func):
5221    pass
5222
5223
5224class Count(AggFunc):
5225    arg_types = {"this": False, "expressions": False, "big_int": False}
5226    is_var_len_args = True
5227
5228
5229class CountIf(AggFunc):
5230    _sql_names = ["COUNT_IF", "COUNTIF"]
5231
5232
5233# cube root
5234class Cbrt(Func):
5235    pass
5236
5237
5238class CurrentDate(Func):
5239    arg_types = {"this": False}
5240
5241
5242class CurrentDatetime(Func):
5243    arg_types = {"this": False}
5244
5245
5246class CurrentTime(Func):
5247    arg_types = {"this": False}
5248
5249
5250class CurrentTimestamp(Func):
5251    arg_types = {"this": False, "sysdate": False}
5252
5253
5254class CurrentUser(Func):
5255    arg_types = {"this": False}
5256
5257
5258class DateAdd(Func, IntervalOp):
5259    arg_types = {"this": True, "expression": True, "unit": False}
5260
5261
5262class DateSub(Func, IntervalOp):
5263    arg_types = {"this": True, "expression": True, "unit": False}
5264
5265
5266class DateDiff(Func, TimeUnit):
5267    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5268    arg_types = {"this": True, "expression": True, "unit": False}
5269
5270
5271class DateTrunc(Func):
5272    arg_types = {"unit": True, "this": True, "zone": False}
5273
5274    def __init__(self, **args):
5275        unit = args.get("unit")
5276        if isinstance(unit, TimeUnit.VAR_LIKE):
5277            args["unit"] = Literal.string(
5278                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5279            )
5280        elif isinstance(unit, Week):
5281            unit.set("this", Literal.string(unit.this.name.upper()))
5282
5283        super().__init__(**args)
5284
5285    @property
5286    def unit(self) -> Expression:
5287        return self.args["unit"]
5288
5289
5290# https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions#datetime
5291# expression can either be time_expr or time_zone
5292class Datetime(Func):
5293    arg_types = {"this": True, "expression": False}
5294
5295
5296class DatetimeAdd(Func, IntervalOp):
5297    arg_types = {"this": True, "expression": True, "unit": False}
5298
5299
5300class DatetimeSub(Func, IntervalOp):
5301    arg_types = {"this": True, "expression": True, "unit": False}
5302
5303
5304class DatetimeDiff(Func, TimeUnit):
5305    arg_types = {"this": True, "expression": True, "unit": False}
5306
5307
5308class DatetimeTrunc(Func, TimeUnit):
5309    arg_types = {"this": True, "unit": True, "zone": False}
5310
5311
5312class DayOfWeek(Func):
5313    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
5314
5315
5316# https://duckdb.org/docs/sql/functions/datepart.html#part-specifiers-only-usable-as-date-part-specifiers
5317# ISO day of week function in duckdb is ISODOW
5318class DayOfWeekIso(Func):
5319    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
5320
5321
5322class DayOfMonth(Func):
5323    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
5324
5325
5326class DayOfYear(Func):
5327    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
5328
5329
5330class ToDays(Func):
5331    pass
5332
5333
5334class WeekOfYear(Func):
5335    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
5336
5337
5338class MonthsBetween(Func):
5339    arg_types = {"this": True, "expression": True, "roundoff": False}
5340
5341
5342class LastDay(Func, TimeUnit):
5343    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5344    arg_types = {"this": True, "unit": False}
5345
5346
5347class Extract(Func):
5348    arg_types = {"this": True, "expression": True}
5349
5350
5351class Timestamp(Func):
5352    arg_types = {"this": False, "zone": False, "with_tz": False}
5353
5354
5355class TimestampAdd(Func, TimeUnit):
5356    arg_types = {"this": True, "expression": True, "unit": False}
5357
5358
5359class TimestampSub(Func, TimeUnit):
5360    arg_types = {"this": True, "expression": True, "unit": False}
5361
5362
5363class TimestampDiff(Func, TimeUnit):
5364    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5365    arg_types = {"this": True, "expression": True, "unit": False}
5366
5367
5368class TimestampTrunc(Func, TimeUnit):
5369    arg_types = {"this": True, "unit": True, "zone": False}
5370
5371
5372class TimeAdd(Func, TimeUnit):
5373    arg_types = {"this": True, "expression": True, "unit": False}
5374
5375
5376class TimeSub(Func, TimeUnit):
5377    arg_types = {"this": True, "expression": True, "unit": False}
5378
5379
5380class TimeDiff(Func, TimeUnit):
5381    arg_types = {"this": True, "expression": True, "unit": False}
5382
5383
5384class TimeTrunc(Func, TimeUnit):
5385    arg_types = {"this": True, "unit": True, "zone": False}
5386
5387
5388class DateFromParts(Func):
5389    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5390    arg_types = {"year": True, "month": True, "day": True}
5391
5392
5393class TimeFromParts(Func):
5394    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5395    arg_types = {
5396        "hour": True,
5397        "min": True,
5398        "sec": True,
5399        "nano": False,
5400        "fractions": False,
5401        "precision": False,
5402    }
5403
5404
5405class DateStrToDate(Func):
5406    pass
5407
5408
5409class DateToDateStr(Func):
5410    pass
5411
5412
5413class DateToDi(Func):
5414    pass
5415
5416
5417# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
5418class Date(Func):
5419    arg_types = {"this": False, "zone": False, "expressions": False}
5420    is_var_len_args = True
5421
5422
5423class Day(Func):
5424    pass
5425
5426
5427class Decode(Func):
5428    arg_types = {"this": True, "charset": True, "replace": False}
5429
5430
5431class DiToDate(Func):
5432    pass
5433
5434
5435class Encode(Func):
5436    arg_types = {"this": True, "charset": True}
5437
5438
5439class Exp(Func):
5440    pass
5441
5442
5443# https://docs.snowflake.com/en/sql-reference/functions/flatten
5444class Explode(Func):
5445    arg_types = {"this": True, "expressions": False}
5446    is_var_len_args = True
5447
5448
5449# https://spark.apache.org/docs/latest/api/sql/#inline
5450class Inline(Func):
5451    pass
5452
5453
5454class ExplodeOuter(Explode):
5455    pass
5456
5457
5458class Posexplode(Explode):
5459    pass
5460
5461
5462class PosexplodeOuter(Posexplode, ExplodeOuter):
5463    pass
5464
5465
5466class Unnest(Func, UDTF):
5467    arg_types = {
5468        "expressions": True,
5469        "alias": False,
5470        "offset": False,
5471        "explode_array": False,
5472    }
5473
5474    @property
5475    def selects(self) -> t.List[Expression]:
5476        columns = super().selects
5477        offset = self.args.get("offset")
5478        if offset:
5479            columns = columns + [to_identifier("offset") if offset is True else offset]
5480        return columns
5481
5482
5483class Floor(Func):
5484    arg_types = {"this": True, "decimals": False}
5485
5486
5487class FromBase64(Func):
5488    pass
5489
5490
5491class ToBase64(Func):
5492    pass
5493
5494
5495# https://trino.io/docs/current/functions/datetime.html#from_iso8601_timestamp
5496class FromISO8601Timestamp(Func):
5497    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
5498
5499
5500class GapFill(Func):
5501    arg_types = {
5502        "this": True,
5503        "ts_column": True,
5504        "bucket_width": True,
5505        "partitioning_columns": False,
5506        "value_columns": False,
5507        "origin": False,
5508        "ignore_nulls": False,
5509    }
5510
5511
5512# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_date_array
5513class GenerateDateArray(Func):
5514    arg_types = {"start": True, "end": True, "step": False}
5515
5516
5517# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_timestamp_array
5518class GenerateTimestampArray(Func):
5519    arg_types = {"start": True, "end": True, "step": True}
5520
5521
5522class Greatest(Func):
5523    arg_types = {"this": True, "expressions": False}
5524    is_var_len_args = True
5525
5526
5527class GroupConcat(AggFunc):
5528    arg_types = {"this": True, "separator": False}
5529
5530
5531class Hex(Func):
5532    pass
5533
5534
5535class LowerHex(Hex):
5536    pass
5537
5538
5539class Xor(Connector, Func):
5540    arg_types = {"this": False, "expression": False, "expressions": False}
5541
5542
5543class If(Func):
5544    arg_types = {"this": True, "true": True, "false": False}
5545    _sql_names = ["IF", "IIF"]
5546
5547
5548class Nullif(Func):
5549    arg_types = {"this": True, "expression": True}
5550
5551
5552class Initcap(Func):
5553    arg_types = {"this": True, "expression": False}
5554
5555
5556class IsNan(Func):
5557    _sql_names = ["IS_NAN", "ISNAN"]
5558
5559
5560class IsInf(Func):
5561    _sql_names = ["IS_INF", "ISINF"]
5562
5563
5564# https://www.postgresql.org/docs/current/functions-json.html
5565class JSON(Expression):
5566    arg_types = {"this": False, "with": False, "unique": False}
5567
5568
5569class JSONPath(Expression):
5570    arg_types = {"expressions": True, "escape": False}
5571
5572    @property
5573    def output_name(self) -> str:
5574        last_segment = self.expressions[-1].this
5575        return last_segment if isinstance(last_segment, str) else ""
5576
5577
5578class JSONPathPart(Expression):
5579    arg_types = {}
5580
5581
5582class JSONPathFilter(JSONPathPart):
5583    arg_types = {"this": True}
5584
5585
5586class JSONPathKey(JSONPathPart):
5587    arg_types = {"this": True}
5588
5589
5590class JSONPathRecursive(JSONPathPart):
5591    arg_types = {"this": False}
5592
5593
5594class JSONPathRoot(JSONPathPart):
5595    pass
5596
5597
5598class JSONPathScript(JSONPathPart):
5599    arg_types = {"this": True}
5600
5601
5602class JSONPathSlice(JSONPathPart):
5603    arg_types = {"start": False, "end": False, "step": False}
5604
5605
5606class JSONPathSelector(JSONPathPart):
5607    arg_types = {"this": True}
5608
5609
5610class JSONPathSubscript(JSONPathPart):
5611    arg_types = {"this": True}
5612
5613
5614class JSONPathUnion(JSONPathPart):
5615    arg_types = {"expressions": True}
5616
5617
5618class JSONPathWildcard(JSONPathPart):
5619    pass
5620
5621
5622class FormatJson(Expression):
5623    pass
5624
5625
5626class JSONKeyValue(Expression):
5627    arg_types = {"this": True, "expression": True}
5628
5629
5630class JSONObject(Func):
5631    arg_types = {
5632        "expressions": False,
5633        "null_handling": False,
5634        "unique_keys": False,
5635        "return_type": False,
5636        "encoding": False,
5637    }
5638
5639
5640class JSONObjectAgg(AggFunc):
5641    arg_types = {
5642        "expressions": False,
5643        "null_handling": False,
5644        "unique_keys": False,
5645        "return_type": False,
5646        "encoding": False,
5647    }
5648
5649
5650# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
5651class JSONArray(Func):
5652    arg_types = {
5653        "expressions": True,
5654        "null_handling": False,
5655        "return_type": False,
5656        "strict": False,
5657    }
5658
5659
5660# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
5661class JSONArrayAgg(Func):
5662    arg_types = {
5663        "this": True,
5664        "order": False,
5665        "null_handling": False,
5666        "return_type": False,
5667        "strict": False,
5668    }
5669
5670
5671class JSONExists(Func):
5672    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
5673
5674
5675# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
5676# Note: parsing of JSON column definitions is currently incomplete.
5677class JSONColumnDef(Expression):
5678    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
5679
5680
5681class JSONSchema(Expression):
5682    arg_types = {"expressions": True}
5683
5684
5685# https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#function_json-value
5686class JSONValue(Expression):
5687    arg_types = {
5688        "this": True,
5689        "path": True,
5690        "returning": False,
5691        "on_condition": False,
5692    }
5693
5694
5695# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
5696class JSONTable(Func):
5697    arg_types = {
5698        "this": True,
5699        "schema": True,
5700        "path": False,
5701        "error_handling": False,
5702        "empty_handling": False,
5703    }
5704
5705
5706# https://docs.snowflake.com/en/sql-reference/functions/object_insert
5707class ObjectInsert(Func):
5708    arg_types = {
5709        "this": True,
5710        "key": True,
5711        "value": True,
5712        "update_flag": False,
5713    }
5714
5715
5716class OpenJSONColumnDef(Expression):
5717    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
5718
5719
5720class OpenJSON(Func):
5721    arg_types = {"this": True, "path": False, "expressions": False}
5722
5723
5724class JSONBContains(Binary, Func):
5725    _sql_names = ["JSONB_CONTAINS"]
5726
5727
5728class JSONExtract(Binary, Func):
5729    arg_types = {
5730        "this": True,
5731        "expression": True,
5732        "only_json_types": False,
5733        "expressions": False,
5734        "variant_extract": False,
5735    }
5736    _sql_names = ["JSON_EXTRACT"]
5737    is_var_len_args = True
5738
5739    @property
5740    def output_name(self) -> str:
5741        return self.expression.output_name if not self.expressions else ""
5742
5743
5744class JSONExtractScalar(Binary, Func):
5745    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5746    _sql_names = ["JSON_EXTRACT_SCALAR"]
5747    is_var_len_args = True
5748
5749    @property
5750    def output_name(self) -> str:
5751        return self.expression.output_name
5752
5753
5754class JSONBExtract(Binary, Func):
5755    _sql_names = ["JSONB_EXTRACT"]
5756
5757
5758class JSONBExtractScalar(Binary, Func):
5759    _sql_names = ["JSONB_EXTRACT_SCALAR"]
5760
5761
5762class JSONFormat(Func):
5763    arg_types = {"this": False, "options": False}
5764    _sql_names = ["JSON_FORMAT"]
5765
5766
5767# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
5768class JSONArrayContains(Binary, Predicate, Func):
5769    _sql_names = ["JSON_ARRAY_CONTAINS"]
5770
5771
5772class ParseJSON(Func):
5773    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5774    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5775    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5776    arg_types = {"this": True, "expression": False, "safe": False}
5777
5778
5779class Least(Func):
5780    arg_types = {"this": True, "expressions": False}
5781    is_var_len_args = True
5782
5783
5784class Left(Func):
5785    arg_types = {"this": True, "expression": True}
5786
5787
5788class Right(Func):
5789    arg_types = {"this": True, "expression": True}
5790
5791
5792class Length(Func):
5793    arg_types = {"this": True, "binary": False}
5794    _sql_names = ["LENGTH", "LEN"]
5795
5796
5797class Levenshtein(Func):
5798    arg_types = {
5799        "this": True,
5800        "expression": False,
5801        "ins_cost": False,
5802        "del_cost": False,
5803        "sub_cost": False,
5804    }
5805
5806
5807class Ln(Func):
5808    pass
5809
5810
5811class Log(Func):
5812    arg_types = {"this": True, "expression": False}
5813
5814
5815class LogicalOr(AggFunc):
5816    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
5817
5818
5819class LogicalAnd(AggFunc):
5820    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
5821
5822
5823class Lower(Func):
5824    _sql_names = ["LOWER", "LCASE"]
5825
5826
5827class Map(Func):
5828    arg_types = {"keys": False, "values": False}
5829
5830    @property
5831    def keys(self) -> t.List[Expression]:
5832        keys = self.args.get("keys")
5833        return keys.expressions if keys else []
5834
5835    @property
5836    def values(self) -> t.List[Expression]:
5837        values = self.args.get("values")
5838        return values.expressions if values else []
5839
5840
5841# Represents the MAP {...} syntax in DuckDB - basically convert a struct to a MAP
5842class ToMap(Func):
5843    pass
5844
5845
5846class MapFromEntries(Func):
5847    pass
5848
5849
5850# https://learn.microsoft.com/en-us/sql/t-sql/language-elements/scope-resolution-operator-transact-sql?view=sql-server-ver16
5851class ScopeResolution(Expression):
5852    arg_types = {"this": False, "expression": True}
5853
5854
5855class Stream(Expression):
5856    pass
5857
5858
5859class StarMap(Func):
5860    pass
5861
5862
5863class VarMap(Func):
5864    arg_types = {"keys": True, "values": True}
5865    is_var_len_args = True
5866
5867    @property
5868    def keys(self) -> t.List[Expression]:
5869        return self.args["keys"].expressions
5870
5871    @property
5872    def values(self) -> t.List[Expression]:
5873        return self.args["values"].expressions
5874
5875
5876# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
5877class MatchAgainst(Func):
5878    arg_types = {"this": True, "expressions": True, "modifier": False}
5879
5880
5881class Max(AggFunc):
5882    arg_types = {"this": True, "expressions": False}
5883    is_var_len_args = True
5884
5885
5886class MD5(Func):
5887    _sql_names = ["MD5"]
5888
5889
5890# Represents the variant of the MD5 function that returns a binary value
5891class MD5Digest(Func):
5892    _sql_names = ["MD5_DIGEST"]
5893
5894
5895class Min(AggFunc):
5896    arg_types = {"this": True, "expressions": False}
5897    is_var_len_args = True
5898
5899
5900class Month(Func):
5901    pass
5902
5903
5904class AddMonths(Func):
5905    arg_types = {"this": True, "expression": True}
5906
5907
5908class Nvl2(Func):
5909    arg_types = {"this": True, "true": True, "false": False}
5910
5911
5912class Normalize(Func):
5913    arg_types = {"this": True, "form": False}
5914
5915
5916class Overlay(Func):
5917    arg_types = {"this": True, "expression": True, "from": True, "for": False}
5918
5919
5920# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
5921class Predict(Func):
5922    arg_types = {"this": True, "expression": True, "params_struct": False}
5923
5924
5925class Pow(Binary, Func):
5926    _sql_names = ["POWER", "POW"]
5927
5928
5929class PercentileCont(AggFunc):
5930    arg_types = {"this": True, "expression": False}
5931
5932
5933class PercentileDisc(AggFunc):
5934    arg_types = {"this": True, "expression": False}
5935
5936
5937class Quantile(AggFunc):
5938    arg_types = {"this": True, "quantile": True}
5939
5940
5941class ApproxQuantile(Quantile):
5942    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
5943
5944
5945class Quarter(Func):
5946    pass
5947
5948
5949# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/Arithmetic-Trigonometric-Hyperbolic-Operators/Functions/RANDOM/RANDOM-Function-Syntax
5950# teradata lower and upper bounds
5951class Rand(Func):
5952    _sql_names = ["RAND", "RANDOM"]
5953    arg_types = {"this": False, "lower": False, "upper": False}
5954
5955
5956class Randn(Func):
5957    arg_types = {"this": False}
5958
5959
5960class RangeN(Func):
5961    arg_types = {"this": True, "expressions": True, "each": False}
5962
5963
5964class ReadCSV(Func):
5965    _sql_names = ["READ_CSV"]
5966    is_var_len_args = True
5967    arg_types = {"this": True, "expressions": False}
5968
5969
5970class Reduce(Func):
5971    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
5972
5973
5974class RegexpExtract(Func):
5975    arg_types = {
5976        "this": True,
5977        "expression": True,
5978        "position": False,
5979        "occurrence": False,
5980        "parameters": False,
5981        "group": False,
5982    }
5983
5984
5985class RegexpReplace(Func):
5986    arg_types = {
5987        "this": True,
5988        "expression": True,
5989        "replacement": False,
5990        "position": False,
5991        "occurrence": False,
5992        "modifiers": False,
5993    }
5994
5995
5996class RegexpLike(Binary, Func):
5997    arg_types = {"this": True, "expression": True, "flag": False}
5998
5999
6000class RegexpILike(Binary, Func):
6001    arg_types = {"this": True, "expression": True, "flag": False}
6002
6003
6004# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
6005# limit is the number of times a pattern is applied
6006class RegexpSplit(Func):
6007    arg_types = {"this": True, "expression": True, "limit": False}
6008
6009
6010class Repeat(Func):
6011    arg_types = {"this": True, "times": True}
6012
6013
6014# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
6015# tsql third argument function == trunctaion if not 0
6016class Round(Func):
6017    arg_types = {"this": True, "decimals": False, "truncate": False}
6018
6019
6020class RowNumber(Func):
6021    arg_types: t.Dict[str, t.Any] = {}
6022
6023
6024class SafeDivide(Func):
6025    arg_types = {"this": True, "expression": True}
6026
6027
6028class SHA(Func):
6029    _sql_names = ["SHA", "SHA1"]
6030
6031
6032class SHA2(Func):
6033    _sql_names = ["SHA2"]
6034    arg_types = {"this": True, "length": False}
6035
6036
6037class Sign(Func):
6038    _sql_names = ["SIGN", "SIGNUM"]
6039
6040
6041class SortArray(Func):
6042    arg_types = {"this": True, "asc": False}
6043
6044
6045class Split(Func):
6046    arg_types = {"this": True, "expression": True, "limit": False}
6047
6048
6049# Start may be omitted in the case of postgres
6050# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
6051class Substring(Func):
6052    _sql_names = ["SUBSTRING", "SUBSTR"]
6053    arg_types = {"this": True, "start": False, "length": False}
6054
6055
6056class StandardHash(Func):
6057    arg_types = {"this": True, "expression": False}
6058
6059
6060class StartsWith(Func):
6061    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6062    arg_types = {"this": True, "expression": True}
6063
6064
6065class StrPosition(Func):
6066    arg_types = {
6067        "this": True,
6068        "substr": True,
6069        "position": False,
6070        "instance": False,
6071    }
6072
6073
6074class StrToDate(Func):
6075    arg_types = {"this": True, "format": False, "safe": False}
6076
6077
6078class StrToTime(Func):
6079    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
6080
6081
6082# Spark allows unix_timestamp()
6083# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
6084class StrToUnix(Func):
6085    arg_types = {"this": False, "format": False}
6086
6087
6088# https://prestodb.io/docs/current/functions/string.html
6089# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
6090class StrToMap(Func):
6091    arg_types = {
6092        "this": True,
6093        "pair_delim": False,
6094        "key_value_delim": False,
6095        "duplicate_resolution_callback": False,
6096    }
6097
6098
6099class NumberToStr(Func):
6100    arg_types = {"this": True, "format": True, "culture": False}
6101
6102
6103class FromBase(Func):
6104    arg_types = {"this": True, "expression": True}
6105
6106
6107class Struct(Func):
6108    arg_types = {"expressions": False}
6109    is_var_len_args = True
6110
6111
6112class StructExtract(Func):
6113    arg_types = {"this": True, "expression": True}
6114
6115
6116# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
6117# https://docs.snowflake.com/en/sql-reference/functions/insert
6118class Stuff(Func):
6119    _sql_names = ["STUFF", "INSERT"]
6120    arg_types = {"this": True, "start": True, "length": True, "expression": True}
6121
6122
6123class Sum(AggFunc):
6124    pass
6125
6126
6127class Sqrt(Func):
6128    pass
6129
6130
6131class Stddev(AggFunc):
6132    _sql_names = ["STDDEV", "STDEV"]
6133
6134
6135class StddevPop(AggFunc):
6136    pass
6137
6138
6139class StddevSamp(AggFunc):
6140    pass
6141
6142
6143# https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions#time
6144class Time(Func):
6145    arg_types = {"this": False, "zone": False}
6146
6147
6148class TimeToStr(Func):
6149    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
6150
6151
6152class TimeToTimeStr(Func):
6153    pass
6154
6155
6156class TimeToUnix(Func):
6157    pass
6158
6159
6160class TimeStrToDate(Func):
6161    pass
6162
6163
6164class TimeStrToTime(Func):
6165    arg_types = {"this": True, "zone": False}
6166
6167
6168class TimeStrToUnix(Func):
6169    pass
6170
6171
6172class Trim(Func):
6173    arg_types = {
6174        "this": True,
6175        "expression": False,
6176        "position": False,
6177        "collation": False,
6178    }
6179
6180
6181class TsOrDsAdd(Func, TimeUnit):
6182    # return_type is used to correctly cast the arguments of this expression when transpiling it
6183    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6184
6185    @property
6186    def return_type(self) -> DataType:
6187        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
6188
6189
6190class TsOrDsDiff(Func, TimeUnit):
6191    arg_types = {"this": True, "expression": True, "unit": False}
6192
6193
6194class TsOrDsToDateStr(Func):
6195    pass
6196
6197
6198class TsOrDsToDate(Func):
6199    arg_types = {"this": True, "format": False, "safe": False}
6200
6201
6202class TsOrDsToTime(Func):
6203    pass
6204
6205
6206class TsOrDsToTimestamp(Func):
6207    pass
6208
6209
6210class TsOrDiToDi(Func):
6211    pass
6212
6213
6214class Unhex(Func):
6215    pass
6216
6217
6218# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
6219class UnixDate(Func):
6220    pass
6221
6222
6223class UnixToStr(Func):
6224    arg_types = {"this": True, "format": False}
6225
6226
6227# https://prestodb.io/docs/current/functions/datetime.html
6228# presto has weird zone/hours/minutes
6229class UnixToTime(Func):
6230    arg_types = {
6231        "this": True,
6232        "scale": False,
6233        "zone": False,
6234        "hours": False,
6235        "minutes": False,
6236        "format": False,
6237    }
6238
6239    SECONDS = Literal.number(0)
6240    DECIS = Literal.number(1)
6241    CENTIS = Literal.number(2)
6242    MILLIS = Literal.number(3)
6243    DECIMILLIS = Literal.number(4)
6244    CENTIMILLIS = Literal.number(5)
6245    MICROS = Literal.number(6)
6246    DECIMICROS = Literal.number(7)
6247    CENTIMICROS = Literal.number(8)
6248    NANOS = Literal.number(9)
6249
6250
6251class UnixToTimeStr(Func):
6252    pass
6253
6254
6255class Uuid(Func):
6256    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6257
6258    arg_types = {"this": False, "name": False}
6259
6260
6261class TimestampFromParts(Func):
6262    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6263    arg_types = {
6264        "year": True,
6265        "month": True,
6266        "day": True,
6267        "hour": True,
6268        "min": True,
6269        "sec": True,
6270        "nano": False,
6271        "zone": False,
6272        "milli": False,
6273    }
6274
6275
6276class Upper(Func):
6277    _sql_names = ["UPPER", "UCASE"]
6278
6279
6280class Corr(Binary, AggFunc):
6281    pass
6282
6283
6284class Variance(AggFunc):
6285    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
6286
6287
6288class VariancePop(AggFunc):
6289    _sql_names = ["VARIANCE_POP", "VAR_POP"]
6290
6291
6292class CovarSamp(Binary, AggFunc):
6293    pass
6294
6295
6296class CovarPop(Binary, AggFunc):
6297    pass
6298
6299
6300class Week(Func):
6301    arg_types = {"this": True, "mode": False}
6302
6303
6304class XMLTable(Func):
6305    arg_types = {"this": True, "passing": False, "columns": False, "by_ref": False}
6306
6307
6308class Year(Func):
6309    pass
6310
6311
6312class Use(Expression):
6313    arg_types = {"this": True, "kind": False}
6314
6315
6316class Merge(DML):
6317    arg_types = {
6318        "this": True,
6319        "using": True,
6320        "on": True,
6321        "expressions": True,
6322        "with": False,
6323        "returning": False,
6324    }
6325
6326
6327class When(Func):
6328    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
6329
6330
6331# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
6332# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
6333class NextValueFor(Func):
6334    arg_types = {"this": True, "order": False}
6335
6336
6337# Refers to a trailing semi-colon. This is only used to preserve trailing comments
6338# select 1; -- my comment
6339class Semicolon(Expression):
6340    arg_types = {}
6341
6342
6343def _norm_arg(arg):
6344    return arg.lower() if type(arg) is str else arg
6345
6346
6347ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
6348FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
6349
6350JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
6351
6352PERCENTILES = (PercentileCont, PercentileDisc)
6353
6354
6355# Helpers
6356@t.overload
6357def maybe_parse(
6358    sql_or_expression: ExpOrStr,
6359    *,
6360    into: t.Type[E],
6361    dialect: DialectType = None,
6362    prefix: t.Optional[str] = None,
6363    copy: bool = False,
6364    **opts,
6365) -> E: ...
6366
6367
6368@t.overload
6369def maybe_parse(
6370    sql_or_expression: str | E,
6371    *,
6372    into: t.Optional[IntoType] = None,
6373    dialect: DialectType = None,
6374    prefix: t.Optional[str] = None,
6375    copy: bool = False,
6376    **opts,
6377) -> E: ...
6378
6379
6380def maybe_parse(
6381    sql_or_expression: ExpOrStr,
6382    *,
6383    into: t.Optional[IntoType] = None,
6384    dialect: DialectType = None,
6385    prefix: t.Optional[str] = None,
6386    copy: bool = False,
6387    **opts,
6388) -> Expression:
6389    """Gracefully handle a possible string or expression.
6390
6391    Example:
6392        >>> maybe_parse("1")
6393        Literal(this=1, is_string=False)
6394        >>> maybe_parse(to_identifier("x"))
6395        Identifier(this=x, quoted=False)
6396
6397    Args:
6398        sql_or_expression: the SQL code string or an expression
6399        into: the SQLGlot Expression to parse into
6400        dialect: the dialect used to parse the input expressions (in the case that an
6401            input expression is a SQL string).
6402        prefix: a string to prefix the sql with before it gets parsed
6403            (automatically includes a space)
6404        copy: whether to copy the expression.
6405        **opts: other options to use to parse the input expressions (again, in the case
6406            that an input expression is a SQL string).
6407
6408    Returns:
6409        Expression: the parsed or given expression.
6410    """
6411    if isinstance(sql_or_expression, Expression):
6412        if copy:
6413            return sql_or_expression.copy()
6414        return sql_or_expression
6415
6416    if sql_or_expression is None:
6417        raise ParseError("SQL cannot be None")
6418
6419    import sqlglot
6420
6421    sql = str(sql_or_expression)
6422    if prefix:
6423        sql = f"{prefix} {sql}"
6424
6425    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
6426
6427
6428@t.overload
6429def maybe_copy(instance: None, copy: bool = True) -> None: ...
6430
6431
6432@t.overload
6433def maybe_copy(instance: E, copy: bool = True) -> E: ...
6434
6435
6436def maybe_copy(instance, copy=True):
6437    return instance.copy() if copy and instance else instance
6438
6439
6440def _to_s(node: t.Any, verbose: bool = False, level: int = 0) -> str:
6441    """Generate a textual representation of an Expression tree"""
6442    indent = "\n" + ("  " * (level + 1))
6443    delim = f",{indent}"
6444
6445    if isinstance(node, Expression):
6446        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
6447
6448        if (node.type or verbose) and not isinstance(node, DataType):
6449            args["_type"] = node.type
6450        if node.comments or verbose:
6451            args["_comments"] = node.comments
6452
6453        if verbose:
6454            args["_id"] = id(node)
6455
6456        # Inline leaves for a more compact representation
6457        if node.is_leaf():
6458            indent = ""
6459            delim = ", "
6460
6461        items = delim.join([f"{k}={_to_s(v, verbose, level + 1)}" for k, v in args.items()])
6462        return f"{node.__class__.__name__}({indent}{items})"
6463
6464    if isinstance(node, list):
6465        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
6466        items = f"{indent}{items}" if items else ""
6467        return f"[{items}]"
6468
6469    # Indent multiline strings to match the current level
6470    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
6471
6472
6473def _is_wrong_expression(expression, into):
6474    return isinstance(expression, Expression) and not isinstance(expression, into)
6475
6476
6477def _apply_builder(
6478    expression,
6479    instance,
6480    arg,
6481    copy=True,
6482    prefix=None,
6483    into=None,
6484    dialect=None,
6485    into_arg="this",
6486    **opts,
6487):
6488    if _is_wrong_expression(expression, into):
6489        expression = into(**{into_arg: expression})
6490    instance = maybe_copy(instance, copy)
6491    expression = maybe_parse(
6492        sql_or_expression=expression,
6493        prefix=prefix,
6494        into=into,
6495        dialect=dialect,
6496        **opts,
6497    )
6498    instance.set(arg, expression)
6499    return instance
6500
6501
6502def _apply_child_list_builder(
6503    *expressions,
6504    instance,
6505    arg,
6506    append=True,
6507    copy=True,
6508    prefix=None,
6509    into=None,
6510    dialect=None,
6511    properties=None,
6512    **opts,
6513):
6514    instance = maybe_copy(instance, copy)
6515    parsed = []
6516    properties = {} if properties is None else properties
6517
6518    for expression in expressions:
6519        if expression is not None:
6520            if _is_wrong_expression(expression, into):
6521                expression = into(expressions=[expression])
6522
6523            expression = maybe_parse(
6524                expression,
6525                into=into,
6526                dialect=dialect,
6527                prefix=prefix,
6528                **opts,
6529            )
6530            for k, v in expression.args.items():
6531                if k == "expressions":
6532                    parsed.extend(v)
6533                else:
6534                    properties[k] = v
6535
6536    existing = instance.args.get(arg)
6537    if append and existing:
6538        parsed = existing.expressions + parsed
6539
6540    child = into(expressions=parsed)
6541    for k, v in properties.items():
6542        child.set(k, v)
6543    instance.set(arg, child)
6544
6545    return instance
6546
6547
6548def _apply_list_builder(
6549    *expressions,
6550    instance,
6551    arg,
6552    append=True,
6553    copy=True,
6554    prefix=None,
6555    into=None,
6556    dialect=None,
6557    **opts,
6558):
6559    inst = maybe_copy(instance, copy)
6560
6561    expressions = [
6562        maybe_parse(
6563            sql_or_expression=expression,
6564            into=into,
6565            prefix=prefix,
6566            dialect=dialect,
6567            **opts,
6568        )
6569        for expression in expressions
6570        if expression is not None
6571    ]
6572
6573    existing_expressions = inst.args.get(arg)
6574    if append and existing_expressions:
6575        expressions = existing_expressions + expressions
6576
6577    inst.set(arg, expressions)
6578    return inst
6579
6580
6581def _apply_conjunction_builder(
6582    *expressions,
6583    instance,
6584    arg,
6585    into=None,
6586    append=True,
6587    copy=True,
6588    dialect=None,
6589    **opts,
6590):
6591    expressions = [exp for exp in expressions if exp is not None and exp != ""]
6592    if not expressions:
6593        return instance
6594
6595    inst = maybe_copy(instance, copy)
6596
6597    existing = inst.args.get(arg)
6598    if append and existing is not None:
6599        expressions = [existing.this if into else existing] + list(expressions)
6600
6601    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
6602
6603    inst.set(arg, into(this=node) if into else node)
6604    return inst
6605
6606
6607def _apply_cte_builder(
6608    instance: E,
6609    alias: ExpOrStr,
6610    as_: ExpOrStr,
6611    recursive: t.Optional[bool] = None,
6612    materialized: t.Optional[bool] = None,
6613    append: bool = True,
6614    dialect: DialectType = None,
6615    copy: bool = True,
6616    **opts,
6617) -> E:
6618    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
6619    as_expression = maybe_parse(as_, dialect=dialect, **opts)
6620    cte = CTE(this=as_expression, alias=alias_expression, materialized=materialized)
6621    return _apply_child_list_builder(
6622        cte,
6623        instance=instance,
6624        arg="with",
6625        append=append,
6626        copy=copy,
6627        into=With,
6628        properties={"recursive": recursive or False},
6629    )
6630
6631
6632def _combine(
6633    expressions: t.Sequence[t.Optional[ExpOrStr]],
6634    operator: t.Type[Connector],
6635    dialect: DialectType = None,
6636    copy: bool = True,
6637    **opts,
6638) -> Expression:
6639    conditions = [
6640        condition(expression, dialect=dialect, copy=copy, **opts)
6641        for expression in expressions
6642        if expression is not None
6643    ]
6644
6645    this, *rest = conditions
6646    if rest:
6647        this = _wrap(this, Connector)
6648    for expression in rest:
6649        this = operator(this=this, expression=_wrap(expression, Connector))
6650
6651    return this
6652
6653
6654def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren:
6655    return Paren(this=expression) if isinstance(expression, kind) else expression
6656
6657
6658def union(
6659    left: ExpOrStr,
6660    right: ExpOrStr,
6661    distinct: bool = True,
6662    dialect: DialectType = None,
6663    copy: bool = True,
6664    **opts,
6665) -> Union:
6666    """
6667    Initializes a syntax tree from one UNION expression.
6668
6669    Example:
6670        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6671        'SELECT * FROM foo UNION SELECT * FROM bla'
6672
6673    Args:
6674        left: the SQL code string corresponding to the left-hand side.
6675            If an `Expression` instance is passed, it will be used as-is.
6676        right: the SQL code string corresponding to the right-hand side.
6677            If an `Expression` instance is passed, it will be used as-is.
6678        distinct: set the DISTINCT flag if and only if this is true.
6679        dialect: the dialect used to parse the input expression.
6680        copy: whether to copy the expression.
6681        opts: other options to use to parse the input expressions.
6682
6683    Returns:
6684        The new Union instance.
6685    """
6686    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6687    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6688
6689    return Union(this=left, expression=right, distinct=distinct)
6690
6691
6692def intersect(
6693    left: ExpOrStr,
6694    right: ExpOrStr,
6695    distinct: bool = True,
6696    dialect: DialectType = None,
6697    copy: bool = True,
6698    **opts,
6699) -> Intersect:
6700    """
6701    Initializes a syntax tree from one INTERSECT expression.
6702
6703    Example:
6704        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6705        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6706
6707    Args:
6708        left: the SQL code string corresponding to the left-hand side.
6709            If an `Expression` instance is passed, it will be used as-is.
6710        right: the SQL code string corresponding to the right-hand side.
6711            If an `Expression` instance is passed, it will be used as-is.
6712        distinct: set the DISTINCT flag if and only if this is true.
6713        dialect: the dialect used to parse the input expression.
6714        copy: whether to copy the expression.
6715        opts: other options to use to parse the input expressions.
6716
6717    Returns:
6718        The new Intersect instance.
6719    """
6720    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6721    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6722
6723    return Intersect(this=left, expression=right, distinct=distinct)
6724
6725
6726def except_(
6727    left: ExpOrStr,
6728    right: ExpOrStr,
6729    distinct: bool = True,
6730    dialect: DialectType = None,
6731    copy: bool = True,
6732    **opts,
6733) -> Except:
6734    """
6735    Initializes a syntax tree from one EXCEPT expression.
6736
6737    Example:
6738        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6739        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6740
6741    Args:
6742        left: the SQL code string corresponding to the left-hand side.
6743            If an `Expression` instance is passed, it will be used as-is.
6744        right: the SQL code string corresponding to the right-hand side.
6745            If an `Expression` instance is passed, it will be used as-is.
6746        distinct: set the DISTINCT flag if and only if this is true.
6747        dialect: the dialect used to parse the input expression.
6748        copy: whether to copy the expression.
6749        opts: other options to use to parse the input expressions.
6750
6751    Returns:
6752        The new Except instance.
6753    """
6754    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6755    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6756
6757    return Except(this=left, expression=right, distinct=distinct)
6758
6759
6760def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6761    """
6762    Initializes a syntax tree from one or multiple SELECT expressions.
6763
6764    Example:
6765        >>> select("col1", "col2").from_("tbl").sql()
6766        'SELECT col1, col2 FROM tbl'
6767
6768    Args:
6769        *expressions: the SQL code string to parse as the expressions of a
6770            SELECT statement. If an Expression instance is passed, this is used as-is.
6771        dialect: the dialect used to parse the input expressions (in the case that an
6772            input expression is a SQL string).
6773        **opts: other options to use to parse the input expressions (again, in the case
6774            that an input expression is a SQL string).
6775
6776    Returns:
6777        Select: the syntax tree for the SELECT statement.
6778    """
6779    return Select().select(*expressions, dialect=dialect, **opts)
6780
6781
6782def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6783    """
6784    Initializes a syntax tree from a FROM expression.
6785
6786    Example:
6787        >>> from_("tbl").select("col1", "col2").sql()
6788        'SELECT col1, col2 FROM tbl'
6789
6790    Args:
6791        *expression: the SQL code string to parse as the FROM expressions of a
6792            SELECT statement. If an Expression instance is passed, this is used as-is.
6793        dialect: the dialect used to parse the input expression (in the case that the
6794            input expression is a SQL string).
6795        **opts: other options to use to parse the input expressions (again, in the case
6796            that the input expression is a SQL string).
6797
6798    Returns:
6799        Select: the syntax tree for the SELECT statement.
6800    """
6801    return Select().from_(expression, dialect=dialect, **opts)
6802
6803
6804def update(
6805    table: str | Table,
6806    properties: dict,
6807    where: t.Optional[ExpOrStr] = None,
6808    from_: t.Optional[ExpOrStr] = None,
6809    dialect: DialectType = None,
6810    **opts,
6811) -> Update:
6812    """
6813    Creates an update statement.
6814
6815    Example:
6816        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6817        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6818
6819    Args:
6820        *properties: dictionary of properties to set which are
6821            auto converted to sql objects eg None -> NULL
6822        where: sql conditional parsed into a WHERE statement
6823        from_: sql statement parsed into a FROM statement
6824        dialect: the dialect used to parse the input expressions.
6825        **opts: other options to use to parse the input expressions.
6826
6827    Returns:
6828        Update: the syntax tree for the UPDATE statement.
6829    """
6830    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6831    update_expr.set(
6832        "expressions",
6833        [
6834            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6835            for k, v in properties.items()
6836        ],
6837    )
6838    if from_:
6839        update_expr.set(
6840            "from",
6841            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6842        )
6843    if isinstance(where, Condition):
6844        where = Where(this=where)
6845    if where:
6846        update_expr.set(
6847            "where",
6848            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6849        )
6850    return update_expr
6851
6852
6853def delete(
6854    table: ExpOrStr,
6855    where: t.Optional[ExpOrStr] = None,
6856    returning: t.Optional[ExpOrStr] = None,
6857    dialect: DialectType = None,
6858    **opts,
6859) -> Delete:
6860    """
6861    Builds a delete statement.
6862
6863    Example:
6864        >>> delete("my_table", where="id > 1").sql()
6865        'DELETE FROM my_table WHERE id > 1'
6866
6867    Args:
6868        where: sql conditional parsed into a WHERE statement
6869        returning: sql conditional parsed into a RETURNING statement
6870        dialect: the dialect used to parse the input expressions.
6871        **opts: other options to use to parse the input expressions.
6872
6873    Returns:
6874        Delete: the syntax tree for the DELETE statement.
6875    """
6876    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6877    if where:
6878        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6879    if returning:
6880        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6881    return delete_expr
6882
6883
6884def insert(
6885    expression: ExpOrStr,
6886    into: ExpOrStr,
6887    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6888    overwrite: t.Optional[bool] = None,
6889    returning: t.Optional[ExpOrStr] = None,
6890    dialect: DialectType = None,
6891    copy: bool = True,
6892    **opts,
6893) -> Insert:
6894    """
6895    Builds an INSERT statement.
6896
6897    Example:
6898        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6899        'INSERT INTO tbl VALUES (1, 2, 3)'
6900
6901    Args:
6902        expression: the sql string or expression of the INSERT statement
6903        into: the tbl to insert data to.
6904        columns: optionally the table's column names.
6905        overwrite: whether to INSERT OVERWRITE or not.
6906        returning: sql conditional parsed into a RETURNING statement
6907        dialect: the dialect used to parse the input expressions.
6908        copy: whether to copy the expression.
6909        **opts: other options to use to parse the input expressions.
6910
6911    Returns:
6912        Insert: the syntax tree for the INSERT statement.
6913    """
6914    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6915    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6916
6917    if columns:
6918        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6919
6920    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6921
6922    if returning:
6923        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
6924
6925    return insert
6926
6927
6928def merge(
6929    *when_exprs: ExpOrStr,
6930    into: ExpOrStr,
6931    using: ExpOrStr,
6932    on: ExpOrStr,
6933    returning: t.Optional[ExpOrStr] = None,
6934    dialect: DialectType = None,
6935    copy: bool = True,
6936    **opts,
6937) -> Merge:
6938    """
6939    Builds a MERGE statement.
6940
6941    Example:
6942        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
6943        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
6944        ...       into="my_table",
6945        ...       using="source_table",
6946        ...       on="my_table.id = source_table.id").sql()
6947        '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)'
6948
6949    Args:
6950        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
6951        into: The target table to merge data into.
6952        using: The source table to merge data from.
6953        on: The join condition for the merge.
6954        returning: The columns to return from the merge.
6955        dialect: The dialect used to parse the input expressions.
6956        copy: Whether to copy the expression.
6957        **opts: Other options to use to parse the input expressions.
6958
6959    Returns:
6960        Merge: The syntax tree for the MERGE statement.
6961    """
6962    merge = Merge(
6963        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
6964        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
6965        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
6966        expressions=[
6967            maybe_parse(when_expr, dialect=dialect, copy=copy, into=When, **opts)
6968            for when_expr in when_exprs
6969        ],
6970    )
6971    if returning:
6972        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
6973
6974    return merge
6975
6976
6977def condition(
6978    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6979) -> Condition:
6980    """
6981    Initialize a logical condition expression.
6982
6983    Example:
6984        >>> condition("x=1").sql()
6985        'x = 1'
6986
6987        This is helpful for composing larger logical syntax trees:
6988        >>> where = condition("x=1")
6989        >>> where = where.and_("y=1")
6990        >>> Select().from_("tbl").select("*").where(where).sql()
6991        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6992
6993    Args:
6994        *expression: the SQL code string to parse.
6995            If an Expression instance is passed, this is used as-is.
6996        dialect: the dialect used to parse the input expression (in the case that the
6997            input expression is a SQL string).
6998        copy: Whether to copy `expression` (only applies to expressions).
6999        **opts: other options to use to parse the input expressions (again, in the case
7000            that the input expression is a SQL string).
7001
7002    Returns:
7003        The new Condition instance
7004    """
7005    return maybe_parse(
7006        expression,
7007        into=Condition,
7008        dialect=dialect,
7009        copy=copy,
7010        **opts,
7011    )
7012
7013
7014def and_(
7015    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7016) -> Condition:
7017    """
7018    Combine multiple conditions with an AND logical operator.
7019
7020    Example:
7021        >>> and_("x=1", and_("y=1", "z=1")).sql()
7022        'x = 1 AND (y = 1 AND z = 1)'
7023
7024    Args:
7025        *expressions: the SQL code strings to parse.
7026            If an Expression instance is passed, this is used as-is.
7027        dialect: the dialect used to parse the input expression.
7028        copy: whether to copy `expressions` (only applies to Expressions).
7029        **opts: other options to use to parse the input expressions.
7030
7031    Returns:
7032        The new condition
7033    """
7034    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, **opts))
7035
7036
7037def or_(
7038    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7039) -> Condition:
7040    """
7041    Combine multiple conditions with an OR logical operator.
7042
7043    Example:
7044        >>> or_("x=1", or_("y=1", "z=1")).sql()
7045        'x = 1 OR (y = 1 OR z = 1)'
7046
7047    Args:
7048        *expressions: the SQL code strings to parse.
7049            If an Expression instance is passed, this is used as-is.
7050        dialect: the dialect used to parse the input expression.
7051        copy: whether to copy `expressions` (only applies to Expressions).
7052        **opts: other options to use to parse the input expressions.
7053
7054    Returns:
7055        The new condition
7056    """
7057    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, **opts))
7058
7059
7060def xor(
7061    *expressions: t.Optional[ExpOrStr], dialect: DialectType = None, copy: bool = True, **opts
7062) -> Condition:
7063    """
7064    Combine multiple conditions with an XOR logical operator.
7065
7066    Example:
7067        >>> xor("x=1", xor("y=1", "z=1")).sql()
7068        'x = 1 XOR (y = 1 XOR z = 1)'
7069
7070    Args:
7071        *expressions: the SQL code strings to parse.
7072            If an Expression instance is passed, this is used as-is.
7073        dialect: the dialect used to parse the input expression.
7074        copy: whether to copy `expressions` (only applies to Expressions).
7075        **opts: other options to use to parse the input expressions.
7076
7077    Returns:
7078        The new condition
7079    """
7080    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, **opts))
7081
7082
7083def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7084    """
7085    Wrap a condition with a NOT operator.
7086
7087    Example:
7088        >>> not_("this_suit='black'").sql()
7089        "NOT this_suit = 'black'"
7090
7091    Args:
7092        expression: the SQL code string to parse.
7093            If an Expression instance is passed, this is used as-is.
7094        dialect: the dialect used to parse the input expression.
7095        copy: whether to copy the expression or not.
7096        **opts: other options to use to parse the input expressions.
7097
7098    Returns:
7099        The new condition.
7100    """
7101    this = condition(
7102        expression,
7103        dialect=dialect,
7104        copy=copy,
7105        **opts,
7106    )
7107    return Not(this=_wrap(this, Connector))
7108
7109
7110def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7111    """
7112    Wrap an expression in parentheses.
7113
7114    Example:
7115        >>> paren("5 + 3").sql()
7116        '(5 + 3)'
7117
7118    Args:
7119        expression: the SQL code string to parse.
7120            If an Expression instance is passed, this is used as-is.
7121        copy: whether to copy the expression or not.
7122
7123    Returns:
7124        The wrapped expression.
7125    """
7126    return Paren(this=maybe_parse(expression, copy=copy))
7127
7128
7129SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
7130
7131
7132@t.overload
7133def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
7134
7135
7136@t.overload
7137def to_identifier(
7138    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
7139) -> Identifier: ...
7140
7141
7142def to_identifier(name, quoted=None, copy=True):
7143    """Builds an identifier.
7144
7145    Args:
7146        name: The name to turn into an identifier.
7147        quoted: Whether to force quote the identifier.
7148        copy: Whether to copy name if it's an Identifier.
7149
7150    Returns:
7151        The identifier ast node.
7152    """
7153
7154    if name is None:
7155        return None
7156
7157    if isinstance(name, Identifier):
7158        identifier = maybe_copy(name, copy)
7159    elif isinstance(name, str):
7160        identifier = Identifier(
7161            this=name,
7162            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7163        )
7164    else:
7165        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7166    return identifier
7167
7168
7169def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7170    """
7171    Parses a given string into an identifier.
7172
7173    Args:
7174        name: The name to parse into an identifier.
7175        dialect: The dialect to parse against.
7176
7177    Returns:
7178        The identifier ast node.
7179    """
7180    try:
7181        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7182    except (ParseError, TokenError):
7183        expression = to_identifier(name)
7184
7185    return expression
7186
7187
7188INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
7189
7190
7191def to_interval(interval: str | Literal) -> Interval:
7192    """Builds an interval expression from a string like '1 day' or '5 months'."""
7193    if isinstance(interval, Literal):
7194        if not interval.is_string:
7195            raise ValueError("Invalid interval string.")
7196
7197        interval = interval.this
7198
7199    interval_parts = INTERVAL_STRING_RE.match(interval)  # type: ignore
7200
7201    if not interval_parts:
7202        raise ValueError("Invalid interval string.")
7203
7204    return Interval(
7205        this=Literal.string(interval_parts.group(1)),
7206        unit=Var(this=interval_parts.group(2).upper()),
7207    )
7208
7209
7210def to_table(
7211    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7212) -> Table:
7213    """
7214    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7215    If a table is passed in then that table is returned.
7216
7217    Args:
7218        sql_path: a `[catalog].[schema].[table]` string.
7219        dialect: the source dialect according to which the table name will be parsed.
7220        copy: Whether to copy a table if it is passed in.
7221        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7222
7223    Returns:
7224        A table expression.
7225    """
7226    if isinstance(sql_path, Table):
7227        return maybe_copy(sql_path, copy=copy)
7228
7229    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7230
7231    for k, v in kwargs.items():
7232        table.set(k, v)
7233
7234    return table
7235
7236
7237def to_column(
7238    sql_path: str | Column,
7239    quoted: t.Optional[bool] = None,
7240    dialect: DialectType = None,
7241    copy: bool = True,
7242    **kwargs,
7243) -> Column:
7244    """
7245    Create a column from a `[table].[column]` sql path. Table is optional.
7246    If a column is passed in then that column is returned.
7247
7248    Args:
7249        sql_path: a `[table].[column]` string.
7250        quoted: Whether or not to force quote identifiers.
7251        dialect: the source dialect according to which the column name will be parsed.
7252        copy: Whether to copy a column if it is passed in.
7253        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7254
7255    Returns:
7256        A column expression.
7257    """
7258    if isinstance(sql_path, Column):
7259        return maybe_copy(sql_path, copy=copy)
7260
7261    try:
7262        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7263    except ParseError:
7264        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7265
7266    for k, v in kwargs.items():
7267        col.set(k, v)
7268
7269    if quoted:
7270        for i in col.find_all(Identifier):
7271            i.set("quoted", True)
7272
7273    return col
7274
7275
7276def alias_(
7277    expression: ExpOrStr,
7278    alias: t.Optional[str | Identifier],
7279    table: bool | t.Sequence[str | Identifier] = False,
7280    quoted: t.Optional[bool] = None,
7281    dialect: DialectType = None,
7282    copy: bool = True,
7283    **opts,
7284):
7285    """Create an Alias expression.
7286
7287    Example:
7288        >>> alias_('foo', 'bar').sql()
7289        'foo AS bar'
7290
7291        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7292        '(SELECT 1, 2) AS bar(a, b)'
7293
7294    Args:
7295        expression: the SQL code strings to parse.
7296            If an Expression instance is passed, this is used as-is.
7297        alias: the alias name to use. If the name has
7298            special characters it is quoted.
7299        table: Whether to create a table alias, can also be a list of columns.
7300        quoted: whether to quote the alias
7301        dialect: the dialect used to parse the input expression.
7302        copy: Whether to copy the expression.
7303        **opts: other options to use to parse the input expressions.
7304
7305    Returns:
7306        Alias: the aliased expression
7307    """
7308    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7309    alias = to_identifier(alias, quoted=quoted)
7310
7311    if table:
7312        table_alias = TableAlias(this=alias)
7313        exp.set("alias", table_alias)
7314
7315        if not isinstance(table, bool):
7316            for column in table:
7317                table_alias.append("columns", to_identifier(column, quoted=quoted))
7318
7319        return exp
7320
7321    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7322    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7323    # for the complete Window expression.
7324    #
7325    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7326
7327    if "alias" in exp.arg_types and not isinstance(exp, Window):
7328        exp.set("alias", alias)
7329        return exp
7330    return Alias(this=exp, alias=alias)
7331
7332
7333def subquery(
7334    expression: ExpOrStr,
7335    alias: t.Optional[Identifier | str] = None,
7336    dialect: DialectType = None,
7337    **opts,
7338) -> Select:
7339    """
7340    Build a subquery expression that's selected from.
7341
7342    Example:
7343        >>> subquery('select x from tbl', 'bar').select('x').sql()
7344        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7345
7346    Args:
7347        expression: the SQL code strings to parse.
7348            If an Expression instance is passed, this is used as-is.
7349        alias: the alias name to use.
7350        dialect: the dialect used to parse the input expression.
7351        **opts: other options to use to parse the input expressions.
7352
7353    Returns:
7354        A new Select instance with the subquery expression included.
7355    """
7356
7357    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7358    return Select().from_(expression, dialect=dialect, **opts)
7359
7360
7361@t.overload
7362def column(
7363    col: str | Identifier,
7364    table: t.Optional[str | Identifier] = None,
7365    db: t.Optional[str | Identifier] = None,
7366    catalog: t.Optional[str | Identifier] = None,
7367    *,
7368    fields: t.Collection[t.Union[str, Identifier]],
7369    quoted: t.Optional[bool] = None,
7370    copy: bool = True,
7371) -> Dot:
7372    pass
7373
7374
7375@t.overload
7376def column(
7377    col: str | Identifier,
7378    table: t.Optional[str | Identifier] = None,
7379    db: t.Optional[str | Identifier] = None,
7380    catalog: t.Optional[str | Identifier] = None,
7381    *,
7382    fields: Lit[None] = None,
7383    quoted: t.Optional[bool] = None,
7384    copy: bool = True,
7385) -> Column:
7386    pass
7387
7388
7389def column(
7390    col,
7391    table=None,
7392    db=None,
7393    catalog=None,
7394    *,
7395    fields=None,
7396    quoted=None,
7397    copy=True,
7398):
7399    """
7400    Build a Column.
7401
7402    Args:
7403        col: Column name.
7404        table: Table name.
7405        db: Database name.
7406        catalog: Catalog name.
7407        fields: Additional fields using dots.
7408        quoted: Whether to force quotes on the column's identifiers.
7409        copy: Whether to copy identifiers if passed in.
7410
7411    Returns:
7412        The new Column instance.
7413    """
7414    this = Column(
7415        this=to_identifier(col, quoted=quoted, copy=copy),
7416        table=to_identifier(table, quoted=quoted, copy=copy),
7417        db=to_identifier(db, quoted=quoted, copy=copy),
7418        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7419    )
7420
7421    if fields:
7422        this = Dot.build(
7423            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7424        )
7425    return this
7426
7427
7428def cast(
7429    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7430) -> Cast:
7431    """Cast an expression to a data type.
7432
7433    Example:
7434        >>> cast('x + 1', 'int').sql()
7435        'CAST(x + 1 AS INT)'
7436
7437    Args:
7438        expression: The expression to cast.
7439        to: The datatype to cast to.
7440        copy: Whether to copy the supplied expressions.
7441        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7442            - The expression to be cast is already a exp.Cast expression
7443            - The existing cast is to a type that is logically equivalent to new type
7444
7445            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7446            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7447            and instead just return the original expression `CAST(x as DATETIME)`.
7448
7449            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7450            mapping is applied in the target dialect generator.
7451
7452    Returns:
7453        The new Cast instance.
7454    """
7455    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
7456    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
7457
7458    # dont re-cast if the expression is already a cast to the correct type
7459    if isinstance(expr, Cast):
7460        from sqlglot.dialects.dialect import Dialect
7461
7462        target_dialect = Dialect.get_or_raise(dialect)
7463        type_mapping = target_dialect.generator_class.TYPE_MAPPING
7464
7465        existing_cast_type: DataType.Type = expr.to.this
7466        new_cast_type: DataType.Type = data_type.this
7467        types_are_equivalent = type_mapping.get(
7468            existing_cast_type, existing_cast_type
7469        ) == type_mapping.get(new_cast_type, new_cast_type)
7470        if expr.is_type(data_type) or types_are_equivalent:
7471            return expr
7472
7473    expr = Cast(this=expr, to=data_type)
7474    expr.type = data_type
7475
7476    return expr
7477
7478
7479def table_(
7480    table: Identifier | str,
7481    db: t.Optional[Identifier | str] = None,
7482    catalog: t.Optional[Identifier | str] = None,
7483    quoted: t.Optional[bool] = None,
7484    alias: t.Optional[Identifier | str] = None,
7485) -> Table:
7486    """Build a Table.
7487
7488    Args:
7489        table: Table name.
7490        db: Database name.
7491        catalog: Catalog name.
7492        quote: Whether to force quotes on the table's identifiers.
7493        alias: Table's alias.
7494
7495    Returns:
7496        The new Table instance.
7497    """
7498    return Table(
7499        this=to_identifier(table, quoted=quoted) if table else None,
7500        db=to_identifier(db, quoted=quoted) if db else None,
7501        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
7502        alias=TableAlias(this=to_identifier(alias)) if alias else None,
7503    )
7504
7505
7506def values(
7507    values: t.Iterable[t.Tuple[t.Any, ...]],
7508    alias: t.Optional[str] = None,
7509    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
7510) -> Values:
7511    """Build VALUES statement.
7512
7513    Example:
7514        >>> values([(1, '2')]).sql()
7515        "VALUES (1, '2')"
7516
7517    Args:
7518        values: values statements that will be converted to SQL
7519        alias: optional alias
7520        columns: Optional list of ordered column names or ordered dictionary of column names to types.
7521         If either are provided then an alias is also required.
7522
7523    Returns:
7524        Values: the Values expression object
7525    """
7526    if columns and not alias:
7527        raise ValueError("Alias is required when providing columns")
7528
7529    return Values(
7530        expressions=[convert(tup) for tup in values],
7531        alias=(
7532            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
7533            if columns
7534            else (TableAlias(this=to_identifier(alias)) if alias else None)
7535        ),
7536    )
7537
7538
7539def var(name: t.Optional[ExpOrStr]) -> Var:
7540    """Build a SQL variable.
7541
7542    Example:
7543        >>> repr(var('x'))
7544        'Var(this=x)'
7545
7546        >>> repr(var(column('x', table='y')))
7547        'Var(this=x)'
7548
7549    Args:
7550        name: The name of the var or an expression who's name will become the var.
7551
7552    Returns:
7553        The new variable node.
7554    """
7555    if not name:
7556        raise ValueError("Cannot convert empty name into var.")
7557
7558    if isinstance(name, Expression):
7559        name = name.name
7560    return Var(this=name)
7561
7562
7563def rename_table(
7564    old_name: str | Table,
7565    new_name: str | Table,
7566    dialect: DialectType = None,
7567) -> Alter:
7568    """Build ALTER TABLE... RENAME... expression
7569
7570    Args:
7571        old_name: The old name of the table
7572        new_name: The new name of the table
7573        dialect: The dialect to parse the table.
7574
7575    Returns:
7576        Alter table expression
7577    """
7578    old_table = to_table(old_name, dialect=dialect)
7579    new_table = to_table(new_name, dialect=dialect)
7580    return Alter(
7581        this=old_table,
7582        kind="TABLE",
7583        actions=[
7584            RenameTable(this=new_table),
7585        ],
7586    )
7587
7588
7589def rename_column(
7590    table_name: str | Table,
7591    old_column_name: str | Column,
7592    new_column_name: str | Column,
7593    exists: t.Optional[bool] = None,
7594    dialect: DialectType = None,
7595) -> Alter:
7596    """Build ALTER TABLE... RENAME COLUMN... expression
7597
7598    Args:
7599        table_name: Name of the table
7600        old_column: The old name of the column
7601        new_column: The new name of the column
7602        exists: Whether to add the `IF EXISTS` clause
7603        dialect: The dialect to parse the table/column.
7604
7605    Returns:
7606        Alter table expression
7607    """
7608    table = to_table(table_name, dialect=dialect)
7609    old_column = to_column(old_column_name, dialect=dialect)
7610    new_column = to_column(new_column_name, dialect=dialect)
7611    return Alter(
7612        this=table,
7613        kind="TABLE",
7614        actions=[
7615            RenameColumn(this=old_column, to=new_column, exists=exists),
7616        ],
7617    )
7618
7619
7620def convert(value: t.Any, copy: bool = False) -> Expression:
7621    """Convert a python value into an expression object.
7622
7623    Raises an error if a conversion is not possible.
7624
7625    Args:
7626        value: A python object.
7627        copy: Whether to copy `value` (only applies to Expressions and collections).
7628
7629    Returns:
7630        The equivalent expression object.
7631    """
7632    if isinstance(value, Expression):
7633        return maybe_copy(value, copy)
7634    if isinstance(value, str):
7635        return Literal.string(value)
7636    if isinstance(value, bool):
7637        return Boolean(this=value)
7638    if value is None or (isinstance(value, float) and math.isnan(value)):
7639        return null()
7640    if isinstance(value, numbers.Number):
7641        return Literal.number(value)
7642    if isinstance(value, bytes):
7643        return HexString(this=value.hex())
7644    if isinstance(value, datetime.datetime):
7645        datetime_literal = Literal.string(value.isoformat(sep=" "))
7646
7647        tz = None
7648        if value.tzinfo:
7649            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
7650            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
7651            tz = Literal.string(str(value.tzinfo))
7652
7653        return TimeStrToTime(this=datetime_literal, zone=tz)
7654    if isinstance(value, datetime.date):
7655        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
7656        return DateStrToDate(this=date_literal)
7657    if isinstance(value, tuple):
7658        if hasattr(value, "_fields"):
7659            return Struct(
7660                expressions=[
7661                    PropertyEQ(
7662                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
7663                    )
7664                    for k in value._fields
7665                ]
7666            )
7667        return Tuple(expressions=[convert(v, copy=copy) for v in value])
7668    if isinstance(value, list):
7669        return Array(expressions=[convert(v, copy=copy) for v in value])
7670    if isinstance(value, dict):
7671        return Map(
7672            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
7673            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
7674        )
7675    if hasattr(value, "__dict__"):
7676        return Struct(
7677            expressions=[
7678                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
7679                for k, v in value.__dict__.items()
7680            ]
7681        )
7682    raise ValueError(f"Cannot convert {value}")
7683
7684
7685def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
7686    """
7687    Replace children of an expression with the result of a lambda fun(child) -> exp.
7688    """
7689    for k, v in tuple(expression.args.items()):
7690        is_list_arg = type(v) is list
7691
7692        child_nodes = v if is_list_arg else [v]
7693        new_child_nodes = []
7694
7695        for cn in child_nodes:
7696            if isinstance(cn, Expression):
7697                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
7698                    new_child_nodes.append(child_node)
7699            else:
7700                new_child_nodes.append(cn)
7701
7702        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))
7703
7704
7705def replace_tree(
7706    expression: Expression,
7707    fun: t.Callable,
7708    prune: t.Optional[t.Callable[[Expression], bool]] = None,
7709) -> Expression:
7710    """
7711    Replace an entire tree with the result of function calls on each node.
7712
7713    This will be traversed in reverse dfs, so leaves first.
7714    If new nodes are created as a result of function calls, they will also be traversed.
7715    """
7716    stack = list(expression.dfs(prune=prune))
7717
7718    while stack:
7719        node = stack.pop()
7720        new_node = fun(node)
7721
7722        if new_node is not node:
7723            node.replace(new_node)
7724
7725            if isinstance(new_node, Expression):
7726                stack.append(new_node)
7727
7728    return new_node
7729
7730
7731def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
7732    """
7733    Return all table names referenced through columns in an expression.
7734
7735    Example:
7736        >>> import sqlglot
7737        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
7738        ['a', 'c']
7739
7740    Args:
7741        expression: expression to find table names.
7742        exclude: a table name to exclude
7743
7744    Returns:
7745        A list of unique names.
7746    """
7747    return {
7748        table
7749        for table in (column.table for column in expression.find_all(Column))
7750        if table and table != exclude
7751    }
7752
7753
7754def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
7755    """Get the full name of a table as a string.
7756
7757    Args:
7758        table: Table expression node or string.
7759        dialect: The dialect to generate the table name for.
7760        identify: Determines when an identifier should be quoted. Possible values are:
7761            False (default): Never quote, except in cases where it's mandatory by the dialect.
7762            True: Always quote.
7763
7764    Examples:
7765        >>> from sqlglot import exp, parse_one
7766        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
7767        'a.b.c'
7768
7769    Returns:
7770        The table name.
7771    """
7772
7773    table = maybe_parse(table, into=Table, dialect=dialect)
7774
7775    if not table:
7776        raise ValueError(f"Cannot parse {table}")
7777
7778    return ".".join(
7779        (
7780            part.sql(dialect=dialect, identify=True, copy=False)
7781            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
7782            else part.name
7783        )
7784        for part in table.parts
7785    )
7786
7787
7788def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
7789    """Returns a case normalized table name without quotes.
7790
7791    Args:
7792        table: the table to normalize
7793        dialect: the dialect to use for normalization rules
7794        copy: whether to copy the expression.
7795
7796    Examples:
7797        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
7798        'A-B.c'
7799    """
7800    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
7801
7802    return ".".join(
7803        p.name
7804        for p in normalize_identifiers(
7805            to_table(table, dialect=dialect, copy=copy), dialect=dialect
7806        ).parts
7807    )
7808
7809
7810def replace_tables(
7811    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
7812) -> E:
7813    """Replace all tables in expression according to the mapping.
7814
7815    Args:
7816        expression: expression node to be transformed and replaced.
7817        mapping: mapping of table names.
7818        dialect: the dialect of the mapping table
7819        copy: whether to copy the expression.
7820
7821    Examples:
7822        >>> from sqlglot import exp, parse_one
7823        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
7824        'SELECT * FROM c /* a.b */'
7825
7826    Returns:
7827        The mapped expression.
7828    """
7829
7830    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
7831
7832    def _replace_tables(node: Expression) -> Expression:
7833        if isinstance(node, Table):
7834            original = normalize_table_name(node, dialect=dialect)
7835            new_name = mapping.get(original)
7836
7837            if new_name:
7838                table = to_table(
7839                    new_name,
7840                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
7841                    dialect=dialect,
7842                )
7843                table.add_comments([original])
7844                return table
7845        return node
7846
7847    return expression.transform(_replace_tables, copy=copy)  # type: ignore
7848
7849
7850def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
7851    """Replace placeholders in an expression.
7852
7853    Args:
7854        expression: expression node to be transformed and replaced.
7855        args: positional names that will substitute unnamed placeholders in the given order.
7856        kwargs: keyword arguments that will substitute named placeholders.
7857
7858    Examples:
7859        >>> from sqlglot import exp, parse_one
7860        >>> replace_placeholders(
7861        ...     parse_one("select * from :tbl where ? = ?"),
7862        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
7863        ... ).sql()
7864        "SELECT * FROM foo WHERE str_col = 'b'"
7865
7866    Returns:
7867        The mapped expression.
7868    """
7869
7870    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
7871        if isinstance(node, Placeholder):
7872            if node.this:
7873                new_name = kwargs.get(node.this)
7874                if new_name is not None:
7875                    return convert(new_name)
7876            else:
7877                try:
7878                    return convert(next(args))
7879                except StopIteration:
7880                    pass
7881        return node
7882
7883    return expression.transform(_replace_placeholders, iter(args), **kwargs)
7884
7885
7886def expand(
7887    expression: Expression,
7888    sources: t.Dict[str, Query],
7889    dialect: DialectType = None,
7890    copy: bool = True,
7891) -> Expression:
7892    """Transforms an expression by expanding all referenced sources into subqueries.
7893
7894    Examples:
7895        >>> from sqlglot import parse_one
7896        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
7897        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
7898
7899        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
7900        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
7901
7902    Args:
7903        expression: The expression to expand.
7904        sources: A dictionary of name to Queries.
7905        dialect: The dialect of the sources dict.
7906        copy: Whether to copy the expression during transformation. Defaults to True.
7907
7908    Returns:
7909        The transformed expression.
7910    """
7911    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
7912
7913    def _expand(node: Expression):
7914        if isinstance(node, Table):
7915            name = normalize_table_name(node, dialect=dialect)
7916            source = sources.get(name)
7917            if source:
7918                subquery = source.subquery(node.alias or name)
7919                subquery.comments = [f"source: {name}"]
7920                return subquery.transform(_expand, copy=False)
7921        return node
7922
7923    return expression.transform(_expand, copy=copy)
7924
7925
7926def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
7927    """
7928    Returns a Func expression.
7929
7930    Examples:
7931        >>> func("abs", 5).sql()
7932        'ABS(5)'
7933
7934        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
7935        'CAST(5 AS DOUBLE)'
7936
7937    Args:
7938        name: the name of the function to build.
7939        args: the args used to instantiate the function of interest.
7940        copy: whether to copy the argument expressions.
7941        dialect: the source dialect.
7942        kwargs: the kwargs used to instantiate the function of interest.
7943
7944    Note:
7945        The arguments `args` and `kwargs` are mutually exclusive.
7946
7947    Returns:
7948        An instance of the function of interest, or an anonymous function, if `name` doesn't
7949        correspond to an existing `sqlglot.expressions.Func` class.
7950    """
7951    if args and kwargs:
7952        raise ValueError("Can't use both args and kwargs to instantiate a function.")
7953
7954    from sqlglot.dialects.dialect import Dialect
7955
7956    dialect = Dialect.get_or_raise(dialect)
7957
7958    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
7959    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
7960
7961    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
7962    if constructor:
7963        if converted:
7964            if "dialect" in constructor.__code__.co_varnames:
7965                function = constructor(converted, dialect=dialect)
7966            else:
7967                function = constructor(converted)
7968        elif constructor.__name__ == "from_arg_list":
7969            function = constructor.__self__(**kwargs)  # type: ignore
7970        else:
7971            constructor = FUNCTION_BY_NAME.get(name.upper())
7972            if constructor:
7973                function = constructor(**kwargs)
7974            else:
7975                raise ValueError(
7976                    f"Unable to convert '{name}' into a Func. Either manually construct "
7977                    "the Func expression of interest or parse the function call."
7978                )
7979    else:
7980        kwargs = kwargs or {"expressions": converted}
7981        function = Anonymous(this=name, **kwargs)
7982
7983    for error_message in function.error_messages(converted):
7984        raise ValueError(error_message)
7985
7986    return function
7987
7988
7989def case(
7990    expression: t.Optional[ExpOrStr] = None,
7991    **opts,
7992) -> Case:
7993    """
7994    Initialize a CASE statement.
7995
7996    Example:
7997        case().when("a = 1", "foo").else_("bar")
7998
7999    Args:
8000        expression: Optionally, the input expression (not all dialects support this)
8001        **opts: Extra keyword arguments for parsing `expression`
8002    """
8003    if expression is not None:
8004        this = maybe_parse(expression, **opts)
8005    else:
8006        this = None
8007    return Case(this=this, ifs=[])
8008
8009
8010def array(
8011    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8012) -> Array:
8013    """
8014    Returns an array.
8015
8016    Examples:
8017        >>> array(1, 'x').sql()
8018        'ARRAY(1, x)'
8019
8020    Args:
8021        expressions: the expressions to add to the array.
8022        copy: whether to copy the argument expressions.
8023        dialect: the source dialect.
8024        kwargs: the kwargs used to instantiate the function of interest.
8025
8026    Returns:
8027        An array expression.
8028    """
8029    return Array(
8030        expressions=[
8031            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8032            for expression in expressions
8033        ]
8034    )
8035
8036
8037def tuple_(
8038    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8039) -> Tuple:
8040    """
8041    Returns an tuple.
8042
8043    Examples:
8044        >>> tuple_(1, 'x').sql()
8045        '(1, x)'
8046
8047    Args:
8048        expressions: the expressions to add to the tuple.
8049        copy: whether to copy the argument expressions.
8050        dialect: the source dialect.
8051        kwargs: the kwargs used to instantiate the function of interest.
8052
8053    Returns:
8054        A tuple expression.
8055    """
8056    return Tuple(
8057        expressions=[
8058            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8059            for expression in expressions
8060        ]
8061    )
8062
8063
8064def true() -> Boolean:
8065    """
8066    Returns a true Boolean expression.
8067    """
8068    return Boolean(this=True)
8069
8070
8071def false() -> Boolean:
8072    """
8073    Returns a false Boolean expression.
8074    """
8075    return Boolean(this=False)
8076
8077
8078def null() -> Null:
8079    """
8080    Returns a Null expression.
8081    """
8082    return Null()
8083
8084
8085NONNULL_CONSTANTS = (
8086    Literal,
8087    Boolean,
8088)
8089
8090CONSTANTS = (
8091    Literal,
8092    Boolean,
8093    Null,
8094)
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.UNION: 'UNION'>, <Type.NESTED: 'NESTED'>}
ARRAY_TYPES = {<Type.LIST: 'LIST'>, <Type.ARRAY: 'ARRAY'>}
NESTED_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.UNION: 'UNION'>, <Type.ARRAY: 'ARRAY'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.LIST: 'LIST'>, <Type.MAP: 'MAP'>}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.NAME: 'NAME'>, <Type.TEXT: 'TEXT'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.VARCHAR: 'VARCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT256: 'UINT256'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT: 'UINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>}
INTEGER_TYPES = {<Type.BIGINT: 'BIGINT'>, <Type.INT256: 'INT256'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT256: 'UINT256'>, <Type.UBIGINT: 'UBIGINT'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.INT128: 'INT128'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.MONEY: 'MONEY'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL64: 'DECIMAL64'>}
NUMERIC_TYPES = {<Type.INT256: 'INT256'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UBIGINT: 'UBIGINT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.INT128: 'INT128'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.FLOAT: 'FLOAT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT128: 'UINT128'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.BIGINT: 'BIGINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UINT256: 'UINT256'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.BIT: 'BIT'>, <Type.UINT: 'UINT'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.MONEY: 'MONEY'>, <Type.TINYINT: 'TINYINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>}
TEMPORAL_TYPES = {<Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIMESTAMP: 'TIMESTAMP'>}
@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 Columns(Func):
4988class Columns(Func):
4989    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
4993class Convert(Func):
4994    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
4997class ConvertTimezone(Func):
4998    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):
5001class GenerateSeries(Func):
5002    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):
5008class ExplodingGenerateSeries(GenerateSeries):
5009    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5012class ArrayAgg(AggFunc):
5013    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5016class ArrayUniqueAgg(AggFunc):
5017    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5020class ArrayAll(Func):
5021    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5025class ArrayAny(Func):
5026    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5029class ArrayConcat(Func):
5030    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5031    arg_types = {"this": True, "expressions": False}
5032    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5035class ArrayConstructCompact(Func):
5036    arg_types = {"expressions": True}
5037    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5040class ArrayContains(Binary, Func):
5041    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5044class ArrayContainsAll(Binary, Func):
5045    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5048class ArrayFilter(Func):
5049    arg_types = {"this": True, "expression": True}
5050    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5053class ArrayToString(Func):
5054    arg_types = {"this": True, "expression": True, "null": False}
5055    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
5058class StringToArray(Func):
5059    arg_types = {"this": True, "expression": True, "null": False}
5060    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5063class ArrayOverlaps(Binary, Func):
5064    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5067class ArraySize(Func):
5068    arg_types = {"this": True, "expression": False}
5069    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5072class ArraySort(Func):
5073    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5076class ArraySum(Func):
5077    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5080class ArrayUnionAgg(AggFunc):
5081    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5084class Avg(AggFunc):
5085    pass
key = 'avg'
class AnyValue(AggFunc):
5088class AnyValue(AggFunc):
5089    pass
key = 'anyvalue'
class Lag(AggFunc):
5092class Lag(AggFunc):
5093    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5096class Lead(AggFunc):
5097    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5102class First(AggFunc):
5103    pass
key = 'first'
class Last(AggFunc):
5106class Last(AggFunc):
5107    pass
key = 'last'
class FirstValue(AggFunc):
5110class FirstValue(AggFunc):
5111    pass
key = 'firstvalue'
class LastValue(AggFunc):
5114class LastValue(AggFunc):
5115    pass
key = 'lastvalue'
class NthValue(AggFunc):
5118class NthValue(AggFunc):
5119    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5122class Case(Func):
5123    arg_types = {"this": False, "ifs": True, "default": False}
5124
5125    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5126        instance = maybe_copy(self, copy)
5127        instance.append(
5128            "ifs",
5129            If(
5130                this=maybe_parse(condition, copy=copy, **opts),
5131                true=maybe_parse(then, copy=copy, **opts),
5132            ),
5133        )
5134        return instance
5135
5136    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5137        instance = maybe_copy(self, copy)
5138        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5139        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:
5125    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5126        instance = maybe_copy(self, copy)
5127        instance.append(
5128            "ifs",
5129            If(
5130                this=maybe_parse(condition, copy=copy, **opts),
5131                true=maybe_parse(then, copy=copy, **opts),
5132            ),
5133        )
5134        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5136    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5137        instance = maybe_copy(self, copy)
5138        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5139        return instance
key = 'case'
class Cast(Func):
5142class Cast(Func):
5143    arg_types = {
5144        "this": True,
5145        "to": True,
5146        "format": False,
5147        "safe": False,
5148        "action": False,
5149    }
5150
5151    @property
5152    def name(self) -> str:
5153        return self.this.name
5154
5155    @property
5156    def to(self) -> DataType:
5157        return self.args["to"]
5158
5159    @property
5160    def output_name(self) -> str:
5161        return self.name
5162
5163    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5164        """
5165        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5166        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5167        array<int> != array<float>.
5168
5169        Args:
5170            dtypes: the data types to compare this Cast's DataType to.
5171
5172        Returns:
5173            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5174        """
5175        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5151    @property
5152    def name(self) -> str:
5153        return self.this.name
to: DataType
5155    @property
5156    def to(self) -> DataType:
5157        return self.args["to"]
output_name: str
5159    @property
5160    def output_name(self) -> str:
5161        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:
5163    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5164        """
5165        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5166        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5167        array<int> != array<float>.
5168
5169        Args:
5170            dtypes: the data types to compare this Cast's DataType to.
5171
5172        Returns:
5173            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5174        """
5175        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):
5178class TryCast(Cast):
5179    pass
key = 'trycast'
class Try(Func):
5182class Try(Func):
5183    pass
key = 'try'
class CastToStrType(Func):
5186class CastToStrType(Func):
5187    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5190class Collate(Binary, Func):
5191    pass
key = 'collate'
class Ceil(Func):
5194class Ceil(Func):
5195    arg_types = {"this": True, "decimals": False}
5196    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5199class Coalesce(Func):
5200    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5201    is_var_len_args = True
5202    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5205class Chr(Func):
5206    arg_types = {"expressions": True, "charset": False}
5207    is_var_len_args = True
5208    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5211class Concat(Func):
5212    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5213    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5216class ConcatWs(Concat):
5217    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5221class ConnectByRoot(Func):
5222    pass
key = 'connectbyroot'
class Count(AggFunc):
5225class Count(AggFunc):
5226    arg_types = {"this": False, "expressions": False, "big_int": False}
5227    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5230class CountIf(AggFunc):
5231    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5235class Cbrt(Func):
5236    pass
key = 'cbrt'
class CurrentDate(Func):
5239class CurrentDate(Func):
5240    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5243class CurrentDatetime(Func):
5244    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5247class CurrentTime(Func):
5248    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5251class CurrentTimestamp(Func):
5252    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5255class CurrentUser(Func):
5256    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5259class DateAdd(Func, IntervalOp):
5260    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5263class DateSub(Func, IntervalOp):
5264    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5267class DateDiff(Func, TimeUnit):
5268    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5269    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5272class DateTrunc(Func):
5273    arg_types = {"unit": True, "this": True, "zone": False}
5274
5275    def __init__(self, **args):
5276        unit = args.get("unit")
5277        if isinstance(unit, TimeUnit.VAR_LIKE):
5278            args["unit"] = Literal.string(
5279                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5280            )
5281        elif isinstance(unit, Week):
5282            unit.set("this", Literal.string(unit.this.name.upper()))
5283
5284        super().__init__(**args)
5285
5286    @property
5287    def unit(self) -> Expression:
5288        return self.args["unit"]
DateTrunc(**args)
5275    def __init__(self, **args):
5276        unit = args.get("unit")
5277        if isinstance(unit, TimeUnit.VAR_LIKE):
5278            args["unit"] = Literal.string(
5279                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5280            )
5281        elif isinstance(unit, Week):
5282            unit.set("this", Literal.string(unit.this.name.upper()))
5283
5284        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5286    @property
5287    def unit(self) -> Expression:
5288        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5293class Datetime(Func):
5294    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5297class DatetimeAdd(Func, IntervalOp):
5298    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5301class DatetimeSub(Func, IntervalOp):
5302    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5305class DatetimeDiff(Func, TimeUnit):
5306    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5309class DatetimeTrunc(Func, TimeUnit):
5310    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5313class DayOfWeek(Func):
5314    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5319class DayOfWeekIso(Func):
5320    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5323class DayOfMonth(Func):
5324    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5327class DayOfYear(Func):
5328    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5331class ToDays(Func):
5332    pass
key = 'todays'
class WeekOfYear(Func):
5335class WeekOfYear(Func):
5336    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5339class MonthsBetween(Func):
5340    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5343class LastDay(Func, TimeUnit):
5344    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5345    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5348class Extract(Func):
5349    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5352class Timestamp(Func):
5353    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5356class TimestampAdd(Func, TimeUnit):
5357    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5360class TimestampSub(Func, TimeUnit):
5361    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5364class TimestampDiff(Func, TimeUnit):
5365    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5366    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5369class TimestampTrunc(Func, TimeUnit):
5370    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5373class TimeAdd(Func, TimeUnit):
5374    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5377class TimeSub(Func, TimeUnit):
5378    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5381class TimeDiff(Func, TimeUnit):
5382    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5385class TimeTrunc(Func, TimeUnit):
5386    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5389class DateFromParts(Func):
5390    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5391    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5394class TimeFromParts(Func):
5395    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5396    arg_types = {
5397        "hour": True,
5398        "min": True,
5399        "sec": True,
5400        "nano": False,
5401        "fractions": False,
5402        "precision": False,
5403    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5406class DateStrToDate(Func):
5407    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5410class DateToDateStr(Func):
5411    pass
key = 'datetodatestr'
class DateToDi(Func):
5414class DateToDi(Func):
5415    pass
key = 'datetodi'
class Date(Func):
5419class Date(Func):
5420    arg_types = {"this": False, "zone": False, "expressions": False}
5421    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5424class Day(Func):
5425    pass
key = 'day'
class Decode(Func):
5428class Decode(Func):
5429    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5432class DiToDate(Func):
5433    pass
key = 'ditodate'
class Encode(Func):
5436class Encode(Func):
5437    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5440class Exp(Func):
5441    pass
key = 'exp'
class Explode(Func):
5445class Explode(Func):
5446    arg_types = {"this": True, "expressions": False}
5447    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5451class Inline(Func):
5452    pass
key = 'inline'
class ExplodeOuter(Explode):
5455class ExplodeOuter(Explode):
5456    pass
key = 'explodeouter'
class Posexplode(Explode):
5459class Posexplode(Explode):
5460    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5463class PosexplodeOuter(Posexplode, ExplodeOuter):
5464    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5467class Unnest(Func, UDTF):
5468    arg_types = {
5469        "expressions": True,
5470        "alias": False,
5471        "offset": False,
5472        "explode_array": False,
5473    }
5474
5475    @property
5476    def selects(self) -> t.List[Expression]:
5477        columns = super().selects
5478        offset = self.args.get("offset")
5479        if offset:
5480            columns = columns + [to_identifier("offset") if offset is True else offset]
5481        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5475    @property
5476    def selects(self) -> t.List[Expression]:
5477        columns = super().selects
5478        offset = self.args.get("offset")
5479        if offset:
5480            columns = columns + [to_identifier("offset") if offset is True else offset]
5481        return columns
key = 'unnest'
class Floor(Func):
5484class Floor(Func):
5485    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5488class FromBase64(Func):
5489    pass
key = 'frombase64'
class ToBase64(Func):
5492class ToBase64(Func):
5493    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5497class FromISO8601Timestamp(Func):
5498    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5501class GapFill(Func):
5502    arg_types = {
5503        "this": True,
5504        "ts_column": True,
5505        "bucket_width": True,
5506        "partitioning_columns": False,
5507        "value_columns": False,
5508        "origin": False,
5509        "ignore_nulls": False,
5510    }
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):
5514class GenerateDateArray(Func):
5515    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5519class GenerateTimestampArray(Func):
5520    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5523class Greatest(Func):
5524    arg_types = {"this": True, "expressions": False}
5525    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5528class GroupConcat(AggFunc):
5529    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5532class Hex(Func):
5533    pass
key = 'hex'
class LowerHex(Hex):
5536class LowerHex(Hex):
5537    pass
key = 'lowerhex'
class Xor(Connector, Func):
5540class Xor(Connector, Func):
5541    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5544class If(Func):
5545    arg_types = {"this": True, "true": True, "false": False}
5546    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5549class Nullif(Func):
5550    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5553class Initcap(Func):
5554    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5557class IsNan(Func):
5558    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5561class IsInf(Func):
5562    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5566class JSON(Expression):
5567    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5570class JSONPath(Expression):
5571    arg_types = {"expressions": True, "escape": False}
5572
5573    @property
5574    def output_name(self) -> str:
5575        last_segment = self.expressions[-1].this
5576        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5573    @property
5574    def output_name(self) -> str:
5575        last_segment = self.expressions[-1].this
5576        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):
5579class JSONPathPart(Expression):
5580    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5583class JSONPathFilter(JSONPathPart):
5584    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5587class JSONPathKey(JSONPathPart):
5588    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5591class JSONPathRecursive(JSONPathPart):
5592    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5595class JSONPathRoot(JSONPathPart):
5596    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5599class JSONPathScript(JSONPathPart):
5600    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5603class JSONPathSlice(JSONPathPart):
5604    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5607class JSONPathSelector(JSONPathPart):
5608    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5611class JSONPathSubscript(JSONPathPart):
5612    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5615class JSONPathUnion(JSONPathPart):
5616    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5619class JSONPathWildcard(JSONPathPart):
5620    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5623class FormatJson(Expression):
5624    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5627class JSONKeyValue(Expression):
5628    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5631class JSONObject(Func):
5632    arg_types = {
5633        "expressions": False,
5634        "null_handling": False,
5635        "unique_keys": False,
5636        "return_type": False,
5637        "encoding": False,
5638    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5641class JSONObjectAgg(AggFunc):
5642    arg_types = {
5643        "expressions": False,
5644        "null_handling": False,
5645        "unique_keys": False,
5646        "return_type": False,
5647        "encoding": False,
5648    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5652class JSONArray(Func):
5653    arg_types = {
5654        "expressions": True,
5655        "null_handling": False,
5656        "return_type": False,
5657        "strict": False,
5658    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5662class JSONArrayAgg(Func):
5663    arg_types = {
5664        "this": True,
5665        "order": False,
5666        "null_handling": False,
5667        "return_type": False,
5668        "strict": False,
5669    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
5672class JSONExists(Func):
5673    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):
5678class JSONColumnDef(Expression):
5679    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):
5682class JSONSchema(Expression):
5683    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
5687class JSONValue(Expression):
5688    arg_types = {
5689        "this": True,
5690        "path": True,
5691        "returning": False,
5692        "on_condition": False,
5693    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONTable(Func):
5697class JSONTable(Func):
5698    arg_types = {
5699        "this": True,
5700        "schema": True,
5701        "path": False,
5702        "error_handling": False,
5703        "empty_handling": False,
5704    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5708class ObjectInsert(Func):
5709    arg_types = {
5710        "this": True,
5711        "key": True,
5712        "value": True,
5713        "update_flag": False,
5714    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5717class OpenJSONColumnDef(Expression):
5718    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):
5721class OpenJSON(Func):
5722    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5725class JSONBContains(Binary, Func):
5726    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5729class JSONExtract(Binary, Func):
5730    arg_types = {
5731        "this": True,
5732        "expression": True,
5733        "only_json_types": False,
5734        "expressions": False,
5735        "variant_extract": False,
5736    }
5737    _sql_names = ["JSON_EXTRACT"]
5738    is_var_len_args = True
5739
5740    @property
5741    def output_name(self) -> str:
5742        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
5740    @property
5741    def output_name(self) -> str:
5742        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):
5745class JSONExtractScalar(Binary, Func):
5746    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5747    _sql_names = ["JSON_EXTRACT_SCALAR"]
5748    is_var_len_args = True
5749
5750    @property
5751    def output_name(self) -> str:
5752        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
5750    @property
5751    def output_name(self) -> str:
5752        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):
5755class JSONBExtract(Binary, Func):
5756    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5759class JSONBExtractScalar(Binary, Func):
5760    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5763class JSONFormat(Func):
5764    arg_types = {"this": False, "options": False}
5765    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5769class JSONArrayContains(Binary, Predicate, Func):
5770    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5773class ParseJSON(Func):
5774    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5775    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5776    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5777    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5780class Least(Func):
5781    arg_types = {"this": True, "expressions": False}
5782    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5785class Left(Func):
5786    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5793class Length(Func):
5794    arg_types = {"this": True, "binary": False}
5795    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5798class Levenshtein(Func):
5799    arg_types = {
5800        "this": True,
5801        "expression": False,
5802        "ins_cost": False,
5803        "del_cost": False,
5804        "sub_cost": False,
5805    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5808class Ln(Func):
5809    pass
key = 'ln'
class Log(Func):
5812class Log(Func):
5813    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5816class LogicalOr(AggFunc):
5817    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5820class LogicalAnd(AggFunc):
5821    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5824class Lower(Func):
5825    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5828class Map(Func):
5829    arg_types = {"keys": False, "values": False}
5830
5831    @property
5832    def keys(self) -> t.List[Expression]:
5833        keys = self.args.get("keys")
5834        return keys.expressions if keys else []
5835
5836    @property
5837    def values(self) -> t.List[Expression]:
5838        values = self.args.get("values")
5839        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5831    @property
5832    def keys(self) -> t.List[Expression]:
5833        keys = self.args.get("keys")
5834        return keys.expressions if keys else []
values: List[Expression]
5836    @property
5837    def values(self) -> t.List[Expression]:
5838        values = self.args.get("values")
5839        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5843class ToMap(Func):
5844    pass
key = 'tomap'
class MapFromEntries(Func):
5847class MapFromEntries(Func):
5848    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5852class ScopeResolution(Expression):
5853    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
5856class Stream(Expression):
5857    pass
key = 'stream'
class StarMap(Func):
5860class StarMap(Func):
5861    pass
key = 'starmap'
class VarMap(Func):
5864class VarMap(Func):
5865    arg_types = {"keys": True, "values": True}
5866    is_var_len_args = True
5867
5868    @property
5869    def keys(self) -> t.List[Expression]:
5870        return self.args["keys"].expressions
5871
5872    @property
5873    def values(self) -> t.List[Expression]:
5874        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5868    @property
5869    def keys(self) -> t.List[Expression]:
5870        return self.args["keys"].expressions
values: List[Expression]
5872    @property
5873    def values(self) -> t.List[Expression]:
5874        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5878class MatchAgainst(Func):
5879    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5882class Max(AggFunc):
5883    arg_types = {"this": True, "expressions": False}
5884    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5887class MD5(Func):
5888    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5892class MD5Digest(Func):
5893    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5896class Min(AggFunc):
5897    arg_types = {"this": True, "expressions": False}
5898    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5901class Month(Func):
5902    pass
key = 'month'
class AddMonths(Func):
5905class AddMonths(Func):
5906    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5909class Nvl2(Func):
5910    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
5913class Normalize(Func):
5914    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
5917class Overlay(Func):
5918    arg_types = {"this": True, "expression": True, "from": True, "for": False}
arg_types = {'this': True, 'expression': True, 'from': True, 'for': False}
key = 'overlay'
class Predict(Func):
5922class Predict(Func):
5923    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5926class Pow(Binary, Func):
5927    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5930class PercentileCont(AggFunc):
5931    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5934class PercentileDisc(AggFunc):
5935    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5938class Quantile(AggFunc):
5939    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5942class ApproxQuantile(Quantile):
5943    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):
5946class Quarter(Func):
5947    pass
key = 'quarter'
class Rand(Func):
5952class Rand(Func):
5953    _sql_names = ["RAND", "RANDOM"]
5954    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5957class Randn(Func):
5958    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5961class RangeN(Func):
5962    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5965class ReadCSV(Func):
5966    _sql_names = ["READ_CSV"]
5967    is_var_len_args = True
5968    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5971class Reduce(Func):
5972    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):
5975class RegexpExtract(Func):
5976    arg_types = {
5977        "this": True,
5978        "expression": True,
5979        "position": False,
5980        "occurrence": False,
5981        "parameters": False,
5982        "group": False,
5983    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5986class RegexpReplace(Func):
5987    arg_types = {
5988        "this": True,
5989        "expression": True,
5990        "replacement": False,
5991        "position": False,
5992        "occurrence": False,
5993        "modifiers": False,
5994    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
5997class RegexpLike(Binary, Func):
5998    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6001class RegexpILike(Binary, Func):
6002    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6007class RegexpSplit(Func):
6008    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6011class Repeat(Func):
6012    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6017class Round(Func):
6018    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6021class RowNumber(Func):
6022    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
6025class SafeDivide(Func):
6026    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6029class SHA(Func):
6030    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6033class SHA2(Func):
6034    _sql_names = ["SHA2"]
6035    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6038class Sign(Func):
6039    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6042class SortArray(Func):
6043    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6046class Split(Func):
6047    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
6052class Substring(Func):
6053    _sql_names = ["SUBSTRING", "SUBSTR"]
6054    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6057class StandardHash(Func):
6058    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6061class StartsWith(Func):
6062    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6063    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6066class StrPosition(Func):
6067    arg_types = {
6068        "this": True,
6069        "substr": True,
6070        "position": False,
6071        "instance": False,
6072    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
6075class StrToDate(Func):
6076    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6079class StrToTime(Func):
6080    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):
6085class StrToUnix(Func):
6086    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6091class StrToMap(Func):
6092    arg_types = {
6093        "this": True,
6094        "pair_delim": False,
6095        "key_value_delim": False,
6096        "duplicate_resolution_callback": False,
6097    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6100class NumberToStr(Func):
6101    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6104class FromBase(Func):
6105    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6108class Struct(Func):
6109    arg_types = {"expressions": False}
6110    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6113class StructExtract(Func):
6114    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6119class Stuff(Func):
6120    _sql_names = ["STUFF", "INSERT"]
6121    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):
6124class Sum(AggFunc):
6125    pass
key = 'sum'
class Sqrt(Func):
6128class Sqrt(Func):
6129    pass
key = 'sqrt'
class Stddev(AggFunc):
6132class Stddev(AggFunc):
6133    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6136class StddevPop(AggFunc):
6137    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6140class StddevSamp(AggFunc):
6141    pass
key = 'stddevsamp'
class Time(Func):
6145class Time(Func):
6146    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6149class TimeToStr(Func):
6150    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):
6153class TimeToTimeStr(Func):
6154    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6157class TimeToUnix(Func):
6158    pass
key = 'timetounix'
class TimeStrToDate(Func):
6161class TimeStrToDate(Func):
6162    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6165class TimeStrToTime(Func):
6166    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6169class TimeStrToUnix(Func):
6170    pass
key = 'timestrtounix'
class Trim(Func):
6173class Trim(Func):
6174    arg_types = {
6175        "this": True,
6176        "expression": False,
6177        "position": False,
6178        "collation": False,
6179    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6182class TsOrDsAdd(Func, TimeUnit):
6183    # return_type is used to correctly cast the arguments of this expression when transpiling it
6184    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6185
6186    @property
6187    def return_type(self) -> DataType:
6188        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
6186    @property
6187    def return_type(self) -> DataType:
6188        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6191class TsOrDsDiff(Func, TimeUnit):
6192    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6195class TsOrDsToDateStr(Func):
6196    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6199class TsOrDsToDate(Func):
6200    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6203class TsOrDsToTime(Func):
6204    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6207class TsOrDsToTimestamp(Func):
6208    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6211class TsOrDiToDi(Func):
6212    pass
key = 'tsorditodi'
class Unhex(Func):
6215class Unhex(Func):
6216    pass
key = 'unhex'
class UnixDate(Func):
6220class UnixDate(Func):
6221    pass
key = 'unixdate'
class UnixToStr(Func):
6224class UnixToStr(Func):
6225    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6230class UnixToTime(Func):
6231    arg_types = {
6232        "this": True,
6233        "scale": False,
6234        "zone": False,
6235        "hours": False,
6236        "minutes": False,
6237        "format": False,
6238    }
6239
6240    SECONDS = Literal.number(0)
6241    DECIS = Literal.number(1)
6242    CENTIS = Literal.number(2)
6243    MILLIS = Literal.number(3)
6244    DECIMILLIS = Literal.number(4)
6245    CENTIMILLIS = Literal.number(5)
6246    MICROS = Literal.number(6)
6247    DECIMICROS = Literal.number(7)
6248    CENTIMICROS = Literal.number(8)
6249    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):
6252class UnixToTimeStr(Func):
6253    pass
key = 'unixtotimestr'
class Uuid(Func):
6256class Uuid(Func):
6257    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6258
6259    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6262class TimestampFromParts(Func):
6263    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6264    arg_types = {
6265        "year": True,
6266        "month": True,
6267        "day": True,
6268        "hour": True,
6269        "min": True,
6270        "sec": True,
6271        "nano": False,
6272        "zone": False,
6273        "milli": False,
6274    }
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):
6277class Upper(Func):
6278    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6281class Corr(Binary, AggFunc):
6282    pass
key = 'corr'
class Variance(AggFunc):
6285class Variance(AggFunc):
6286    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6289class VariancePop(AggFunc):
6290    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6293class CovarSamp(Binary, AggFunc):
6294    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6297class CovarPop(Binary, AggFunc):
6298    pass
key = 'covarpop'
class Week(Func):
6301class Week(Func):
6302    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6305class XMLTable(Func):
6306    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):
6309class Year(Func):
6310    pass
key = 'year'
class Use(Expression):
6313class Use(Expression):
6314    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(DML):
6317class Merge(DML):
6318    arg_types = {
6319        "this": True,
6320        "using": True,
6321        "on": True,
6322        "expressions": True,
6323        "with": False,
6324        "returning": False,
6325    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False, 'returning': False}
key = 'merge'
class When(Func):
6328class When(Func):
6329    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):
6334class NextValueFor(Func):
6335    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6340class Semicolon(Expression):
6341    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 'Columns'>, <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 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'Time'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'UnixDate'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class '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'>, 'COLUMNS': <class 'Columns'>, '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'>, 'OVERLAY': <class 'Overlay'>, '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'>, '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:
6381def maybe_parse(
6382    sql_or_expression: ExpOrStr,
6383    *,
6384    into: t.Optional[IntoType] = None,
6385    dialect: DialectType = None,
6386    prefix: t.Optional[str] = None,
6387    copy: bool = False,
6388    **opts,
6389) -> Expression:
6390    """Gracefully handle a possible string or expression.
6391
6392    Example:
6393        >>> maybe_parse("1")
6394        Literal(this=1, is_string=False)
6395        >>> maybe_parse(to_identifier("x"))
6396        Identifier(this=x, quoted=False)
6397
6398    Args:
6399        sql_or_expression: the SQL code string or an expression
6400        into: the SQLGlot Expression to parse into
6401        dialect: the dialect used to parse the input expressions (in the case that an
6402            input expression is a SQL string).
6403        prefix: a string to prefix the sql with before it gets parsed
6404            (automatically includes a space)
6405        copy: whether to copy the expression.
6406        **opts: other options to use to parse the input expressions (again, in the case
6407            that an input expression is a SQL string).
6408
6409    Returns:
6410        Expression: the parsed or given expression.
6411    """
6412    if isinstance(sql_or_expression, Expression):
6413        if copy:
6414            return sql_or_expression.copy()
6415        return sql_or_expression
6416
6417    if sql_or_expression is None:
6418        raise ParseError("SQL cannot be None")
6419
6420    import sqlglot
6421
6422    sql = str(sql_or_expression)
6423    if prefix:
6424        sql = f"{prefix} {sql}"
6425
6426    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):
6437def maybe_copy(instance, copy=True):
6438    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:
6659def union(
6660    left: ExpOrStr,
6661    right: ExpOrStr,
6662    distinct: bool = True,
6663    dialect: DialectType = None,
6664    copy: bool = True,
6665    **opts,
6666) -> Union:
6667    """
6668    Initializes a syntax tree from one UNION expression.
6669
6670    Example:
6671        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6672        'SELECT * FROM foo UNION SELECT * FROM bla'
6673
6674    Args:
6675        left: the SQL code string corresponding to the left-hand side.
6676            If an `Expression` instance is passed, it will be used as-is.
6677        right: the SQL code string corresponding to the right-hand side.
6678            If an `Expression` instance is passed, it will be used as-is.
6679        distinct: set the DISTINCT flag if and only if this is true.
6680        dialect: the dialect used to parse the input expression.
6681        copy: whether to copy the expression.
6682        opts: other options to use to parse the input expressions.
6683
6684    Returns:
6685        The new Union instance.
6686    """
6687    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6688    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6689
6690    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:
6693def intersect(
6694    left: ExpOrStr,
6695    right: ExpOrStr,
6696    distinct: bool = True,
6697    dialect: DialectType = None,
6698    copy: bool = True,
6699    **opts,
6700) -> Intersect:
6701    """
6702    Initializes a syntax tree from one INTERSECT expression.
6703
6704    Example:
6705        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6706        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6707
6708    Args:
6709        left: the SQL code string corresponding to the left-hand side.
6710            If an `Expression` instance is passed, it will be used as-is.
6711        right: the SQL code string corresponding to the right-hand side.
6712            If an `Expression` instance is passed, it will be used as-is.
6713        distinct: set the DISTINCT flag if and only if this is true.
6714        dialect: the dialect used to parse the input expression.
6715        copy: whether to copy the expression.
6716        opts: other options to use to parse the input expressions.
6717
6718    Returns:
6719        The new Intersect instance.
6720    """
6721    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6722    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6723
6724    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:
6727def except_(
6728    left: ExpOrStr,
6729    right: ExpOrStr,
6730    distinct: bool = True,
6731    dialect: DialectType = None,
6732    copy: bool = True,
6733    **opts,
6734) -> Except:
6735    """
6736    Initializes a syntax tree from one EXCEPT expression.
6737
6738    Example:
6739        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6740        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6741
6742    Args:
6743        left: the SQL code string corresponding to the left-hand side.
6744            If an `Expression` instance is passed, it will be used as-is.
6745        right: the SQL code string corresponding to the right-hand side.
6746            If an `Expression` instance is passed, it will be used as-is.
6747        distinct: set the DISTINCT flag if and only if this is true.
6748        dialect: the dialect used to parse the input expression.
6749        copy: whether to copy the expression.
6750        opts: other options to use to parse the input expressions.
6751
6752    Returns:
6753        The new Except instance.
6754    """
6755    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6756    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6757
6758    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:
6761def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6762    """
6763    Initializes a syntax tree from one or multiple SELECT expressions.
6764
6765    Example:
6766        >>> select("col1", "col2").from_("tbl").sql()
6767        'SELECT col1, col2 FROM tbl'
6768
6769    Args:
6770        *expressions: the SQL code string to parse as the expressions of a
6771            SELECT statement. If an Expression instance is passed, this is used as-is.
6772        dialect: the dialect used to parse the input expressions (in the case that an
6773            input expression is a SQL string).
6774        **opts: other options to use to parse the input expressions (again, in the case
6775            that an input expression is a SQL string).
6776
6777    Returns:
6778        Select: the syntax tree for the SELECT statement.
6779    """
6780    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:
6783def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6784    """
6785    Initializes a syntax tree from a FROM expression.
6786
6787    Example:
6788        >>> from_("tbl").select("col1", "col2").sql()
6789        'SELECT col1, col2 FROM tbl'
6790
6791    Args:
6792        *expression: the SQL code string to parse as the FROM expressions of a
6793            SELECT statement. If an Expression instance is passed, this is used as-is.
6794        dialect: the dialect used to parse the input expression (in the case that the
6795            input expression is a SQL string).
6796        **opts: other options to use to parse the input expressions (again, in the case
6797            that the input expression is a SQL string).
6798
6799    Returns:
6800        Select: the syntax tree for the SELECT statement.
6801    """
6802    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:
6805def update(
6806    table: str | Table,
6807    properties: dict,
6808    where: t.Optional[ExpOrStr] = None,
6809    from_: t.Optional[ExpOrStr] = None,
6810    dialect: DialectType = None,
6811    **opts,
6812) -> Update:
6813    """
6814    Creates an update statement.
6815
6816    Example:
6817        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6818        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6819
6820    Args:
6821        *properties: dictionary of properties to set which are
6822            auto converted to sql objects eg None -> NULL
6823        where: sql conditional parsed into a WHERE statement
6824        from_: sql statement parsed into a FROM statement
6825        dialect: the dialect used to parse the input expressions.
6826        **opts: other options to use to parse the input expressions.
6827
6828    Returns:
6829        Update: the syntax tree for the UPDATE statement.
6830    """
6831    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6832    update_expr.set(
6833        "expressions",
6834        [
6835            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6836            for k, v in properties.items()
6837        ],
6838    )
6839    if from_:
6840        update_expr.set(
6841            "from",
6842            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6843        )
6844    if isinstance(where, Condition):
6845        where = Where(this=where)
6846    if where:
6847        update_expr.set(
6848            "where",
6849            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6850        )
6851    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:
6854def delete(
6855    table: ExpOrStr,
6856    where: t.Optional[ExpOrStr] = None,
6857    returning: t.Optional[ExpOrStr] = None,
6858    dialect: DialectType = None,
6859    **opts,
6860) -> Delete:
6861    """
6862    Builds a delete statement.
6863
6864    Example:
6865        >>> delete("my_table", where="id > 1").sql()
6866        'DELETE FROM my_table WHERE id > 1'
6867
6868    Args:
6869        where: sql conditional parsed into a WHERE statement
6870        returning: sql conditional parsed into a RETURNING statement
6871        dialect: the dialect used to parse the input expressions.
6872        **opts: other options to use to parse the input expressions.
6873
6874    Returns:
6875        Delete: the syntax tree for the DELETE statement.
6876    """
6877    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6878    if where:
6879        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6880    if returning:
6881        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6882    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:
6885def insert(
6886    expression: ExpOrStr,
6887    into: ExpOrStr,
6888    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6889    overwrite: t.Optional[bool] = None,
6890    returning: t.Optional[ExpOrStr] = None,
6891    dialect: DialectType = None,
6892    copy: bool = True,
6893    **opts,
6894) -> Insert:
6895    """
6896    Builds an INSERT statement.
6897
6898    Example:
6899        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6900        'INSERT INTO tbl VALUES (1, 2, 3)'
6901
6902    Args:
6903        expression: the sql string or expression of the INSERT statement
6904        into: the tbl to insert data to.
6905        columns: optionally the table's column names.
6906        overwrite: whether to INSERT OVERWRITE or not.
6907        returning: sql conditional parsed into a RETURNING statement
6908        dialect: the dialect used to parse the input expressions.
6909        copy: whether to copy the expression.
6910        **opts: other options to use to parse the input expressions.
6911
6912    Returns:
6913        Insert: the syntax tree for the INSERT statement.
6914    """
6915    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6916    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6917
6918    if columns:
6919        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6920
6921    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6922
6923    if returning:
6924        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
6925
6926    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:
6929def merge(
6930    *when_exprs: ExpOrStr,
6931    into: ExpOrStr,
6932    using: ExpOrStr,
6933    on: ExpOrStr,
6934    returning: t.Optional[ExpOrStr] = None,
6935    dialect: DialectType = None,
6936    copy: bool = True,
6937    **opts,
6938) -> Merge:
6939    """
6940    Builds a MERGE statement.
6941
6942    Example:
6943        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
6944        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
6945        ...       into="my_table",
6946        ...       using="source_table",
6947        ...       on="my_table.id = source_table.id").sql()
6948        '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)'
6949
6950    Args:
6951        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
6952        into: The target table to merge data into.
6953        using: The source table to merge data from.
6954        on: The join condition for the merge.
6955        returning: The columns to return from the merge.
6956        dialect: The dialect used to parse the input expressions.
6957        copy: Whether to copy the expression.
6958        **opts: Other options to use to parse the input expressions.
6959
6960    Returns:
6961        Merge: The syntax tree for the MERGE statement.
6962    """
6963    merge = Merge(
6964        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
6965        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
6966        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
6967        expressions=[
6968            maybe_parse(when_expr, dialect=dialect, copy=copy, into=When, **opts)
6969            for when_expr in when_exprs
6970        ],
6971    )
6972    if returning:
6973        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
6974
6975    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:
6978def condition(
6979    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6980) -> Condition:
6981    """
6982    Initialize a logical condition expression.
6983
6984    Example:
6985        >>> condition("x=1").sql()
6986        'x = 1'
6987
6988        This is helpful for composing larger logical syntax trees:
6989        >>> where = condition("x=1")
6990        >>> where = where.and_("y=1")
6991        >>> Select().from_("tbl").select("*").where(where).sql()
6992        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6993
6994    Args:
6995        *expression: the SQL code string to parse.
6996            If an Expression instance is passed, this is used as-is.
6997        dialect: the dialect used to parse the input expression (in the case that the
6998            input expression is a SQL string).
6999        copy: Whether to copy `expression` (only applies to expressions).
7000        **opts: other options to use to parse the input expressions (again, in the case
7001            that the input expression is a SQL string).
7002
7003    Returns:
7004        The new Condition instance
7005    """
7006    return maybe_parse(
7007        expression,
7008        into=Condition,
7009        dialect=dialect,
7010        copy=copy,
7011        **opts,
7012    )

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

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

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

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

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

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

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

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

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

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

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:
8065def true() -> Boolean:
8066    """
8067    Returns a true Boolean expression.
8068    """
8069    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8072def false() -> Boolean:
8073    """
8074    Returns a false Boolean expression.
8075    """
8076    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8079def null() -> Null:
8080    """
8081    Returns a Null expression.
8082    """
8083    return Null()

Returns a Null expression.

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