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

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):
2254class ConditionalInsert(Expression):
2255    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2258class MultitableInserts(Expression):
2259    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2262class OnConflict(Expression):
2263    arg_types = {
2264        "duplicate": False,
2265        "expressions": False,
2266        "action": False,
2267        "conflict_keys": False,
2268        "constraint": False,
2269    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False}
key = 'onconflict'
class OnCondition(Expression):
2272class OnCondition(Expression):
2273    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2276class Returning(Expression):
2277    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2281class Introducer(Expression):
2282    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2286class National(Expression):
2287    pass
key = 'national'
class LoadData(Expression):
2290class LoadData(Expression):
2291    arg_types = {
2292        "this": True,
2293        "local": False,
2294        "overwrite": False,
2295        "inpath": True,
2296        "partition": False,
2297        "input_format": False,
2298        "serde": False,
2299    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2302class Partition(Expression):
2303    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'partition'
class PartitionRange(Expression):
2306class PartitionRange(Expression):
2307    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2311class PartitionId(Expression):
2312    pass
key = 'partitionid'
class Fetch(Expression):
2315class Fetch(Expression):
2316    arg_types = {
2317        "direction": False,
2318        "count": False,
2319        "percent": False,
2320        "with_ties": False,
2321    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Grant(Expression):
2324class Grant(Expression):
2325    arg_types = {
2326        "privileges": True,
2327        "kind": False,
2328        "securable": True,
2329        "principals": True,
2330        "grant_option": False,
2331    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2334class Group(Expression):
2335    arg_types = {
2336        "expressions": False,
2337        "grouping_sets": False,
2338        "cube": False,
2339        "rollup": False,
2340        "totals": False,
2341        "all": False,
2342    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2345class Cube(Expression):
2346    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2349class Rollup(Expression):
2350    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2353class GroupingSets(Expression):
2354    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2357class Lambda(Expression):
2358    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2361class Limit(Expression):
2362    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):
2365class Literal(Condition):
2366    arg_types = {"this": True, "is_string": True}
2367
2368    @property
2369    def hashable_args(self) -> t.Any:
2370        return (self.this, self.args.get("is_string"))
2371
2372    @classmethod
2373    def number(cls, number) -> Literal:
2374        return cls(this=str(number), is_string=False)
2375
2376    @classmethod
2377    def string(cls, string) -> Literal:
2378        return cls(this=str(string), is_string=True)
2379
2380    @property
2381    def output_name(self) -> str:
2382        return self.name
2383
2384    def to_py(self) -> int | str | Decimal:
2385        if self.is_number:
2386            try:
2387                return int(self.this)
2388            except ValueError:
2389                return Decimal(self.this)
2390        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2368    @property
2369    def hashable_args(self) -> t.Any:
2370        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2372    @classmethod
2373    def number(cls, number) -> Literal:
2374        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2376    @classmethod
2377    def string(cls, string) -> Literal:
2378        return cls(this=str(string), is_string=True)
output_name: str
2380    @property
2381    def output_name(self) -> str:
2382        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:
2384    def to_py(self) -> int | str | Decimal:
2385        if self.is_number:
2386            try:
2387                return int(self.this)
2388            except ValueError:
2389                return Decimal(self.this)
2390        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2393class Join(Expression):
2394    arg_types = {
2395        "this": True,
2396        "on": False,
2397        "side": False,
2398        "kind": False,
2399        "using": False,
2400        "method": False,
2401        "global": False,
2402        "hint": False,
2403        "match_condition": False,  # Snowflake
2404    }
2405
2406    @property
2407    def method(self) -> str:
2408        return self.text("method").upper()
2409
2410    @property
2411    def kind(self) -> str:
2412        return self.text("kind").upper()
2413
2414    @property
2415    def side(self) -> str:
2416        return self.text("side").upper()
2417
2418    @property
2419    def hint(self) -> str:
2420        return self.text("hint").upper()
2421
2422    @property
2423    def alias_or_name(self) -> str:
2424        return self.this.alias_or_name
2425
2426    def on(
2427        self,
2428        *expressions: t.Optional[ExpOrStr],
2429        append: bool = True,
2430        dialect: DialectType = None,
2431        copy: bool = True,
2432        **opts,
2433    ) -> Join:
2434        """
2435        Append to or set the ON expressions.
2436
2437        Example:
2438            >>> import sqlglot
2439            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2440            'JOIN x ON y = 1'
2441
2442        Args:
2443            *expressions: the SQL code strings to parse.
2444                If an `Expression` instance is passed, it will be used as-is.
2445                Multiple expressions are combined with an AND operator.
2446            append: if `True`, AND the new expressions to any existing expression.
2447                Otherwise, this resets the expression.
2448            dialect: the dialect used to parse the input expressions.
2449            copy: if `False`, modify this expression instance in-place.
2450            opts: other options to use to parse the input expressions.
2451
2452        Returns:
2453            The modified Join expression.
2454        """
2455        join = _apply_conjunction_builder(
2456            *expressions,
2457            instance=self,
2458            arg="on",
2459            append=append,
2460            dialect=dialect,
2461            copy=copy,
2462            **opts,
2463        )
2464
2465        if join.kind == "CROSS":
2466            join.set("kind", None)
2467
2468        return join
2469
2470    def using(
2471        self,
2472        *expressions: t.Optional[ExpOrStr],
2473        append: bool = True,
2474        dialect: DialectType = None,
2475        copy: bool = True,
2476        **opts,
2477    ) -> Join:
2478        """
2479        Append to or set the USING expressions.
2480
2481        Example:
2482            >>> import sqlglot
2483            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2484            'JOIN x USING (foo, bla)'
2485
2486        Args:
2487            *expressions: the SQL code strings to parse.
2488                If an `Expression` instance is passed, it will be used as-is.
2489            append: if `True`, concatenate the new expressions to the existing "using" list.
2490                Otherwise, this resets the expression.
2491            dialect: the dialect used to parse the input expressions.
2492            copy: if `False`, modify this expression instance in-place.
2493            opts: other options to use to parse the input expressions.
2494
2495        Returns:
2496            The modified Join expression.
2497        """
2498        join = _apply_list_builder(
2499            *expressions,
2500            instance=self,
2501            arg="using",
2502            append=append,
2503            dialect=dialect,
2504            copy=copy,
2505            **opts,
2506        )
2507
2508        if join.kind == "CROSS":
2509            join.set("kind", None)
2510
2511        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
2406    @property
2407    def method(self) -> str:
2408        return self.text("method").upper()
kind: str
2410    @property
2411    def kind(self) -> str:
2412        return self.text("kind").upper()
side: str
2414    @property
2415    def side(self) -> str:
2416        return self.text("side").upper()
hint: str
2418    @property
2419    def hint(self) -> str:
2420        return self.text("hint").upper()
alias_or_name: str
2422    @property
2423    def alias_or_name(self) -> str:
2424        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:
2426    def on(
2427        self,
2428        *expressions: t.Optional[ExpOrStr],
2429        append: bool = True,
2430        dialect: DialectType = None,
2431        copy: bool = True,
2432        **opts,
2433    ) -> Join:
2434        """
2435        Append to or set the ON expressions.
2436
2437        Example:
2438            >>> import sqlglot
2439            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2440            'JOIN x ON y = 1'
2441
2442        Args:
2443            *expressions: the SQL code strings to parse.
2444                If an `Expression` instance is passed, it will be used as-is.
2445                Multiple expressions are combined with an AND operator.
2446            append: if `True`, AND the new expressions to any existing expression.
2447                Otherwise, this resets the expression.
2448            dialect: the dialect used to parse the input expressions.
2449            copy: if `False`, modify this expression instance in-place.
2450            opts: other options to use to parse the input expressions.
2451
2452        Returns:
2453            The modified Join expression.
2454        """
2455        join = _apply_conjunction_builder(
2456            *expressions,
2457            instance=self,
2458            arg="on",
2459            append=append,
2460            dialect=dialect,
2461            copy=copy,
2462            **opts,
2463        )
2464
2465        if join.kind == "CROSS":
2466            join.set("kind", None)
2467
2468        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:
2470    def using(
2471        self,
2472        *expressions: t.Optional[ExpOrStr],
2473        append: bool = True,
2474        dialect: DialectType = None,
2475        copy: bool = True,
2476        **opts,
2477    ) -> Join:
2478        """
2479        Append to or set the USING expressions.
2480
2481        Example:
2482            >>> import sqlglot
2483            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2484            'JOIN x USING (foo, bla)'
2485
2486        Args:
2487            *expressions: the SQL code strings to parse.
2488                If an `Expression` instance is passed, it will be used as-is.
2489            append: if `True`, concatenate the new expressions to the existing "using" list.
2490                Otherwise, this resets the expression.
2491            dialect: the dialect used to parse the input expressions.
2492            copy: if `False`, modify this expression instance in-place.
2493            opts: other options to use to parse the input expressions.
2494
2495        Returns:
2496            The modified Join expression.
2497        """
2498        join = _apply_list_builder(
2499            *expressions,
2500            instance=self,
2501            arg="using",
2502            append=append,
2503            dialect=dialect,
2504            copy=copy,
2505            **opts,
2506        )
2507
2508        if join.kind == "CROSS":
2509            join.set("kind", None)
2510
2511        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):
2514class Lateral(UDTF):
2515    arg_types = {
2516        "this": True,
2517        "view": False,
2518        "outer": False,
2519        "alias": False,
2520        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2521    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2524class MatchRecognizeMeasure(Expression):
2525    arg_types = {
2526        "this": True,
2527        "window_frame": False,
2528    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2531class MatchRecognize(Expression):
2532    arg_types = {
2533        "partition_by": False,
2534        "order": False,
2535        "measures": False,
2536        "rows": False,
2537        "after": False,
2538        "pattern": False,
2539        "define": False,
2540        "alias": False,
2541    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2546class Final(Expression):
2547    pass
key = 'final'
class Offset(Expression):
2550class Offset(Expression):
2551    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2554class Order(Expression):
2555    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2559class WithFill(Expression):
2560    arg_types = {
2561        "from": False,
2562        "to": False,
2563        "step": False,
2564        "interpolate": False,
2565    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2570class Cluster(Order):
2571    pass
key = 'cluster'
class Distribute(Order):
2574class Distribute(Order):
2575    pass
key = 'distribute'
class Sort(Order):
2578class Sort(Order):
2579    pass
key = 'sort'
class Ordered(Expression):
2582class Ordered(Expression):
2583    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):
2586class Property(Expression):
2587    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2590class GrantPrivilege(Expression):
2591    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2594class GrantPrincipal(Expression):
2595    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2598class AllowedValuesProperty(Expression):
2599    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2602class AlgorithmProperty(Property):
2603    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2606class AutoIncrementProperty(Property):
2607    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2611class AutoRefreshProperty(Property):
2612    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2615class BackupProperty(Property):
2616    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2619class BlockCompressionProperty(Property):
2620    arg_types = {
2621        "autotemp": False,
2622        "always": False,
2623        "default": False,
2624        "manual": False,
2625        "never": False,
2626    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2629class CharacterSetProperty(Property):
2630    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2633class ChecksumProperty(Property):
2634    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2637class CollateProperty(Property):
2638    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2641class CopyGrantsProperty(Property):
2642    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2645class DataBlocksizeProperty(Property):
2646    arg_types = {
2647        "size": False,
2648        "units": False,
2649        "minimum": False,
2650        "maximum": False,
2651        "default": False,
2652    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2655class DataDeletionProperty(Property):
2656    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):
2659class DefinerProperty(Property):
2660    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2663class DistKeyProperty(Property):
2664    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2669class DistributedByProperty(Property):
2670    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):
2673class DistStyleProperty(Property):
2674    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2677class DuplicateKeyProperty(Property):
2678    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2681class EngineProperty(Property):
2682    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2685class HeapProperty(Property):
2686    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2689class ToTableProperty(Property):
2690    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2693class ExecuteAsProperty(Property):
2694    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2697class ExternalProperty(Property):
2698    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2701class FallbackProperty(Property):
2702    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2705class FileFormatProperty(Property):
2706    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2709class FreespaceProperty(Property):
2710    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2713class GlobalProperty(Property):
2714    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2717class IcebergProperty(Property):
2718    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2721class InheritsProperty(Property):
2722    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2725class InputModelProperty(Property):
2726    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2729class OutputModelProperty(Property):
2730    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2733class IsolatedLoadingProperty(Property):
2734    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2737class JournalProperty(Property):
2738    arg_types = {
2739        "no": False,
2740        "dual": False,
2741        "before": False,
2742        "local": False,
2743        "after": False,
2744    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2747class LanguageProperty(Property):
2748    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2752class ClusteredByProperty(Property):
2753    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2756class DictProperty(Property):
2757    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2760class DictSubProperty(Property):
2761    pass
key = 'dictsubproperty'
class DictRange(Property):
2764class DictRange(Property):
2765    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2768class DynamicProperty(Property):
2769    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2774class OnCluster(Property):
2775    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2779class EmptyProperty(Property):
2780    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2783class LikeProperty(Property):
2784    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2787class LocationProperty(Property):
2788    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2791class LockProperty(Property):
2792    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2795class LockingProperty(Property):
2796    arg_types = {
2797        "this": False,
2798        "kind": True,
2799        "for_or_in": False,
2800        "lock_type": True,
2801        "override": False,
2802    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2805class LogProperty(Property):
2806    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2809class MaterializedProperty(Property):
2810    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2813class MergeBlockRatioProperty(Property):
2814    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):
2817class NoPrimaryIndexProperty(Property):
2818    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2821class OnProperty(Property):
2822    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2825class OnCommitProperty(Property):
2826    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2829class PartitionedByProperty(Property):
2830    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionBoundSpec(Expression):
2834class PartitionBoundSpec(Expression):
2835    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2836    arg_types = {
2837        "this": False,
2838        "expression": False,
2839        "from_expressions": False,
2840        "to_expressions": False,
2841    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2844class PartitionedOfProperty(Property):
2845    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2846    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2849class StreamingTableProperty(Property):
2850    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2853class RemoteWithConnectionModelProperty(Property):
2854    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2857class ReturnsProperty(Property):
2858    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):
2861class StrictProperty(Property):
2862    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2865class RowFormatProperty(Property):
2866    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2869class RowFormatDelimitedProperty(Property):
2870    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2871    arg_types = {
2872        "fields": False,
2873        "escaped": False,
2874        "collection_items": False,
2875        "map_keys": False,
2876        "lines": False,
2877        "null": False,
2878        "serde": False,
2879    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2882class RowFormatSerdeProperty(Property):
2883    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2887class QueryTransform(Expression):
2888    arg_types = {
2889        "expressions": True,
2890        "command_script": True,
2891        "schema": False,
2892        "row_format_before": False,
2893        "record_writer": False,
2894        "row_format_after": False,
2895        "record_reader": False,
2896    }
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):
2899class SampleProperty(Property):
2900    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2904class SecurityProperty(Property):
2905    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2908class SchemaCommentProperty(Property):
2909    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2912class SerdeProperties(Property):
2913    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2916class SetProperty(Property):
2917    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2920class SharingProperty(Property):
2921    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2924class SetConfigProperty(Property):
2925    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2928class SettingsProperty(Property):
2929    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2932class SortKeyProperty(Property):
2933    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2936class SqlReadWriteProperty(Property):
2937    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2940class SqlSecurityProperty(Property):
2941    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2944class StabilityProperty(Property):
2945    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2948class TemporaryProperty(Property):
2949    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
2952class SecureProperty(Property):
2953    arg_types = {}
arg_types = {}
key = 'secureproperty'
class TransformModelProperty(Property):
2956class TransformModelProperty(Property):
2957    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
2960class TransientProperty(Property):
2961    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
2964class UnloggedProperty(Property):
2965    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
2969class ViewAttributeProperty(Property):
2970    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
2973class VolatileProperty(Property):
2974    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
2977class WithDataProperty(Property):
2978    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
2981class WithJournalTableProperty(Property):
2982    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
2985class WithSchemaBindingProperty(Property):
2986    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
2989class WithSystemVersioningProperty(Property):
2990    arg_types = {
2991        "on": False,
2992        "this": False,
2993        "data_consistency": False,
2994        "retention_period": False,
2995        "with": True,
2996    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class Properties(Expression):
2999class Properties(Expression):
3000    arg_types = {"expressions": True}
3001
3002    NAME_TO_PROPERTY = {
3003        "ALGORITHM": AlgorithmProperty,
3004        "AUTO_INCREMENT": AutoIncrementProperty,
3005        "CHARACTER SET": CharacterSetProperty,
3006        "CLUSTERED_BY": ClusteredByProperty,
3007        "COLLATE": CollateProperty,
3008        "COMMENT": SchemaCommentProperty,
3009        "DEFINER": DefinerProperty,
3010        "DISTKEY": DistKeyProperty,
3011        "DISTRIBUTED_BY": DistributedByProperty,
3012        "DISTSTYLE": DistStyleProperty,
3013        "ENGINE": EngineProperty,
3014        "EXECUTE AS": ExecuteAsProperty,
3015        "FORMAT": FileFormatProperty,
3016        "LANGUAGE": LanguageProperty,
3017        "LOCATION": LocationProperty,
3018        "LOCK": LockProperty,
3019        "PARTITIONED_BY": PartitionedByProperty,
3020        "RETURNS": ReturnsProperty,
3021        "ROW_FORMAT": RowFormatProperty,
3022        "SORTKEY": SortKeyProperty,
3023    }
3024
3025    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3026
3027    # CREATE property locations
3028    # Form: schema specified
3029    #   create [POST_CREATE]
3030    #     table a [POST_NAME]
3031    #     (b int) [POST_SCHEMA]
3032    #     with ([POST_WITH])
3033    #     index (b) [POST_INDEX]
3034    #
3035    # Form: alias selection
3036    #   create [POST_CREATE]
3037    #     table a [POST_NAME]
3038    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3039    #     index (c) [POST_INDEX]
3040    class Location(AutoName):
3041        POST_CREATE = auto()
3042        POST_NAME = auto()
3043        POST_SCHEMA = auto()
3044        POST_WITH = auto()
3045        POST_ALIAS = auto()
3046        POST_EXPRESSION = auto()
3047        POST_INDEX = auto()
3048        UNSUPPORTED = auto()
3049
3050    @classmethod
3051    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3052        expressions = []
3053        for key, value in properties_dict.items():
3054            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3055            if property_cls:
3056                expressions.append(property_cls(this=convert(value)))
3057            else:
3058                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3059
3060        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:
3050    @classmethod
3051    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3052        expressions = []
3053        for key, value in properties_dict.items():
3054            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3055            if property_cls:
3056                expressions.append(property_cls(this=convert(value)))
3057            else:
3058                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3059
3060        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3040    class Location(AutoName):
3041        POST_CREATE = auto()
3042        POST_NAME = auto()
3043        POST_SCHEMA = auto()
3044        POST_WITH = auto()
3045        POST_ALIAS = auto()
3046        POST_EXPRESSION = auto()
3047        POST_INDEX = auto()
3048        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):
3063class Qualify(Expression):
3064    pass
key = 'qualify'
class InputOutputFormat(Expression):
3067class InputOutputFormat(Expression):
3068    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3072class Return(Expression):
3073    pass
key = 'return'
class Reference(Expression):
3076class Reference(Expression):
3077    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3080class Tuple(Expression):
3081    arg_types = {"expressions": False}
3082
3083    def isin(
3084        self,
3085        *expressions: t.Any,
3086        query: t.Optional[ExpOrStr] = None,
3087        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3088        copy: bool = True,
3089        **opts,
3090    ) -> In:
3091        return In(
3092            this=maybe_copy(self, copy),
3093            expressions=[convert(e, copy=copy) for e in expressions],
3094            query=maybe_parse(query, copy=copy, **opts) if query else None,
3095            unnest=(
3096                Unnest(
3097                    expressions=[
3098                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3099                        for e in ensure_list(unnest)
3100                    ]
3101                )
3102                if unnest
3103                else None
3104            ),
3105        )
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:
3083    def isin(
3084        self,
3085        *expressions: t.Any,
3086        query: t.Optional[ExpOrStr] = None,
3087        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3088        copy: bool = True,
3089        **opts,
3090    ) -> In:
3091        return In(
3092            this=maybe_copy(self, copy),
3093            expressions=[convert(e, copy=copy) for e in expressions],
3094            query=maybe_parse(query, copy=copy, **opts) if query else None,
3095            unnest=(
3096                Unnest(
3097                    expressions=[
3098                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3099                        for e in ensure_list(unnest)
3100                    ]
3101                )
3102                if unnest
3103                else None
3104            ),
3105        )
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):
3136class QueryOption(Expression):
3137    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3141class WithTableHint(Expression):
3142    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3146class IndexTableHint(Expression):
3147    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3151class HistoricalData(Expression):
3152    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3155class Table(Expression):
3156    arg_types = {
3157        "this": False,
3158        "alias": False,
3159        "db": False,
3160        "catalog": False,
3161        "laterals": False,
3162        "joins": False,
3163        "pivots": False,
3164        "hints": False,
3165        "system_time": False,
3166        "version": False,
3167        "format": False,
3168        "pattern": False,
3169        "ordinality": False,
3170        "when": False,
3171        "only": False,
3172        "partition": False,
3173        "changes": False,
3174        "rows_from": False,
3175        "sample": False,
3176    }
3177
3178    @property
3179    def name(self) -> str:
3180        if isinstance(self.this, Func):
3181            return ""
3182        return self.this.name
3183
3184    @property
3185    def db(self) -> str:
3186        return self.text("db")
3187
3188    @property
3189    def catalog(self) -> str:
3190        return self.text("catalog")
3191
3192    @property
3193    def selects(self) -> t.List[Expression]:
3194        return []
3195
3196    @property
3197    def named_selects(self) -> t.List[str]:
3198        return []
3199
3200    @property
3201    def parts(self) -> t.List[Expression]:
3202        """Return the parts of a table in order catalog, db, table."""
3203        parts: t.List[Expression] = []
3204
3205        for arg in ("catalog", "db", "this"):
3206            part = self.args.get(arg)
3207
3208            if isinstance(part, Dot):
3209                parts.extend(part.flatten())
3210            elif isinstance(part, Expression):
3211                parts.append(part)
3212
3213        return parts
3214
3215    def to_column(self, copy: bool = True) -> Alias | Column | Dot:
3216        parts = self.parts
3217        col = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3218        alias = self.args.get("alias")
3219        if alias:
3220            col = alias_(col, alias.this, copy=copy)
3221        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
3178    @property
3179    def name(self) -> str:
3180        if isinstance(self.this, Func):
3181            return ""
3182        return self.this.name
db: str
3184    @property
3185    def db(self) -> str:
3186        return self.text("db")
catalog: str
3188    @property
3189    def catalog(self) -> str:
3190        return self.text("catalog")
selects: List[Expression]
3192    @property
3193    def selects(self) -> t.List[Expression]:
3194        return []
named_selects: List[str]
3196    @property
3197    def named_selects(self) -> t.List[str]:
3198        return []
parts: List[Expression]
3200    @property
3201    def parts(self) -> t.List[Expression]:
3202        """Return the parts of a table in order catalog, db, table."""
3203        parts: t.List[Expression] = []
3204
3205        for arg in ("catalog", "db", "this"):
3206            part = self.args.get(arg)
3207
3208            if isinstance(part, Dot):
3209                parts.extend(part.flatten())
3210            elif isinstance(part, Expression):
3211                parts.append(part)
3212
3213        return parts

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

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

Returns the output names of the query's projections.

is_star: bool
3253    @property
3254    def is_star(self) -> bool:
3255        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3257    @property
3258    def selects(self) -> t.List[Expression]:
3259        return self.this.unnest().selects

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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

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

Checks whether an expression is a star.

selects: List[Expression]
3885    @property
3886    def selects(self) -> t.List[Expression]:
3887        return self.expressions

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
3972class Pivot(Expression):
3973    arg_types = {
3974        "this": False,
3975        "alias": False,
3976        "expressions": False,
3977        "field": False,
3978        "unpivot": False,
3979        "using": False,
3980        "group": False,
3981        "columns": False,
3982        "include_nulls": False,
3983        "default_on_null": False,
3984    }
3985
3986    @property
3987    def unpivot(self) -> bool:
3988        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
3986    @property
3987    def unpivot(self) -> bool:
3988        return bool(self.args.get("unpivot"))
key = 'pivot'
class Window(Condition):
3991class Window(Condition):
3992    arg_types = {
3993        "this": True,
3994        "partition_by": False,
3995        "order": False,
3996        "spec": False,
3997        "alias": False,
3998        "over": False,
3999        "first": False,
4000    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4003class WindowSpec(Expression):
4004    arg_types = {
4005        "kind": False,
4006        "start": False,
4007        "start_side": False,
4008        "end": False,
4009        "end_side": False,
4010    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4013class PreWhere(Expression):
4014    pass
key = 'prewhere'
class Where(Expression):
4017class Where(Expression):
4018    pass
key = 'where'
class Star(Expression):
4021class Star(Expression):
4022    arg_types = {"except": False, "replace": False, "rename": False}
4023
4024    @property
4025    def name(self) -> str:
4026        return "*"
4027
4028    @property
4029    def output_name(self) -> str:
4030        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4024    @property
4025    def name(self) -> str:
4026        return "*"
output_name: str
4028    @property
4029    def output_name(self) -> str:
4030        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):
4033class Parameter(Condition):
4034    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4037class SessionParameter(Condition):
4038    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4041class Placeholder(Condition):
4042    arg_types = {"this": False, "kind": False}
4043
4044    @property
4045    def name(self) -> str:
4046        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4044    @property
4045    def name(self) -> str:
4046        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4049class Null(Condition):
4050    arg_types: t.Dict[str, t.Any] = {}
4051
4052    @property
4053    def name(self) -> str:
4054        return "NULL"
4055
4056    def to_py(self) -> Lit[None]:
4057        return None
arg_types: Dict[str, Any] = {}
name: str
4052    @property
4053    def name(self) -> str:
4054        return "NULL"
def to_py(self) -> Literal[None]:
4056    def to_py(self) -> Lit[None]:
4057        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4060class Boolean(Condition):
4061    def to_py(self) -> bool:
4062        return self.this
def to_py(self) -> bool:
4061    def to_py(self) -> bool:
4062        return self.this

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

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

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

key = 'dot'
class DPipe(Binary):
4545class DPipe(Binary):
4546    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4549class EQ(Binary, Predicate):
4550    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4553class NullSafeEQ(Binary, Predicate):
4554    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4557class NullSafeNEQ(Binary, Predicate):
4558    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4562class PropertyEQ(Binary):
4563    pass
key = 'propertyeq'
class Distance(Binary):
4566class Distance(Binary):
4567    pass
key = 'distance'
class Escape(Binary):
4570class Escape(Binary):
4571    pass
key = 'escape'
class Glob(Binary, Predicate):
4574class Glob(Binary, Predicate):
4575    pass
key = 'glob'
class GT(Binary, Predicate):
4578class GT(Binary, Predicate):
4579    pass
key = 'gt'
class GTE(Binary, Predicate):
4582class GTE(Binary, Predicate):
4583    pass
key = 'gte'
class ILike(Binary, Predicate):
4586class ILike(Binary, Predicate):
4587    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4590class ILikeAny(Binary, Predicate):
4591    pass
key = 'ilikeany'
class IntDiv(Binary):
4594class IntDiv(Binary):
4595    pass
key = 'intdiv'
class Is(Binary, Predicate):
4598class Is(Binary, Predicate):
4599    pass
key = 'is'
class Kwarg(Binary):
4602class Kwarg(Binary):
4603    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4606class Like(Binary, Predicate):
4607    pass
key = 'like'
class LikeAny(Binary, Predicate):
4610class LikeAny(Binary, Predicate):
4611    pass
key = 'likeany'
class LT(Binary, Predicate):
4614class LT(Binary, Predicate):
4615    pass
key = 'lt'
class LTE(Binary, Predicate):
4618class LTE(Binary, Predicate):
4619    pass
key = 'lte'
class Mod(Binary):
4622class Mod(Binary):
4623    pass
key = 'mod'
class Mul(Binary):
4626class Mul(Binary):
4627    pass
key = 'mul'
class NEQ(Binary, Predicate):
4630class NEQ(Binary, Predicate):
4631    pass
key = 'neq'
class Operator(Binary):
4635class Operator(Binary):
4636    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4639class SimilarTo(Binary, Predicate):
4640    pass
key = 'similarto'
class Slice(Binary):
4643class Slice(Binary):
4644    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
4647class Sub(Binary):
4648    pass
key = 'sub'
class Unary(Condition):
4653class Unary(Condition):
4654    pass
key = 'unary'
class BitwiseNot(Unary):
4657class BitwiseNot(Unary):
4658    pass
key = 'bitwisenot'
class Not(Unary):
4661class Not(Unary):
4662    pass
key = 'not'
class Paren(Unary):
4665class Paren(Unary):
4666    @property
4667    def output_name(self) -> str:
4668        return self.this.name
output_name: str
4666    @property
4667    def output_name(self) -> str:
4668        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):
4671class Neg(Unary):
4672    def to_py(self) -> int | Decimal:
4673        if self.is_number:
4674            return self.this.to_py() * -1
4675        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
4672    def to_py(self) -> int | Decimal:
4673        if self.is_number:
4674            return self.this.to_py() * -1
4675        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
4678class Alias(Expression):
4679    arg_types = {"this": True, "alias": False}
4680
4681    @property
4682    def output_name(self) -> str:
4683        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
4681    @property
4682    def output_name(self) -> str:
4683        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):
4688class PivotAlias(Alias):
4689    pass
key = 'pivotalias'
class PivotAny(Expression):
4694class PivotAny(Expression):
4695    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
4698class Aliases(Expression):
4699    arg_types = {"this": True, "expressions": True}
4700
4701    @property
4702    def aliases(self):
4703        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
4701    @property
4702    def aliases(self):
4703        return self.expressions
key = 'aliases'
class AtIndex(Expression):
4707class AtIndex(Expression):
4708    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
4711class AtTimeZone(Expression):
4712    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
4715class FromTimeZone(Expression):
4716    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
4719class Between(Predicate):
4720    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
4723class Bracket(Condition):
4724    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
4725    arg_types = {
4726        "this": True,
4727        "expressions": True,
4728        "offset": False,
4729        "safe": False,
4730        "returns_list_for_maps": False,
4731    }
4732
4733    @property
4734    def output_name(self) -> str:
4735        if len(self.expressions) == 1:
4736            return self.expressions[0].output_name
4737
4738        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
4733    @property
4734    def output_name(self) -> str:
4735        if len(self.expressions) == 1:
4736            return self.expressions[0].output_name
4737
4738        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):
4741class Distinct(Expression):
4742    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
4745class In(Predicate):
4746    arg_types = {
4747        "this": True,
4748        "expressions": False,
4749        "query": False,
4750        "unnest": False,
4751        "field": False,
4752        "is_global": False,
4753    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
4757class ForIn(Expression):
4758    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
4761class TimeUnit(Expression):
4762    """Automatically converts unit arg into a var."""
4763
4764    arg_types = {"unit": False}
4765
4766    UNABBREVIATED_UNIT_NAME = {
4767        "D": "DAY",
4768        "H": "HOUR",
4769        "M": "MINUTE",
4770        "MS": "MILLISECOND",
4771        "NS": "NANOSECOND",
4772        "Q": "QUARTER",
4773        "S": "SECOND",
4774        "US": "MICROSECOND",
4775        "W": "WEEK",
4776        "Y": "YEAR",
4777    }
4778
4779    VAR_LIKE = (Column, Literal, Var)
4780
4781    def __init__(self, **args):
4782        unit = args.get("unit")
4783        if isinstance(unit, self.VAR_LIKE):
4784            args["unit"] = Var(
4785                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4786            )
4787        elif isinstance(unit, Week):
4788            unit.set("this", Var(this=unit.this.name.upper()))
4789
4790        super().__init__(**args)
4791
4792    @property
4793    def unit(self) -> t.Optional[Var | IntervalSpan]:
4794        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
4781    def __init__(self, **args):
4782        unit = args.get("unit")
4783        if isinstance(unit, self.VAR_LIKE):
4784            args["unit"] = Var(
4785                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
4786            )
4787        elif isinstance(unit, Week):
4788            unit.set("this", Var(this=unit.this.name.upper()))
4789
4790        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]
4792    @property
4793    def unit(self) -> t.Optional[Var | IntervalSpan]:
4794        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
4797class IntervalOp(TimeUnit):
4798    arg_types = {"unit": False, "expression": True}
4799
4800    def interval(self):
4801        return Interval(
4802            this=self.expression.copy(),
4803            unit=self.unit.copy() if self.unit else None,
4804        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
4800    def interval(self):
4801        return Interval(
4802            this=self.expression.copy(),
4803            unit=self.unit.copy() if self.unit else None,
4804        )
key = 'intervalop'
class IntervalSpan(DataType):
4810class IntervalSpan(DataType):
4811    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
4814class Interval(TimeUnit):
4815    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
4818class IgnoreNulls(Expression):
4819    pass
key = 'ignorenulls'
class RespectNulls(Expression):
4822class RespectNulls(Expression):
4823    pass
key = 'respectnulls'
class HavingMax(Expression):
4827class HavingMax(Expression):
4828    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
4832class Func(Condition):
4833    """
4834    The base class for all function expressions.
4835
4836    Attributes:
4837        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
4838            treated as a variable length argument and the argument's value will be stored as a list.
4839        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
4840            function expression. These values are used to map this node to a name during parsing as
4841            well as to provide the function's name during SQL string generation. By default the SQL
4842            name is set to the expression's class name transformed to snake case.
4843    """
4844
4845    is_var_len_args = False
4846
4847    @classmethod
4848    def from_arg_list(cls, args):
4849        if cls.is_var_len_args:
4850            all_arg_keys = list(cls.arg_types)
4851            # If this function supports variable length argument treat the last argument as such.
4852            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4853            num_non_var = len(non_var_len_arg_keys)
4854
4855            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4856            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4857        else:
4858            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4859
4860        return cls(**args_dict)
4861
4862    @classmethod
4863    def sql_names(cls):
4864        if cls is Func:
4865            raise NotImplementedError(
4866                "SQL name is only supported by concrete function implementations"
4867            )
4868        if "_sql_names" not in cls.__dict__:
4869            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4870        return cls._sql_names
4871
4872    @classmethod
4873    def sql_name(cls):
4874        return cls.sql_names()[0]
4875
4876    @classmethod
4877    def default_parser_mappings(cls):
4878        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):
4847    @classmethod
4848    def from_arg_list(cls, args):
4849        if cls.is_var_len_args:
4850            all_arg_keys = list(cls.arg_types)
4851            # If this function supports variable length argument treat the last argument as such.
4852            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
4853            num_non_var = len(non_var_len_arg_keys)
4854
4855            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
4856            args_dict[all_arg_keys[-1]] = args[num_non_var:]
4857        else:
4858            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
4859
4860        return cls(**args_dict)
@classmethod
def sql_names(cls):
4862    @classmethod
4863    def sql_names(cls):
4864        if cls is Func:
4865            raise NotImplementedError(
4866                "SQL name is only supported by concrete function implementations"
4867            )
4868        if "_sql_names" not in cls.__dict__:
4869            cls._sql_names = [camel_to_snake_case(cls.__name__)]
4870        return cls._sql_names
@classmethod
def sql_name(cls):
4872    @classmethod
4873    def sql_name(cls):
4874        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
4876    @classmethod
4877    def default_parser_mappings(cls):
4878        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
4881class AggFunc(Func):
4882    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
4885class ParameterizedAgg(AggFunc):
4886    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
4889class Abs(Func):
4890    pass
key = 'abs'
class ArgMax(AggFunc):
4893class ArgMax(AggFunc):
4894    arg_types = {"this": True, "expression": True, "count": False}
4895    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
4898class ArgMin(AggFunc):
4899    arg_types = {"this": True, "expression": True, "count": False}
4900    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
4903class ApproxTopK(AggFunc):
4904    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
4907class Flatten(Func):
4908    pass
key = 'flatten'
class Transform(Func):
4912class Transform(Func):
4913    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
4916class Anonymous(Func):
4917    arg_types = {"this": True, "expressions": False}
4918    is_var_len_args = True
4919
4920    @property
4921    def name(self) -> str:
4922        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
4920    @property
4921    def name(self) -> str:
4922        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
4925class AnonymousAggFunc(AggFunc):
4926    arg_types = {"this": True, "expressions": False}
4927    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
4931class CombinedAggFunc(AnonymousAggFunc):
4932    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
4935class CombinedParameterizedAgg(ParameterizedAgg):
4936    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):
4941class Hll(AggFunc):
4942    arg_types = {"this": True, "expressions": False}
4943    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
4946class ApproxDistinct(AggFunc):
4947    arg_types = {"this": True, "accuracy": False}
4948    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
4951class Apply(Func):
4952    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
4955class Array(Func):
4956    arg_types = {"expressions": False, "bracket_notation": False}
4957    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
4961class ToArray(Func):
4962    pass
key = 'toarray'
class List(Func):
4966class List(Func):
4967    arg_types = {"expressions": False}
4968    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
4972class Pad(Func):
4973    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):
4978class ToChar(Func):
4979    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
4984class ToNumber(Func):
4985    arg_types = {
4986        "this": True,
4987        "format": False,
4988        "nlsparam": False,
4989        "precision": False,
4990        "scale": False,
4991    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class Columns(Func):
4994class Columns(Func):
4995    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
4999class Convert(Func):
5000    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5003class ConvertTimezone(Func):
5004    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):
5007class GenerateSeries(Func):
5008    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):
5014class ExplodingGenerateSeries(GenerateSeries):
5015    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5018class ArrayAgg(AggFunc):
5019    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5022class ArrayUniqueAgg(AggFunc):
5023    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5026class ArrayAll(Func):
5027    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5031class ArrayAny(Func):
5032    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5035class ArrayConcat(Func):
5036    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5037    arg_types = {"this": True, "expressions": False}
5038    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5041class ArrayConstructCompact(Func):
5042    arg_types = {"expressions": True}
5043    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5046class ArrayContains(Binary, Func):
5047    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5050class ArrayContainsAll(Binary, Func):
5051    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5054class ArrayFilter(Func):
5055    arg_types = {"this": True, "expression": True}
5056    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5059class ArrayToString(Func):
5060    arg_types = {"this": True, "expression": True, "null": False}
5061    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class StringToArray(Func):
5064class StringToArray(Func):
5065    arg_types = {"this": True, "expression": True, "null": False}
5066    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5069class ArrayOverlaps(Binary, Func):
5070    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5073class ArraySize(Func):
5074    arg_types = {"this": True, "expression": False}
5075    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5078class ArraySort(Func):
5079    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5082class ArraySum(Func):
5083    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5086class ArrayUnionAgg(AggFunc):
5087    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5090class Avg(AggFunc):
5091    pass
key = 'avg'
class AnyValue(AggFunc):
5094class AnyValue(AggFunc):
5095    pass
key = 'anyvalue'
class Lag(AggFunc):
5098class Lag(AggFunc):
5099    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5102class Lead(AggFunc):
5103    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5108class First(AggFunc):
5109    pass
key = 'first'
class Last(AggFunc):
5112class Last(AggFunc):
5113    pass
key = 'last'
class FirstValue(AggFunc):
5116class FirstValue(AggFunc):
5117    pass
key = 'firstvalue'
class LastValue(AggFunc):
5120class LastValue(AggFunc):
5121    pass
key = 'lastvalue'
class NthValue(AggFunc):
5124class NthValue(AggFunc):
5125    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5128class Case(Func):
5129    arg_types = {"this": False, "ifs": True, "default": False}
5130
5131    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5132        instance = maybe_copy(self, copy)
5133        instance.append(
5134            "ifs",
5135            If(
5136                this=maybe_parse(condition, copy=copy, **opts),
5137                true=maybe_parse(then, copy=copy, **opts),
5138            ),
5139        )
5140        return instance
5141
5142    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5143        instance = maybe_copy(self, copy)
5144        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5145        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:
5131    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5132        instance = maybe_copy(self, copy)
5133        instance.append(
5134            "ifs",
5135            If(
5136                this=maybe_parse(condition, copy=copy, **opts),
5137                true=maybe_parse(then, copy=copy, **opts),
5138            ),
5139        )
5140        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5142    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5143        instance = maybe_copy(self, copy)
5144        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5145        return instance
key = 'case'
class Cast(Func):
5148class Cast(Func):
5149    arg_types = {
5150        "this": True,
5151        "to": True,
5152        "format": False,
5153        "safe": False,
5154        "action": False,
5155    }
5156
5157    @property
5158    def name(self) -> str:
5159        return self.this.name
5160
5161    @property
5162    def to(self) -> DataType:
5163        return self.args["to"]
5164
5165    @property
5166    def output_name(self) -> str:
5167        return self.name
5168
5169    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5170        """
5171        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5172        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5173        array<int> != array<float>.
5174
5175        Args:
5176            dtypes: the data types to compare this Cast's DataType to.
5177
5178        Returns:
5179            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5180        """
5181        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5157    @property
5158    def name(self) -> str:
5159        return self.this.name
to: DataType
5161    @property
5162    def to(self) -> DataType:
5163        return self.args["to"]
output_name: str
5165    @property
5166    def output_name(self) -> str:
5167        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:
5169    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5170        """
5171        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5172        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5173        array<int> != array<float>.
5174
5175        Args:
5176            dtypes: the data types to compare this Cast's DataType to.
5177
5178        Returns:
5179            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5180        """
5181        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):
5184class TryCast(Cast):
5185    pass
key = 'trycast'
class Try(Func):
5188class Try(Func):
5189    pass
key = 'try'
class CastToStrType(Func):
5192class CastToStrType(Func):
5193    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5196class Collate(Binary, Func):
5197    pass
key = 'collate'
class Ceil(Func):
5200class Ceil(Func):
5201    arg_types = {"this": True, "decimals": False}
5202    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False}
key = 'ceil'
class Coalesce(Func):
5205class Coalesce(Func):
5206    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5207    is_var_len_args = True
5208    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5211class Chr(Func):
5212    arg_types = {"expressions": True, "charset": False}
5213    is_var_len_args = True
5214    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5217class Concat(Func):
5218    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5219    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5222class ConcatWs(Concat):
5223    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class ConnectByRoot(Func):
5227class ConnectByRoot(Func):
5228    pass
key = 'connectbyroot'
class Count(AggFunc):
5231class Count(AggFunc):
5232    arg_types = {"this": False, "expressions": False, "big_int": False}
5233    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5236class CountIf(AggFunc):
5237    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5241class Cbrt(Func):
5242    pass
key = 'cbrt'
class CurrentDate(Func):
5245class CurrentDate(Func):
5246    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5249class CurrentDatetime(Func):
5250    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5253class CurrentTime(Func):
5254    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5257class CurrentTimestamp(Func):
5258    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5261class CurrentUser(Func):
5262    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5265class DateAdd(Func, IntervalOp):
5266    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5269class DateSub(Func, IntervalOp):
5270    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5273class DateDiff(Func, TimeUnit):
5274    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5275    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5278class DateTrunc(Func):
5279    arg_types = {"unit": True, "this": True, "zone": False}
5280
5281    def __init__(self, **args):
5282        unit = args.get("unit")
5283        if isinstance(unit, TimeUnit.VAR_LIKE):
5284            args["unit"] = Literal.string(
5285                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5286            )
5287        elif isinstance(unit, Week):
5288            unit.set("this", Literal.string(unit.this.name.upper()))
5289
5290        super().__init__(**args)
5291
5292    @property
5293    def unit(self) -> Expression:
5294        return self.args["unit"]
DateTrunc(**args)
5281    def __init__(self, **args):
5282        unit = args.get("unit")
5283        if isinstance(unit, TimeUnit.VAR_LIKE):
5284            args["unit"] = Literal.string(
5285                (TimeUnit.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5286            )
5287        elif isinstance(unit, Week):
5288            unit.set("this", Literal.string(unit.this.name.upper()))
5289
5290        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5292    @property
5293    def unit(self) -> Expression:
5294        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5299class Datetime(Func):
5300    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5303class DatetimeAdd(Func, IntervalOp):
5304    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5307class DatetimeSub(Func, IntervalOp):
5308    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5311class DatetimeDiff(Func, TimeUnit):
5312    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5315class DatetimeTrunc(Func, TimeUnit):
5316    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5319class DayOfWeek(Func):
5320    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5325class DayOfWeekIso(Func):
5326    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5329class DayOfMonth(Func):
5330    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5333class DayOfYear(Func):
5334    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5337class ToDays(Func):
5338    pass
key = 'todays'
class WeekOfYear(Func):
5341class WeekOfYear(Func):
5342    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5345class MonthsBetween(Func):
5346    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class LastDay(Func, TimeUnit):
5349class LastDay(Func, TimeUnit):
5350    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5351    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5354class Extract(Func):
5355    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Timestamp(Func):
5358class Timestamp(Func):
5359    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5362class TimestampAdd(Func, TimeUnit):
5363    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5366class TimestampSub(Func, TimeUnit):
5367    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5370class TimestampDiff(Func, TimeUnit):
5371    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5372    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5375class TimestampTrunc(Func, TimeUnit):
5376    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5379class TimeAdd(Func, TimeUnit):
5380    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5383class TimeSub(Func, TimeUnit):
5384    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5387class TimeDiff(Func, TimeUnit):
5388    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5391class TimeTrunc(Func, TimeUnit):
5392    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5395class DateFromParts(Func):
5396    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5397    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5400class TimeFromParts(Func):
5401    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5402    arg_types = {
5403        "hour": True,
5404        "min": True,
5405        "sec": True,
5406        "nano": False,
5407        "fractions": False,
5408        "precision": False,
5409    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5412class DateStrToDate(Func):
5413    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5416class DateToDateStr(Func):
5417    pass
key = 'datetodatestr'
class DateToDi(Func):
5420class DateToDi(Func):
5421    pass
key = 'datetodi'
class Date(Func):
5425class Date(Func):
5426    arg_types = {"this": False, "zone": False, "expressions": False}
5427    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5430class Day(Func):
5431    pass
key = 'day'
class Decode(Func):
5434class Decode(Func):
5435    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5438class DiToDate(Func):
5439    pass
key = 'ditodate'
class Encode(Func):
5442class Encode(Func):
5443    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5446class Exp(Func):
5447    pass
key = 'exp'
class Explode(Func):
5451class Explode(Func):
5452    arg_types = {"this": True, "expressions": False}
5453    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5457class Inline(Func):
5458    pass
key = 'inline'
class ExplodeOuter(Explode):
5461class ExplodeOuter(Explode):
5462    pass
key = 'explodeouter'
class Posexplode(Explode):
5465class Posexplode(Explode):
5466    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5469class PosexplodeOuter(Posexplode, ExplodeOuter):
5470    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5473class Unnest(Func, UDTF):
5474    arg_types = {
5475        "expressions": True,
5476        "alias": False,
5477        "offset": False,
5478        "explode_array": False,
5479    }
5480
5481    @property
5482    def selects(self) -> t.List[Expression]:
5483        columns = super().selects
5484        offset = self.args.get("offset")
5485        if offset:
5486            columns = columns + [to_identifier("offset") if offset is True else offset]
5487        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5481    @property
5482    def selects(self) -> t.List[Expression]:
5483        columns = super().selects
5484        offset = self.args.get("offset")
5485        if offset:
5486            columns = columns + [to_identifier("offset") if offset is True else offset]
5487        return columns
key = 'unnest'
class Floor(Func):
5490class Floor(Func):
5491    arg_types = {"this": True, "decimals": False}
arg_types = {'this': True, 'decimals': False}
key = 'floor'
class FromBase64(Func):
5494class FromBase64(Func):
5495    pass
key = 'frombase64'
class ToBase64(Func):
5498class ToBase64(Func):
5499    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5503class FromISO8601Timestamp(Func):
5504    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5507class GapFill(Func):
5508    arg_types = {
5509        "this": True,
5510        "ts_column": True,
5511        "bucket_width": True,
5512        "partitioning_columns": False,
5513        "value_columns": False,
5514        "origin": False,
5515        "ignore_nulls": False,
5516    }
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):
5520class GenerateDateArray(Func):
5521    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5525class GenerateTimestampArray(Func):
5526    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5529class Greatest(Func):
5530    arg_types = {"this": True, "expressions": False}
5531    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class GroupConcat(AggFunc):
5534class GroupConcat(AggFunc):
5535    arg_types = {"this": True, "separator": False}
arg_types = {'this': True, 'separator': False}
key = 'groupconcat'
class Hex(Func):
5538class Hex(Func):
5539    pass
key = 'hex'
class LowerHex(Hex):
5542class LowerHex(Hex):
5543    pass
key = 'lowerhex'
class Xor(Connector, Func):
5546class Xor(Connector, Func):
5547    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5550class If(Func):
5551    arg_types = {"this": True, "true": True, "false": False}
5552    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5555class Nullif(Func):
5556    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5559class Initcap(Func):
5560    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsNan(Func):
5563class IsNan(Func):
5564    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class IsInf(Func):
5567class IsInf(Func):
5568    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5572class JSON(Expression):
5573    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5576class JSONPath(Expression):
5577    arg_types = {"expressions": True, "escape": False}
5578
5579    @property
5580    def output_name(self) -> str:
5581        last_segment = self.expressions[-1].this
5582        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5579    @property
5580    def output_name(self) -> str:
5581        last_segment = self.expressions[-1].this
5582        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):
5585class JSONPathPart(Expression):
5586    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
5589class JSONPathFilter(JSONPathPart):
5590    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
5593class JSONPathKey(JSONPathPart):
5594    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
5597class JSONPathRecursive(JSONPathPart):
5598    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
5601class JSONPathRoot(JSONPathPart):
5602    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
5605class JSONPathScript(JSONPathPart):
5606    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
5609class JSONPathSlice(JSONPathPart):
5610    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
5613class JSONPathSelector(JSONPathPart):
5614    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
5617class JSONPathSubscript(JSONPathPart):
5618    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
5621class JSONPathUnion(JSONPathPart):
5622    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
5625class JSONPathWildcard(JSONPathPart):
5626    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
5629class FormatJson(Expression):
5630    pass
key = 'formatjson'
class JSONKeyValue(Expression):
5633class JSONKeyValue(Expression):
5634    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
5637class JSONObject(Func):
5638    arg_types = {
5639        "expressions": False,
5640        "null_handling": False,
5641        "unique_keys": False,
5642        "return_type": False,
5643        "encoding": False,
5644    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
5647class JSONObjectAgg(AggFunc):
5648    arg_types = {
5649        "expressions": False,
5650        "null_handling": False,
5651        "unique_keys": False,
5652        "return_type": False,
5653        "encoding": False,
5654    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
5658class JSONArray(Func):
5659    arg_types = {
5660        "expressions": True,
5661        "null_handling": False,
5662        "return_type": False,
5663        "strict": False,
5664    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
5668class JSONArrayAgg(Func):
5669    arg_types = {
5670        "this": True,
5671        "order": False,
5672        "null_handling": False,
5673        "return_type": False,
5674        "strict": False,
5675    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
5678class JSONExists(Func):
5679    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):
5684class JSONColumnDef(Expression):
5685    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):
5688class JSONSchema(Expression):
5689    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
5693class JSONValue(Expression):
5694    arg_types = {
5695        "this": True,
5696        "path": True,
5697        "returning": False,
5698        "on_condition": False,
5699    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONTable(Func):
5703class JSONTable(Func):
5704    arg_types = {
5705        "this": True,
5706        "schema": True,
5707        "path": False,
5708        "error_handling": False,
5709        "empty_handling": False,
5710    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
5714class ObjectInsert(Func):
5715    arg_types = {
5716        "this": True,
5717        "key": True,
5718        "value": True,
5719        "update_flag": False,
5720    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
5723class OpenJSONColumnDef(Expression):
5724    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):
5727class OpenJSON(Func):
5728    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
5731class JSONBContains(Binary, Func):
5732    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONExtract(Binary, Func):
5735class JSONExtract(Binary, Func):
5736    arg_types = {
5737        "this": True,
5738        "expression": True,
5739        "only_json_types": False,
5740        "expressions": False,
5741        "variant_extract": False,
5742    }
5743    _sql_names = ["JSON_EXTRACT"]
5744    is_var_len_args = True
5745
5746    @property
5747    def output_name(self) -> str:
5748        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
5746    @property
5747    def output_name(self) -> str:
5748        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):
5751class JSONExtractScalar(Binary, Func):
5752    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
5753    _sql_names = ["JSON_EXTRACT_SCALAR"]
5754    is_var_len_args = True
5755
5756    @property
5757    def output_name(self) -> str:
5758        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
5756    @property
5757    def output_name(self) -> str:
5758        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):
5761class JSONBExtract(Binary, Func):
5762    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
5765class JSONBExtractScalar(Binary, Func):
5766    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
5769class JSONFormat(Func):
5770    arg_types = {"this": False, "options": False}
5771    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
5775class JSONArrayContains(Binary, Predicate, Func):
5776    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
5779class ParseJSON(Func):
5780    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
5781    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
5782    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
5783    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
5786class Least(Func):
5787    arg_types = {"this": True, "expressions": False}
5788    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
5791class Left(Func):
5792    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
5799class Length(Func):
5800    arg_types = {"this": True, "binary": False}
5801    _sql_names = ["LENGTH", "LEN"]
arg_types = {'this': True, 'binary': False}
key = 'length'
class Levenshtein(Func):
5804class Levenshtein(Func):
5805    arg_types = {
5806        "this": True,
5807        "expression": False,
5808        "ins_cost": False,
5809        "del_cost": False,
5810        "sub_cost": False,
5811    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False}
key = 'levenshtein'
class Ln(Func):
5814class Ln(Func):
5815    pass
key = 'ln'
class Log(Func):
5818class Log(Func):
5819    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
5822class LogicalOr(AggFunc):
5823    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
5826class LogicalAnd(AggFunc):
5827    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
5830class Lower(Func):
5831    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
5834class Map(Func):
5835    arg_types = {"keys": False, "values": False}
5836
5837    @property
5838    def keys(self) -> t.List[Expression]:
5839        keys = self.args.get("keys")
5840        return keys.expressions if keys else []
5841
5842    @property
5843    def values(self) -> t.List[Expression]:
5844        values = self.args.get("values")
5845        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
5837    @property
5838    def keys(self) -> t.List[Expression]:
5839        keys = self.args.get("keys")
5840        return keys.expressions if keys else []
values: List[Expression]
5842    @property
5843    def values(self) -> t.List[Expression]:
5844        values = self.args.get("values")
5845        return values.expressions if values else []
key = 'map'
class ToMap(Func):
5849class ToMap(Func):
5850    pass
key = 'tomap'
class MapFromEntries(Func):
5853class MapFromEntries(Func):
5854    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
5858class ScopeResolution(Expression):
5859    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
5862class Stream(Expression):
5863    pass
key = 'stream'
class StarMap(Func):
5866class StarMap(Func):
5867    pass
key = 'starmap'
class VarMap(Func):
5870class VarMap(Func):
5871    arg_types = {"keys": True, "values": True}
5872    is_var_len_args = True
5873
5874    @property
5875    def keys(self) -> t.List[Expression]:
5876        return self.args["keys"].expressions
5877
5878    @property
5879    def values(self) -> t.List[Expression]:
5880        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
5874    @property
5875    def keys(self) -> t.List[Expression]:
5876        return self.args["keys"].expressions
values: List[Expression]
5878    @property
5879    def values(self) -> t.List[Expression]:
5880        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
5884class MatchAgainst(Func):
5885    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
5888class Max(AggFunc):
5889    arg_types = {"this": True, "expressions": False}
5890    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
5893class MD5(Func):
5894    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
5898class MD5Digest(Func):
5899    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Min(AggFunc):
5902class Min(AggFunc):
5903    arg_types = {"this": True, "expressions": False}
5904    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
5907class Month(Func):
5908    pass
key = 'month'
class AddMonths(Func):
5911class AddMonths(Func):
5912    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
5915class Nvl2(Func):
5916    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
5919class Normalize(Func):
5920    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
5923class Overlay(Func):
5924    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):
5928class Predict(Func):
5929    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
5932class Pow(Binary, Func):
5933    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
5936class PercentileCont(AggFunc):
5937    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
5940class PercentileDisc(AggFunc):
5941    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
5944class Quantile(AggFunc):
5945    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
5948class ApproxQuantile(Quantile):
5949    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):
5952class Quarter(Func):
5953    pass
key = 'quarter'
class Rand(Func):
5958class Rand(Func):
5959    _sql_names = ["RAND", "RANDOM"]
5960    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
5963class Randn(Func):
5964    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
5967class RangeN(Func):
5968    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
5971class ReadCSV(Func):
5972    _sql_names = ["READ_CSV"]
5973    is_var_len_args = True
5974    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
5977class Reduce(Func):
5978    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):
5981class RegexpExtract(Func):
5982    arg_types = {
5983        "this": True,
5984        "expression": True,
5985        "position": False,
5986        "occurrence": False,
5987        "parameters": False,
5988        "group": False,
5989    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpReplace(Func):
5992class RegexpReplace(Func):
5993    arg_types = {
5994        "this": True,
5995        "expression": True,
5996        "replacement": False,
5997        "position": False,
5998        "occurrence": False,
5999        "modifiers": False,
6000    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6003class RegexpLike(Binary, Func):
6004    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6007class RegexpILike(Binary, Func):
6008    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6013class RegexpSplit(Func):
6014    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6017class Repeat(Func):
6018    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6023class Round(Func):
6024    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6027class RowNumber(Func):
6028    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'rownumber'
class SafeDivide(Func):
6031class SafeDivide(Func):
6032    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6035class SHA(Func):
6036    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6039class SHA2(Func):
6040    _sql_names = ["SHA2"]
6041    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6044class Sign(Func):
6045    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6048class SortArray(Func):
6049    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6052class Split(Func):
6053    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class Substring(Func):
6058class Substring(Func):
6059    _sql_names = ["SUBSTRING", "SUBSTR"]
6060    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6063class StandardHash(Func):
6064    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6067class StartsWith(Func):
6068    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6069    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6072class StrPosition(Func):
6073    arg_types = {
6074        "this": True,
6075        "substr": True,
6076        "position": False,
6077        "instance": False,
6078    }
arg_types = {'this': True, 'substr': True, 'position': False, 'instance': False}
key = 'strposition'
class StrToDate(Func):
6081class StrToDate(Func):
6082    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6085class StrToTime(Func):
6086    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):
6091class StrToUnix(Func):
6092    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6097class StrToMap(Func):
6098    arg_types = {
6099        "this": True,
6100        "pair_delim": False,
6101        "key_value_delim": False,
6102        "duplicate_resolution_callback": False,
6103    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6106class NumberToStr(Func):
6107    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6110class FromBase(Func):
6111    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6114class Struct(Func):
6115    arg_types = {"expressions": False}
6116    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6119class StructExtract(Func):
6120    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6125class Stuff(Func):
6126    _sql_names = ["STUFF", "INSERT"]
6127    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):
6130class Sum(AggFunc):
6131    pass
key = 'sum'
class Sqrt(Func):
6134class Sqrt(Func):
6135    pass
key = 'sqrt'
class Stddev(AggFunc):
6138class Stddev(AggFunc):
6139    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6142class StddevPop(AggFunc):
6143    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6146class StddevSamp(AggFunc):
6147    pass
key = 'stddevsamp'
class Time(Func):
6151class Time(Func):
6152    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6155class TimeToStr(Func):
6156    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):
6159class TimeToTimeStr(Func):
6160    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6163class TimeToUnix(Func):
6164    pass
key = 'timetounix'
class TimeStrToDate(Func):
6167class TimeStrToDate(Func):
6168    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6171class TimeStrToTime(Func):
6172    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6175class TimeStrToUnix(Func):
6176    pass
key = 'timestrtounix'
class Trim(Func):
6179class Trim(Func):
6180    arg_types = {
6181        "this": True,
6182        "expression": False,
6183        "position": False,
6184        "collation": False,
6185    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6188class TsOrDsAdd(Func, TimeUnit):
6189    # return_type is used to correctly cast the arguments of this expression when transpiling it
6190    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6191
6192    @property
6193    def return_type(self) -> DataType:
6194        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
6192    @property
6193    def return_type(self) -> DataType:
6194        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6197class TsOrDsDiff(Func, TimeUnit):
6198    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6201class TsOrDsToDateStr(Func):
6202    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6205class TsOrDsToDate(Func):
6206    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToTime(Func):
6209class TsOrDsToTime(Func):
6210    pass
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6213class TsOrDsToTimestamp(Func):
6214    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6217class TsOrDiToDi(Func):
6218    pass
key = 'tsorditodi'
class Unhex(Func):
6221class Unhex(Func):
6222    pass
key = 'unhex'
class UnixDate(Func):
6226class UnixDate(Func):
6227    pass
key = 'unixdate'
class UnixToStr(Func):
6230class UnixToStr(Func):
6231    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6236class UnixToTime(Func):
6237    arg_types = {
6238        "this": True,
6239        "scale": False,
6240        "zone": False,
6241        "hours": False,
6242        "minutes": False,
6243        "format": False,
6244    }
6245
6246    SECONDS = Literal.number(0)
6247    DECIS = Literal.number(1)
6248    CENTIS = Literal.number(2)
6249    MILLIS = Literal.number(3)
6250    DECIMILLIS = Literal.number(4)
6251    CENTIMILLIS = Literal.number(5)
6252    MICROS = Literal.number(6)
6253    DECIMICROS = Literal.number(7)
6254    CENTIMICROS = Literal.number(8)
6255    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):
6258class UnixToTimeStr(Func):
6259    pass
key = 'unixtotimestr'
class Uuid(Func):
6262class Uuid(Func):
6263    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6264
6265    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6268class TimestampFromParts(Func):
6269    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6270    arg_types = {
6271        "year": True,
6272        "month": True,
6273        "day": True,
6274        "hour": True,
6275        "min": True,
6276        "sec": True,
6277        "nano": False,
6278        "zone": False,
6279        "milli": False,
6280    }
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):
6283class Upper(Func):
6284    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6287class Corr(Binary, AggFunc):
6288    pass
key = 'corr'
class Variance(AggFunc):
6291class Variance(AggFunc):
6292    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6295class VariancePop(AggFunc):
6296    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6299class CovarSamp(Binary, AggFunc):
6300    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6303class CovarPop(Binary, AggFunc):
6304    pass
key = 'covarpop'
class Week(Func):
6307class Week(Func):
6308    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLTable(Func):
6311class XMLTable(Func):
6312    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):
6315class Year(Func):
6316    pass
key = 'year'
class Use(Expression):
6319class Use(Expression):
6320    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(DML):
6323class Merge(DML):
6324    arg_types = {
6325        "this": True,
6326        "using": True,
6327        "on": True,
6328        "expressions": True,
6329        "with": False,
6330        "returning": False,
6331    }
arg_types = {'this': True, 'using': True, 'on': True, 'expressions': True, 'with': False, 'returning': False}
key = 'merge'
class When(Func):
6334class When(Func):
6335    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):
6340class NextValueFor(Func):
6341    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6346class Semicolon(Expression):
6347    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:
6387def maybe_parse(
6388    sql_or_expression: ExpOrStr,
6389    *,
6390    into: t.Optional[IntoType] = None,
6391    dialect: DialectType = None,
6392    prefix: t.Optional[str] = None,
6393    copy: bool = False,
6394    **opts,
6395) -> Expression:
6396    """Gracefully handle a possible string or expression.
6397
6398    Example:
6399        >>> maybe_parse("1")
6400        Literal(this=1, is_string=False)
6401        >>> maybe_parse(to_identifier("x"))
6402        Identifier(this=x, quoted=False)
6403
6404    Args:
6405        sql_or_expression: the SQL code string or an expression
6406        into: the SQLGlot Expression to parse into
6407        dialect: the dialect used to parse the input expressions (in the case that an
6408            input expression is a SQL string).
6409        prefix: a string to prefix the sql with before it gets parsed
6410            (automatically includes a space)
6411        copy: whether to copy the expression.
6412        **opts: other options to use to parse the input expressions (again, in the case
6413            that an input expression is a SQL string).
6414
6415    Returns:
6416        Expression: the parsed or given expression.
6417    """
6418    if isinstance(sql_or_expression, Expression):
6419        if copy:
6420            return sql_or_expression.copy()
6421        return sql_or_expression
6422
6423    if sql_or_expression is None:
6424        raise ParseError("SQL cannot be None")
6425
6426    import sqlglot
6427
6428    sql = str(sql_or_expression)
6429    if prefix:
6430        sql = f"{prefix} {sql}"
6431
6432    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):
6443def maybe_copy(instance, copy=True):
6444    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:
6665def union(
6666    left: ExpOrStr,
6667    right: ExpOrStr,
6668    distinct: bool = True,
6669    dialect: DialectType = None,
6670    copy: bool = True,
6671    **opts,
6672) -> Union:
6673    """
6674    Initializes a syntax tree from one UNION expression.
6675
6676    Example:
6677        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
6678        'SELECT * FROM foo UNION SELECT * FROM bla'
6679
6680    Args:
6681        left: the SQL code string corresponding to the left-hand side.
6682            If an `Expression` instance is passed, it will be used as-is.
6683        right: the SQL code string corresponding to the right-hand side.
6684            If an `Expression` instance is passed, it will be used as-is.
6685        distinct: set the DISTINCT flag if and only if this is true.
6686        dialect: the dialect used to parse the input expression.
6687        copy: whether to copy the expression.
6688        opts: other options to use to parse the input expressions.
6689
6690    Returns:
6691        The new Union instance.
6692    """
6693    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6694    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6695
6696    return 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:
6699def intersect(
6700    left: ExpOrStr,
6701    right: ExpOrStr,
6702    distinct: bool = True,
6703    dialect: DialectType = None,
6704    copy: bool = True,
6705    **opts,
6706) -> Intersect:
6707    """
6708    Initializes a syntax tree from one INTERSECT expression.
6709
6710    Example:
6711        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
6712        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
6713
6714    Args:
6715        left: the SQL code string corresponding to the left-hand side.
6716            If an `Expression` instance is passed, it will be used as-is.
6717        right: the SQL code string corresponding to the right-hand side.
6718            If an `Expression` instance is passed, it will be used as-is.
6719        distinct: set the DISTINCT flag if and only if this is true.
6720        dialect: the dialect used to parse the input expression.
6721        copy: whether to copy the expression.
6722        opts: other options to use to parse the input expressions.
6723
6724    Returns:
6725        The new Intersect instance.
6726    """
6727    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6728    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6729
6730    return 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:
6733def except_(
6734    left: ExpOrStr,
6735    right: ExpOrStr,
6736    distinct: bool = True,
6737    dialect: DialectType = None,
6738    copy: bool = True,
6739    **opts,
6740) -> Except:
6741    """
6742    Initializes a syntax tree from one EXCEPT expression.
6743
6744    Example:
6745        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
6746        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
6747
6748    Args:
6749        left: the SQL code string corresponding to the left-hand side.
6750            If an `Expression` instance is passed, it will be used as-is.
6751        right: the SQL code string corresponding to the right-hand side.
6752            If an `Expression` instance is passed, it will be used as-is.
6753        distinct: set the DISTINCT flag if and only if this is true.
6754        dialect: the dialect used to parse the input expression.
6755        copy: whether to copy the expression.
6756        opts: other options to use to parse the input expressions.
6757
6758    Returns:
6759        The new Except instance.
6760    """
6761    left = maybe_parse(sql_or_expression=left, dialect=dialect, copy=copy, **opts)
6762    right = maybe_parse(sql_or_expression=right, dialect=dialect, copy=copy, **opts)
6763
6764    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:
6767def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6768    """
6769    Initializes a syntax tree from one or multiple SELECT expressions.
6770
6771    Example:
6772        >>> select("col1", "col2").from_("tbl").sql()
6773        'SELECT col1, col2 FROM tbl'
6774
6775    Args:
6776        *expressions: the SQL code string to parse as the expressions of a
6777            SELECT statement. If an Expression instance is passed, this is used as-is.
6778        dialect: the dialect used to parse the input expressions (in the case that an
6779            input expression is a SQL string).
6780        **opts: other options to use to parse the input expressions (again, in the case
6781            that an input expression is a SQL string).
6782
6783    Returns:
6784        Select: the syntax tree for the SELECT statement.
6785    """
6786    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:
6789def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
6790    """
6791    Initializes a syntax tree from a FROM expression.
6792
6793    Example:
6794        >>> from_("tbl").select("col1", "col2").sql()
6795        'SELECT col1, col2 FROM tbl'
6796
6797    Args:
6798        *expression: the SQL code string to parse as the FROM expressions of a
6799            SELECT statement. If an Expression instance is passed, this is used as-is.
6800        dialect: the dialect used to parse the input expression (in the case that the
6801            input expression is a SQL string).
6802        **opts: other options to use to parse the input expressions (again, in the case
6803            that the input expression is a SQL string).
6804
6805    Returns:
6806        Select: the syntax tree for the SELECT statement.
6807    """
6808    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:
6811def update(
6812    table: str | Table,
6813    properties: dict,
6814    where: t.Optional[ExpOrStr] = None,
6815    from_: t.Optional[ExpOrStr] = None,
6816    dialect: DialectType = None,
6817    **opts,
6818) -> Update:
6819    """
6820    Creates an update statement.
6821
6822    Example:
6823        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz", where="id > 1").sql()
6824        "UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz WHERE id > 1"
6825
6826    Args:
6827        *properties: dictionary of properties to set which are
6828            auto converted to sql objects eg None -> NULL
6829        where: sql conditional parsed into a WHERE statement
6830        from_: sql statement parsed into a FROM statement
6831        dialect: the dialect used to parse the input expressions.
6832        **opts: other options to use to parse the input expressions.
6833
6834    Returns:
6835        Update: the syntax tree for the UPDATE statement.
6836    """
6837    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
6838    update_expr.set(
6839        "expressions",
6840        [
6841            EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
6842            for k, v in properties.items()
6843        ],
6844    )
6845    if from_:
6846        update_expr.set(
6847            "from",
6848            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
6849        )
6850    if isinstance(where, Condition):
6851        where = Where(this=where)
6852    if where:
6853        update_expr.set(
6854            "where",
6855            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
6856        )
6857    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:
6860def delete(
6861    table: ExpOrStr,
6862    where: t.Optional[ExpOrStr] = None,
6863    returning: t.Optional[ExpOrStr] = None,
6864    dialect: DialectType = None,
6865    **opts,
6866) -> Delete:
6867    """
6868    Builds a delete statement.
6869
6870    Example:
6871        >>> delete("my_table", where="id > 1").sql()
6872        'DELETE FROM my_table WHERE id > 1'
6873
6874    Args:
6875        where: sql conditional parsed into a WHERE statement
6876        returning: sql conditional parsed into a RETURNING statement
6877        dialect: the dialect used to parse the input expressions.
6878        **opts: other options to use to parse the input expressions.
6879
6880    Returns:
6881        Delete: the syntax tree for the DELETE statement.
6882    """
6883    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
6884    if where:
6885        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
6886    if returning:
6887        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
6888    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:
6891def insert(
6892    expression: ExpOrStr,
6893    into: ExpOrStr,
6894    columns: t.Optional[t.Sequence[str | Identifier]] = None,
6895    overwrite: t.Optional[bool] = None,
6896    returning: t.Optional[ExpOrStr] = None,
6897    dialect: DialectType = None,
6898    copy: bool = True,
6899    **opts,
6900) -> Insert:
6901    """
6902    Builds an INSERT statement.
6903
6904    Example:
6905        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
6906        'INSERT INTO tbl VALUES (1, 2, 3)'
6907
6908    Args:
6909        expression: the sql string or expression of the INSERT statement
6910        into: the tbl to insert data to.
6911        columns: optionally the table's column names.
6912        overwrite: whether to INSERT OVERWRITE or not.
6913        returning: sql conditional parsed into a RETURNING statement
6914        dialect: the dialect used to parse the input expressions.
6915        copy: whether to copy the expression.
6916        **opts: other options to use to parse the input expressions.
6917
6918    Returns:
6919        Insert: the syntax tree for the INSERT statement.
6920    """
6921    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
6922    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
6923
6924    if columns:
6925        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
6926
6927    insert = Insert(this=this, expression=expr, overwrite=overwrite)
6928
6929    if returning:
6930        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
6931
6932    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:
6935def merge(
6936    *when_exprs: ExpOrStr,
6937    into: ExpOrStr,
6938    using: ExpOrStr,
6939    on: ExpOrStr,
6940    returning: t.Optional[ExpOrStr] = None,
6941    dialect: DialectType = None,
6942    copy: bool = True,
6943    **opts,
6944) -> Merge:
6945    """
6946    Builds a MERGE statement.
6947
6948    Example:
6949        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
6950        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
6951        ...       into="my_table",
6952        ...       using="source_table",
6953        ...       on="my_table.id = source_table.id").sql()
6954        '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)'
6955
6956    Args:
6957        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
6958        into: The target table to merge data into.
6959        using: The source table to merge data from.
6960        on: The join condition for the merge.
6961        returning: The columns to return from the merge.
6962        dialect: The dialect used to parse the input expressions.
6963        copy: Whether to copy the expression.
6964        **opts: Other options to use to parse the input expressions.
6965
6966    Returns:
6967        Merge: The syntax tree for the MERGE statement.
6968    """
6969    merge = Merge(
6970        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
6971        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
6972        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
6973        expressions=[
6974            maybe_parse(when_expr, dialect=dialect, copy=copy, into=When, **opts)
6975            for when_expr in when_exprs
6976        ],
6977    )
6978    if returning:
6979        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
6980
6981    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:
6984def condition(
6985    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
6986) -> Condition:
6987    """
6988    Initialize a logical condition expression.
6989
6990    Example:
6991        >>> condition("x=1").sql()
6992        'x = 1'
6993
6994        This is helpful for composing larger logical syntax trees:
6995        >>> where = condition("x=1")
6996        >>> where = where.and_("y=1")
6997        >>> Select().from_("tbl").select("*").where(where).sql()
6998        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
6999
7000    Args:
7001        *expression: the SQL code string to parse.
7002            If an Expression instance is passed, this is used as-is.
7003        dialect: the dialect used to parse the input expression (in the case that the
7004            input expression is a SQL string).
7005        copy: Whether to copy `expression` (only applies to expressions).
7006        **opts: other options to use to parse the input expressions (again, in the case
7007            that the input expression is a SQL string).
7008
7009    Returns:
7010        The new Condition instance
7011    """
7012    return maybe_parse(
7013        expression,
7014        into=Condition,
7015        dialect=dialect,
7016        copy=copy,
7017        **opts,
7018    )

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

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

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

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

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

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

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

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

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

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

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:
8071def true() -> Boolean:
8072    """
8073    Returns a true Boolean expression.
8074    """
8075    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8078def false() -> Boolean:
8079    """
8080    Returns a false Boolean expression.
8081    """
8082    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8085def null() -> Null:
8086    """
8087    Returns a Null expression.
8088    """
8089    return Null()

Returns a Null expression.

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