Edit on GitHub

Expressions

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

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


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

Retrieves the argument with key "this".

expression: Any
150    @property
151    def expression(self) -> t.Any:
152        """
153        Retrieves the argument with key "expression".
154        """
155        return self.args.get("expression")

Retrieves the argument with key "expression".

expressions: List[Any]
157    @property
158    def expressions(self) -> t.List[t.Any]:
159        """
160        Retrieves the argument with key "expressions".
161        """
162        return self.args.get("expressions") or []

Retrieves the argument with key "expressions".

def text(self, key) -> str:
164    def text(self, key) -> str:
165        """
166        Returns a textual representation of the argument corresponding to "key". This can only be used
167        for args that are strings or leaf Expression instances, such as identifiers and literals.
168        """
169        field = self.args.get(key)
170        if isinstance(field, str):
171            return field
172        if isinstance(field, (Identifier, Literal, Var)):
173            return field.this
174        if isinstance(field, (Star, Null)):
175            return field.name
176        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
178    @property
179    def is_string(self) -> bool:
180        """
181        Checks whether a Literal expression is a string.
182        """
183        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

is_number: bool
185    @property
186    def is_number(self) -> bool:
187        """
188        Checks whether a Literal expression is a number.
189        """
190        return (isinstance(self, Literal) and not self.args["is_string"]) or (
191            isinstance(self, Neg) and self.this.is_number
192        )

Checks whether a Literal expression is a number.

def to_py(self) -> Any:
194    def to_py(self) -> t.Any:
195        """
196        Returns a Python object equivalent of the SQL node.
197        """
198        raise ValueError(f"{self} cannot be converted to a Python object.")

Returns a Python object equivalent of the SQL node.

is_int: bool
200    @property
201    def is_int(self) -> bool:
202        """
203        Checks whether an expression is an integer.
204        """
205        return self.is_number and isinstance(self.to_py(), int)

Checks whether an expression is an integer.

is_star: bool
207    @property
208    def is_star(self) -> bool:
209        """Checks whether an expression is a star."""
210        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

alias: str
212    @property
213    def alias(self) -> str:
214        """
215        Returns the alias of the expression, or an empty string if it's not aliased.
216        """
217        if isinstance(self.args.get("alias"), TableAlias):
218            return self.args["alias"].name
219        return self.text("alias")

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

alias_column_names: List[str]
221    @property
222    def alias_column_names(self) -> t.List[str]:
223        table_alias = self.args.get("alias")
224        if not table_alias:
225            return []
226        return [c.name for c in table_alias.args.get("columns") or []]
name: str
228    @property
229    def name(self) -> str:
230        return self.text("this")
alias_or_name: str
232    @property
233    def alias_or_name(self) -> str:
234        return self.alias or self.name
output_name: str
236    @property
237    def output_name(self) -> str:
238        """
239        Name of the output column if this expression is a selection.
240
241        If the Expression has no output name, an empty string is returned.
242
243        Example:
244            >>> from sqlglot import parse_one
245            >>> parse_one("SELECT a").expressions[0].output_name
246            'a'
247            >>> parse_one("SELECT b AS c").expressions[0].output_name
248            'c'
249            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
250            ''
251        """
252        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]
254    @property
255    def type(self) -> t.Optional[DataType]:
256        return self._type
def is_type(self, *dtypes) -> bool:
264    def is_type(self, *dtypes) -> bool:
265        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
267    def is_leaf(self) -> bool:
268        return not any(isinstance(v, (Expression, list)) and v for v in self.args.values())
meta: Dict[str, Any]
270    @property
271    def meta(self) -> t.Dict[str, t.Any]:
272        if self._meta is None:
273            self._meta = {}
274        return self._meta
def copy(self) -> typing_extensions.Self:
310    def copy(self) -> Self:
311        """
312        Returns a deep copy of the expression.
313        """
314        return deepcopy(self)

Returns a deep copy of the expression.

def add_comments( self, comments: Optional[List[str]] = None, prepend: bool = False) -> None:
316    def add_comments(self, comments: t.Optional[t.List[str]] = None, prepend: bool = False) -> None:
317        if self.comments is None:
318            self.comments = []
319
320        if comments:
321            for comment in comments:
322                _, *meta = comment.split(SQLGLOT_META)
323                if meta:
324                    for kv in "".join(meta).split(","):
325                        k, *v = kv.split("=")
326                        value = v[0].strip() if v else True
327                        self.meta[k.strip()] = to_bool(value)
328
329                if not prepend:
330                    self.comments.append(comment)
331
332            if prepend:
333                self.comments = comments + self.comments
def pop_comments(self) -> List[str]:
335    def pop_comments(self) -> t.List[str]:
336        comments = self.comments or []
337        self.comments = None
338        return comments
def append(self, arg_key: str, value: Any) -> None:
340    def append(self, arg_key: str, value: t.Any) -> None:
341        """
342        Appends value to arg_key if it's a list or sets it as a new list.
343
344        Args:
345            arg_key (str): name of the list expression arg
346            value (Any): value to append to the list
347        """
348        if type(self.args.get(arg_key)) is not list:
349            self.args[arg_key] = []
350        self._set_parent(arg_key, value)
351        values = self.args[arg_key]
352        if hasattr(value, "parent"):
353            value.index = len(values)
354        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:
356    def set(
357        self,
358        arg_key: str,
359        value: t.Any,
360        index: t.Optional[int] = None,
361        overwrite: bool = True,
362    ) -> None:
363        """
364        Sets arg_key to value.
365
366        Args:
367            arg_key: name of the expression arg.
368            value: value to set the arg to.
369            index: if the arg is a list, this specifies what position to add the value in it.
370            overwrite: assuming an index is given, this determines whether to overwrite the
371                list entry instead of only inserting a new value (i.e., like list.insert).
372        """
373        if index is not None:
374            expressions = self.args.get(arg_key) or []
375
376            if seq_get(expressions, index) is None:
377                return
378            if value is None:
379                expressions.pop(index)
380                for v in expressions[index:]:
381                    v.index = v.index - 1
382                return
383
384            if isinstance(value, list):
385                expressions.pop(index)
386                expressions[index:index] = value
387            elif overwrite:
388                expressions[index] = value
389            else:
390                expressions.insert(index, value)
391
392            value = expressions
393        elif value is None:
394            self.args.pop(arg_key, None)
395            return
396
397        self.args[arg_key] = value
398        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
412    @property
413    def depth(self) -> int:
414        """
415        Returns the depth of this tree.
416        """
417        if self.parent:
418            return self.parent.depth + 1
419        return 0

Returns the depth of this tree.

def iter_expressions(self, reverse: bool = False) -> Iterator[Expression]:
421    def iter_expressions(self, reverse: bool = False) -> t.Iterator[Expression]:
422        """Yields the key and expression for all arguments, exploding list args."""
423        for vs in reversed(self.args.values()) if reverse else self.args.values():  # type: ignore
424            if type(vs) is list:
425                for v in reversed(vs) if reverse else vs:  # type: ignore
426                    if hasattr(v, "parent"):
427                        yield v
428            else:
429                if hasattr(vs, "parent"):
430                    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]:
432    def find(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Optional[E]:
433        """
434        Returns the first node in this tree which matches at least one of
435        the specified types.
436
437        Args:
438            expression_types: the expression type(s) to match.
439            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
440
441        Returns:
442            The node which matches the criteria or None if no such node was found.
443        """
444        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]:
446    def find_all(self, *expression_types: t.Type[E], bfs: bool = True) -> t.Iterator[E]:
447        """
448        Returns a generator object which visits all nodes in this tree and only
449        yields those that match at least one of the specified expression types.
450
451        Args:
452            expression_types: the expression type(s) to match.
453            bfs: whether to search the AST using the BFS algorithm (DFS is used if false).
454
455        Returns:
456            The generator object.
457        """
458        for expression in self.walk(bfs=bfs):
459            if isinstance(expression, expression_types):
460                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]:
462    def find_ancestor(self, *expression_types: t.Type[E]) -> t.Optional[E]:
463        """
464        Returns a nearest parent matching expression_types.
465
466        Args:
467            expression_types: the expression type(s) to match.
468
469        Returns:
470            The parent node.
471        """
472        ancestor = self.parent
473        while ancestor and not isinstance(ancestor, expression_types):
474            ancestor = ancestor.parent
475        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]
477    @property
478    def parent_select(self) -> t.Optional[Select]:
479        """
480        Returns the parent select statement.
481        """
482        return self.find_ancestor(Select)

Returns the parent select statement.

same_parent: bool
484    @property
485    def same_parent(self) -> bool:
486        """Returns if the parent is the same class as itself."""
487        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
489    def root(self) -> Expression:
490        """
491        Returns the root expression of this tree.
492        """
493        expression = self
494        while expression.parent:
495            expression = expression.parent
496        return expression

Returns the root expression of this tree.

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

Returns the first non parenthesis child or self.

def unalias(self):
573    def unalias(self):
574        """
575        Returns the inner expression if this is an Alias.
576        """
577        if isinstance(self, Alias):
578            return self.this
579        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
581    def unnest_operands(self):
582        """
583        Returns unnested operands as a tuple.
584        """
585        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

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

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
772    @classmethod
773    def load(cls, obj):
774        """
775        Load a dict (as returned by `Expression.dump`) into an Expression instance.
776        """
777        from sqlglot.serde import load
778
779        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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
781    def and_(
782        self,
783        *expressions: t.Optional[ExpOrStr],
784        dialect: DialectType = None,
785        copy: bool = True,
786        wrap: bool = True,
787        **opts,
788    ) -> Condition:
789        """
790        AND this condition with one or multiple expressions.
791
792        Example:
793            >>> condition("x=1").and_("y=1").sql()
794            'x = 1 AND y = 1'
795
796        Args:
797            *expressions: the SQL code strings to parse.
798                If an `Expression` instance is passed, it will be used as-is.
799            dialect: the dialect used to parse the input expression.
800            copy: whether to copy the involved expressions (only applies to Expressions).
801            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
802                precedence issues, but can be turned off when the produced AST is too deep and
803                causes recursion-related issues.
804            opts: other options to use to parse the input expressions.
805
806        Returns:
807            The new And condition.
808        """
809        return and_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **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).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • 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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
811    def or_(
812        self,
813        *expressions: t.Optional[ExpOrStr],
814        dialect: DialectType = None,
815        copy: bool = True,
816        wrap: bool = True,
817        **opts,
818    ) -> Condition:
819        """
820        OR this condition with one or multiple expressions.
821
822        Example:
823            >>> condition("x=1").or_("y=1").sql()
824            'x = 1 OR y = 1'
825
826        Args:
827            *expressions: the SQL code strings to parse.
828                If an `Expression` instance is passed, it will be used as-is.
829            dialect: the dialect used to parse the input expression.
830            copy: whether to copy the involved expressions (only applies to Expressions).
831            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
832                precedence issues, but can be turned off when the produced AST is too deep and
833                causes recursion-related issues.
834            opts: other options to use to parse the input expressions.
835
836        Returns:
837            The new Or condition.
838        """
839        return or_(self, *expressions, dialect=dialect, copy=copy, wrap=wrap, **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).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • opts: other options to use to parse the input expressions.
Returns:

The new Or condition.

def not_(self, copy: bool = True):
841    def not_(self, copy: bool = True):
842        """
843        Wrap this condition with NOT.
844
845        Example:
846            >>> condition("x=1").not_().sql()
847            'NOT x = 1'
848
849        Args:
850            copy: whether to copy this object.
851
852        Returns:
853            The new Not instance.
854        """
855        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 update_positions( self: ~E, other: Union[sqlglot.tokens.Token, Expression, NoneType] = None, **kwargs: Any) -> ~E:
857    def update_positions(
858        self: E, other: t.Optional[Token | Expression] = None, **kwargs: t.Any
859    ) -> E:
860        """
861        Update this expression with positions from a token or other expression.
862
863        Args:
864            other: a token or expression to update this expression with.
865
866        Returns:
867            The updated expression.
868        """
869        if isinstance(other, Expression):
870            self.meta.update({k: v for k, v in other.meta.items() if k in POSITION_META_KEYS})
871        elif other is not None:
872            self.meta.update(
873                {
874                    "line": other.line,
875                    "col": other.col,
876                    "start": other.start,
877                    "end": other.end,
878                }
879            )
880        self.meta.update({k: v for k, v in kwargs.items() if k in POSITION_META_KEYS})
881        return self

Update this expression with positions from a token or other expression.

Arguments:
  • other: a token or expression to update this expression with.
Returns:

The updated expression.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
883    def as_(
884        self,
885        alias: str | Identifier,
886        quoted: t.Optional[bool] = None,
887        dialect: DialectType = None,
888        copy: bool = True,
889        **opts,
890    ) -> Alias:
891        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:
916    def isin(
917        self,
918        *expressions: t.Any,
919        query: t.Optional[ExpOrStr] = None,
920        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
921        copy: bool = True,
922        **opts,
923    ) -> In:
924        subquery = maybe_parse(query, copy=copy, **opts) if query else None
925        if subquery and not isinstance(subquery, Subquery):
926            subquery = subquery.subquery(copy=False)
927
928        return In(
929            this=maybe_copy(self, copy),
930            expressions=[convert(e, copy=copy) for e in expressions],
931            query=subquery,
932            unnest=(
933                Unnest(
934                    expressions=[
935                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
936                        for e in ensure_list(unnest)
937                    ]
938                )
939                if unnest
940                else None
941            ),
942        )
def between( self, low: Any, high: Any, copy: bool = True, symmetric: Optional[bool] = None, **opts) -> Between:
944    def between(
945        self,
946        low: t.Any,
947        high: t.Any,
948        copy: bool = True,
949        symmetric: t.Optional[bool] = None,
950        **opts,
951    ) -> Between:
952        between = Between(
953            this=maybe_copy(self, copy),
954            low=convert(low, copy=copy, **opts),
955            high=convert(high, copy=copy, **opts),
956        )
957        if symmetric is not None:
958            between.set("symmetric", symmetric)
959
960        return between
def is_( self, other: Union[str, Expression]) -> Is:
962    def is_(self, other: ExpOrStr) -> Is:
963        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
965    def like(self, other: ExpOrStr) -> Like:
966        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
968    def ilike(self, other: ExpOrStr) -> ILike:
969        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
971    def eq(self, other: t.Any) -> EQ:
972        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
974    def neq(self, other: t.Any) -> NEQ:
975        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
977    def rlike(self, other: ExpOrStr) -> RegexpLike:
978        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
980    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
981        div = self._binop(Div, other)
982        div.args["typed"] = typed
983        div.args["safe"] = safe
984        return div
def asc(self, nulls_first: bool = True) -> Ordered:
986    def asc(self, nulls_first: bool = True) -> Ordered:
987        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
989    def desc(self, nulls_first: bool = False) -> Ordered:
990        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):
1073class Condition(Expression):
1074    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

key = 'predicate'
class DerivedTable(Expression):
1081class DerivedTable(Expression):
1082    @property
1083    def selects(self) -> t.List[Expression]:
1084        return self.this.selects if isinstance(self.this, Query) else []
1085
1086    @property
1087    def named_selects(self) -> t.List[str]:
1088        return [select.output_name for select in self.selects]
selects: List[Expression]
1082    @property
1083    def selects(self) -> t.List[Expression]:
1084        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
1086    @property
1087    def named_selects(self) -> t.List[str]:
1088        return [select.output_name for select in self.selects]
key = 'derivedtable'
class Query(Expression):
1091class Query(Expression):
1092    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1093        """
1094        Returns a `Subquery` that wraps around this query.
1095
1096        Example:
1097            >>> subquery = Select().select("x").from_("tbl").subquery()
1098            >>> Select().select("x").from_(subquery).sql()
1099            'SELECT x FROM (SELECT x FROM tbl)'
1100
1101        Args:
1102            alias: an optional alias for the subquery.
1103            copy: if `False`, modify this expression instance in-place.
1104        """
1105        instance = maybe_copy(self, copy)
1106        if not isinstance(alias, Expression):
1107            alias = TableAlias(this=to_identifier(alias)) if alias else None
1108
1109        return Subquery(this=instance, alias=alias)
1110
1111    def limit(
1112        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1113    ) -> Q:
1114        """
1115        Adds a LIMIT clause to this query.
1116
1117        Example:
1118            >>> select("1").union(select("1")).limit(1).sql()
1119            'SELECT 1 UNION SELECT 1 LIMIT 1'
1120
1121        Args:
1122            expression: the SQL code string to parse.
1123                This can also be an integer.
1124                If a `Limit` instance is passed, it will be used as-is.
1125                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1126            dialect: the dialect used to parse the input expression.
1127            copy: if `False`, modify this expression instance in-place.
1128            opts: other options to use to parse the input expressions.
1129
1130        Returns:
1131            A limited Select expression.
1132        """
1133        return _apply_builder(
1134            expression=expression,
1135            instance=self,
1136            arg="limit",
1137            into=Limit,
1138            prefix="LIMIT",
1139            dialect=dialect,
1140            copy=copy,
1141            into_arg="expression",
1142            **opts,
1143        )
1144
1145    def offset(
1146        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1147    ) -> Q:
1148        """
1149        Set the OFFSET expression.
1150
1151        Example:
1152            >>> Select().from_("tbl").select("x").offset(10).sql()
1153            'SELECT x FROM tbl OFFSET 10'
1154
1155        Args:
1156            expression: the SQL code string to parse.
1157                This can also be an integer.
1158                If a `Offset` instance is passed, this is used as-is.
1159                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1160            dialect: the dialect used to parse the input expression.
1161            copy: if `False`, modify this expression instance in-place.
1162            opts: other options to use to parse the input expressions.
1163
1164        Returns:
1165            The modified Select expression.
1166        """
1167        return _apply_builder(
1168            expression=expression,
1169            instance=self,
1170            arg="offset",
1171            into=Offset,
1172            prefix="OFFSET",
1173            dialect=dialect,
1174            copy=copy,
1175            into_arg="expression",
1176            **opts,
1177        )
1178
1179    def order_by(
1180        self: Q,
1181        *expressions: t.Optional[ExpOrStr],
1182        append: bool = True,
1183        dialect: DialectType = None,
1184        copy: bool = True,
1185        **opts,
1186    ) -> Q:
1187        """
1188        Set the ORDER BY expression.
1189
1190        Example:
1191            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1192            'SELECT x FROM tbl ORDER BY x DESC'
1193
1194        Args:
1195            *expressions: the SQL code strings to parse.
1196                If a `Group` instance is passed, this is used as-is.
1197                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1198            append: if `True`, add to any existing expressions.
1199                Otherwise, this flattens all the `Order` expression into a single expression.
1200            dialect: the dialect used to parse the input expression.
1201            copy: if `False`, modify this expression instance in-place.
1202            opts: other options to use to parse the input expressions.
1203
1204        Returns:
1205            The modified Select expression.
1206        """
1207        return _apply_child_list_builder(
1208            *expressions,
1209            instance=self,
1210            arg="order",
1211            append=append,
1212            copy=copy,
1213            prefix="ORDER BY",
1214            into=Order,
1215            dialect=dialect,
1216            **opts,
1217        )
1218
1219    @property
1220    def ctes(self) -> t.List[CTE]:
1221        """Returns a list of all the CTEs attached to this query."""
1222        with_ = self.args.get("with")
1223        return with_.expressions if with_ else []
1224
1225    @property
1226    def selects(self) -> t.List[Expression]:
1227        """Returns the query's projections."""
1228        raise NotImplementedError("Query objects must implement `selects`")
1229
1230    @property
1231    def named_selects(self) -> t.List[str]:
1232        """Returns the output names of the query's projections."""
1233        raise NotImplementedError("Query objects must implement `named_selects`")
1234
1235    def select(
1236        self: Q,
1237        *expressions: t.Optional[ExpOrStr],
1238        append: bool = True,
1239        dialect: DialectType = None,
1240        copy: bool = True,
1241        **opts,
1242    ) -> Q:
1243        """
1244        Append to or set the SELECT expressions.
1245
1246        Example:
1247            >>> Select().select("x", "y").sql()
1248            'SELECT x, y'
1249
1250        Args:
1251            *expressions: the SQL code strings to parse.
1252                If an `Expression` instance is passed, it will be used as-is.
1253            append: if `True`, add to any existing expressions.
1254                Otherwise, this resets the expressions.
1255            dialect: the dialect used to parse the input expressions.
1256            copy: if `False`, modify this expression instance in-place.
1257            opts: other options to use to parse the input expressions.
1258
1259        Returns:
1260            The modified Query expression.
1261        """
1262        raise NotImplementedError("Query objects must implement `select`")
1263
1264    def where(
1265        self: Q,
1266        *expressions: t.Optional[ExpOrStr],
1267        append: bool = True,
1268        dialect: DialectType = None,
1269        copy: bool = True,
1270        **opts,
1271    ) -> Q:
1272        """
1273        Append to or set the WHERE expressions.
1274
1275        Examples:
1276            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1277            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1278
1279        Args:
1280            *expressions: the SQL code strings to parse.
1281                If an `Expression` instance is passed, it will be used as-is.
1282                Multiple expressions are combined with an AND operator.
1283            append: if `True`, AND the new expressions to any existing expression.
1284                Otherwise, this resets the expression.
1285            dialect: the dialect used to parse the input expressions.
1286            copy: if `False`, modify this expression instance in-place.
1287            opts: other options to use to parse the input expressions.
1288
1289        Returns:
1290            The modified expression.
1291        """
1292        return _apply_conjunction_builder(
1293            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1294            instance=self,
1295            arg="where",
1296            append=append,
1297            into=Where,
1298            dialect=dialect,
1299            copy=copy,
1300            **opts,
1301        )
1302
1303    def with_(
1304        self: Q,
1305        alias: ExpOrStr,
1306        as_: ExpOrStr,
1307        recursive: t.Optional[bool] = None,
1308        materialized: t.Optional[bool] = None,
1309        append: bool = True,
1310        dialect: DialectType = None,
1311        copy: bool = True,
1312        scalar: bool = False,
1313        **opts,
1314    ) -> Q:
1315        """
1316        Append to or set the common table expressions.
1317
1318        Example:
1319            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1320            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1321
1322        Args:
1323            alias: the SQL code string to parse as the table name.
1324                If an `Expression` instance is passed, this is used as-is.
1325            as_: the SQL code string to parse as the table expression.
1326                If an `Expression` instance is passed, it will be used as-is.
1327            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1328            materialized: set the MATERIALIZED part of the expression.
1329            append: if `True`, add to any existing expressions.
1330                Otherwise, this resets the expressions.
1331            dialect: the dialect used to parse the input expression.
1332            copy: if `False`, modify this expression instance in-place.
1333            scalar: if `True`, this is a scalar common table expression.
1334            opts: other options to use to parse the input expressions.
1335
1336        Returns:
1337            The modified expression.
1338        """
1339        return _apply_cte_builder(
1340            self,
1341            alias,
1342            as_,
1343            recursive=recursive,
1344            materialized=materialized,
1345            append=append,
1346            dialect=dialect,
1347            copy=copy,
1348            scalar=scalar,
1349            **opts,
1350        )
1351
1352    def union(
1353        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1354    ) -> Union:
1355        """
1356        Builds a UNION expression.
1357
1358        Example:
1359            >>> import sqlglot
1360            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1361            'SELECT * FROM foo UNION SELECT * FROM bla'
1362
1363        Args:
1364            expressions: the SQL code strings.
1365                If `Expression` instances are passed, they will be used as-is.
1366            distinct: set the DISTINCT flag if and only if this is true.
1367            dialect: the dialect used to parse the input expression.
1368            opts: other options to use to parse the input expressions.
1369
1370        Returns:
1371            The new Union expression.
1372        """
1373        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1374
1375    def intersect(
1376        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1377    ) -> Intersect:
1378        """
1379        Builds an INTERSECT expression.
1380
1381        Example:
1382            >>> import sqlglot
1383            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1384            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1385
1386        Args:
1387            expressions: the SQL code strings.
1388                If `Expression` instances are passed, they will be used as-is.
1389            distinct: set the DISTINCT flag if and only if this is true.
1390            dialect: the dialect used to parse the input expression.
1391            opts: other options to use to parse the input expressions.
1392
1393        Returns:
1394            The new Intersect expression.
1395        """
1396        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)
1397
1398    def except_(
1399        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1400    ) -> Except:
1401        """
1402        Builds an EXCEPT expression.
1403
1404        Example:
1405            >>> import sqlglot
1406            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1407            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1408
1409        Args:
1410            expressions: the SQL code strings.
1411                If `Expression` instance are passed, they will be used as-is.
1412            distinct: set the DISTINCT flag if and only if this is true.
1413            dialect: the dialect used to parse the input expression.
1414            opts: other options to use to parse the input expressions.
1415
1416        Returns:
1417            The new Except expression.
1418        """
1419        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
1092    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
1093        """
1094        Returns a `Subquery` that wraps around this query.
1095
1096        Example:
1097            >>> subquery = Select().select("x").from_("tbl").subquery()
1098            >>> Select().select("x").from_(subquery).sql()
1099            'SELECT x FROM (SELECT x FROM tbl)'
1100
1101        Args:
1102            alias: an optional alias for the subquery.
1103            copy: if `False`, modify this expression instance in-place.
1104        """
1105        instance = maybe_copy(self, copy)
1106        if not isinstance(alias, Expression):
1107            alias = TableAlias(this=to_identifier(alias)) if alias else None
1108
1109        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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1111    def limit(
1112        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1113    ) -> Q:
1114        """
1115        Adds a LIMIT clause to this query.
1116
1117        Example:
1118            >>> select("1").union(select("1")).limit(1).sql()
1119            'SELECT 1 UNION SELECT 1 LIMIT 1'
1120
1121        Args:
1122            expression: the SQL code string to parse.
1123                This can also be an integer.
1124                If a `Limit` instance is passed, it will be used as-is.
1125                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
1126            dialect: the dialect used to parse the input expression.
1127            copy: if `False`, modify this expression instance in-place.
1128            opts: other options to use to parse the input expressions.
1129
1130        Returns:
1131            A limited Select expression.
1132        """
1133        return _apply_builder(
1134            expression=expression,
1135            instance=self,
1136            arg="limit",
1137            into=Limit,
1138            prefix="LIMIT",
1139            dialect=dialect,
1140            copy=copy,
1141            into_arg="expression",
1142            **opts,
1143        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1145    def offset(
1146        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1147    ) -> Q:
1148        """
1149        Set the OFFSET expression.
1150
1151        Example:
1152            >>> Select().from_("tbl").select("x").offset(10).sql()
1153            'SELECT x FROM tbl OFFSET 10'
1154
1155        Args:
1156            expression: the SQL code string to parse.
1157                This can also be an integer.
1158                If a `Offset` instance is passed, this is used as-is.
1159                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1160            dialect: the dialect used to parse the input expression.
1161            copy: if `False`, modify this expression instance in-place.
1162            opts: other options to use to parse the input expressions.
1163
1164        Returns:
1165            The modified Select expression.
1166        """
1167        return _apply_builder(
1168            expression=expression,
1169            instance=self,
1170            arg="offset",
1171            into=Offset,
1172            prefix="OFFSET",
1173            dialect=dialect,
1174            copy=copy,
1175            into_arg="expression",
1176            **opts,
1177        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1179    def order_by(
1180        self: Q,
1181        *expressions: t.Optional[ExpOrStr],
1182        append: bool = True,
1183        dialect: DialectType = None,
1184        copy: bool = True,
1185        **opts,
1186    ) -> Q:
1187        """
1188        Set the ORDER BY expression.
1189
1190        Example:
1191            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
1192            'SELECT x FROM tbl ORDER BY x DESC'
1193
1194        Args:
1195            *expressions: the SQL code strings to parse.
1196                If a `Group` instance is passed, this is used as-is.
1197                If another `Expression` instance is passed, it will be wrapped in a `Order`.
1198            append: if `True`, add to any existing expressions.
1199                Otherwise, this flattens all the `Order` expression into a single expression.
1200            dialect: the dialect used to parse the input expression.
1201            copy: if `False`, modify this expression instance in-place.
1202            opts: other options to use to parse the input expressions.
1203
1204        Returns:
1205            The modified Select expression.
1206        """
1207        return _apply_child_list_builder(
1208            *expressions,
1209            instance=self,
1210            arg="order",
1211            append=append,
1212            copy=copy,
1213            prefix="ORDER BY",
1214            into=Order,
1215            dialect=dialect,
1216            **opts,
1217        )

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

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

selects: List[Expression]
1225    @property
1226    def selects(self) -> t.List[Expression]:
1227        """Returns the query's projections."""
1228        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
1230    @property
1231    def named_selects(self) -> t.List[str]:
1232        """Returns the output names of the query's projections."""
1233        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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1235    def select(
1236        self: Q,
1237        *expressions: t.Optional[ExpOrStr],
1238        append: bool = True,
1239        dialect: DialectType = None,
1240        copy: bool = True,
1241        **opts,
1242    ) -> Q:
1243        """
1244        Append to or set the SELECT expressions.
1245
1246        Example:
1247            >>> Select().select("x", "y").sql()
1248            'SELECT x, y'
1249
1250        Args:
1251            *expressions: the SQL code strings to parse.
1252                If an `Expression` instance is passed, it will be used as-is.
1253            append: if `True`, add to any existing expressions.
1254                Otherwise, this resets the expressions.
1255            dialect: the dialect used to parse the input expressions.
1256            copy: if `False`, modify this expression instance in-place.
1257            opts: other options to use to parse the input expressions.
1258
1259        Returns:
1260            The modified Query expression.
1261        """
1262        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 where( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1264    def where(
1265        self: Q,
1266        *expressions: t.Optional[ExpOrStr],
1267        append: bool = True,
1268        dialect: DialectType = None,
1269        copy: bool = True,
1270        **opts,
1271    ) -> Q:
1272        """
1273        Append to or set the WHERE expressions.
1274
1275        Examples:
1276            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
1277            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
1278
1279        Args:
1280            *expressions: the SQL code strings to parse.
1281                If an `Expression` instance is passed, it will be used as-is.
1282                Multiple expressions are combined with an AND operator.
1283            append: if `True`, AND the new expressions to any existing expression.
1284                Otherwise, this resets the expression.
1285            dialect: the dialect used to parse the input expressions.
1286            copy: if `False`, modify this expression instance in-place.
1287            opts: other options to use to parse the input expressions.
1288
1289        Returns:
1290            The modified expression.
1291        """
1292        return _apply_conjunction_builder(
1293            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
1294            instance=self,
1295            arg="where",
1296            append=append,
1297            into=Where,
1298            dialect=dialect,
1299            copy=copy,
1300            **opts,
1301        )

Append to or set the WHERE expressions.

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

The modified 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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, scalar: bool = False, **opts) -> ~Q:
1303    def with_(
1304        self: Q,
1305        alias: ExpOrStr,
1306        as_: ExpOrStr,
1307        recursive: t.Optional[bool] = None,
1308        materialized: t.Optional[bool] = None,
1309        append: bool = True,
1310        dialect: DialectType = None,
1311        copy: bool = True,
1312        scalar: bool = False,
1313        **opts,
1314    ) -> Q:
1315        """
1316        Append to or set the common table expressions.
1317
1318        Example:
1319            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1320            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1321
1322        Args:
1323            alias: the SQL code string to parse as the table name.
1324                If an `Expression` instance is passed, this is used as-is.
1325            as_: the SQL code string to parse as the table expression.
1326                If an `Expression` instance is passed, it will be used as-is.
1327            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1328            materialized: set the MATERIALIZED part of the expression.
1329            append: if `True`, add to any existing expressions.
1330                Otherwise, this resets the expressions.
1331            dialect: the dialect used to parse the input expression.
1332            copy: if `False`, modify this expression instance in-place.
1333            scalar: if `True`, this is a scalar common table expression.
1334            opts: other options to use to parse the input expressions.
1335
1336        Returns:
1337            The modified expression.
1338        """
1339        return _apply_cte_builder(
1340            self,
1341            alias,
1342            as_,
1343            recursive=recursive,
1344            materialized=materialized,
1345            append=append,
1346            dialect=dialect,
1347            copy=copy,
1348            scalar=scalar,
1349            **opts,
1350        )

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.
  • scalar: if True, this is a scalar common table expression.
  • opts: other options to use to parse the input expressions.
Returns:

The modified expression.

def union( self, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Union:
1352    def union(
1353        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1354    ) -> Union:
1355        """
1356        Builds a UNION expression.
1357
1358        Example:
1359            >>> import sqlglot
1360            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1361            'SELECT * FROM foo UNION SELECT * FROM bla'
1362
1363        Args:
1364            expressions: the SQL code strings.
1365                If `Expression` instances are passed, they will be used as-is.
1366            distinct: set the DISTINCT flag if and only if this is true.
1367            dialect: the dialect used to parse the input expression.
1368            opts: other options to use to parse the input expressions.
1369
1370        Returns:
1371            The new Union expression.
1372        """
1373        return union(self, *expressions, 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:
  • expressions: the SQL code strings. If Expression instances are passed, they 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, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Intersect:
1375    def intersect(
1376        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1377    ) -> Intersect:
1378        """
1379        Builds an INTERSECT expression.
1380
1381        Example:
1382            >>> import sqlglot
1383            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1384            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1385
1386        Args:
1387            expressions: the SQL code strings.
1388                If `Expression` instances are passed, they will be used as-is.
1389            distinct: set the DISTINCT flag if and only if this is true.
1390            dialect: the dialect used to parse the input expression.
1391            opts: other options to use to parse the input expressions.
1392
1393        Returns:
1394            The new Intersect expression.
1395        """
1396        return intersect(self, *expressions, 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:
  • expressions: the SQL code strings. If Expression instances are passed, they 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, *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Except:
1398    def except_(
1399        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1400    ) -> Except:
1401        """
1402        Builds an EXCEPT expression.
1403
1404        Example:
1405            >>> import sqlglot
1406            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1407            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1408
1409        Args:
1410            expressions: the SQL code strings.
1411                If `Expression` instance are passed, they will be used as-is.
1412            distinct: set the DISTINCT flag if and only if this is true.
1413            dialect: the dialect used to parse the input expression.
1414            opts: other options to use to parse the input expressions.
1415
1416        Returns:
1417            The new Except expression.
1418        """
1419        return except_(self, *expressions, 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:
  • expressions: the SQL code strings. If Expression instance are passed, they 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):
1422class UDTF(DerivedTable):
1423    @property
1424    def selects(self) -> t.List[Expression]:
1425        alias = self.args.get("alias")
1426        return alias.columns if alias else []
selects: List[Expression]
1423    @property
1424    def selects(self) -> t.List[Expression]:
1425        alias = self.args.get("alias")
1426        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1429class Cache(Expression):
1430    arg_types = {
1431        "this": True,
1432        "lazy": False,
1433        "options": False,
1434        "expression": False,
1435    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1438class Uncache(Expression):
1439    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1442class Refresh(Expression):
1443    pass
key = 'refresh'
class DDL(Expression):
1446class DDL(Expression):
1447    @property
1448    def ctes(self) -> t.List[CTE]:
1449        """Returns a list of all the CTEs attached to this statement."""
1450        with_ = self.args.get("with")
1451        return with_.expressions if with_ else []
1452
1453    @property
1454    def selects(self) -> t.List[Expression]:
1455        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1456        return self.expression.selects if isinstance(self.expression, Query) else []
1457
1458    @property
1459    def named_selects(self) -> t.List[str]:
1460        """
1461        If this statement contains a query (e.g. a CTAS), this returns the output
1462        names of the query's projections.
1463        """
1464        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1447    @property
1448    def ctes(self) -> t.List[CTE]:
1449        """Returns a list of all the CTEs attached to this statement."""
1450        with_ = self.args.get("with")
1451        return with_.expressions if with_ else []

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

selects: List[Expression]
1453    @property
1454    def selects(self) -> t.List[Expression]:
1455        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1456        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]
1458    @property
1459    def named_selects(self) -> t.List[str]:
1460        """
1461        If this statement contains a query (e.g. a CTAS), this returns the output
1462        names of the query's projections.
1463        """
1464        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 LockingStatement(Expression):
1468class LockingStatement(Expression):
1469    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'lockingstatement'
class DML(Expression):
1472class DML(Expression):
1473    def returning(
1474        self,
1475        expression: ExpOrStr,
1476        dialect: DialectType = None,
1477        copy: bool = True,
1478        **opts,
1479    ) -> "Self":
1480        """
1481        Set the RETURNING expression. Not supported by all dialects.
1482
1483        Example:
1484            >>> delete("tbl").returning("*", dialect="postgres").sql()
1485            'DELETE FROM tbl RETURNING *'
1486
1487        Args:
1488            expression: the SQL code strings to parse.
1489                If an `Expression` instance is passed, it will be used as-is.
1490            dialect: the dialect used to parse the input expressions.
1491            copy: if `False`, modify this expression instance in-place.
1492            opts: other options to use to parse the input expressions.
1493
1494        Returns:
1495            Delete: the modified expression.
1496        """
1497        return _apply_builder(
1498            expression=expression,
1499            instance=self,
1500            arg="returning",
1501            prefix="RETURNING",
1502            dialect=dialect,
1503            copy=copy,
1504            into=Returning,
1505            **opts,
1506        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> typing_extensions.Self:
1473    def returning(
1474        self,
1475        expression: ExpOrStr,
1476        dialect: DialectType = None,
1477        copy: bool = True,
1478        **opts,
1479    ) -> "Self":
1480        """
1481        Set the RETURNING expression. Not supported by all dialects.
1482
1483        Example:
1484            >>> delete("tbl").returning("*", dialect="postgres").sql()
1485            'DELETE FROM tbl RETURNING *'
1486
1487        Args:
1488            expression: the SQL code strings to parse.
1489                If an `Expression` instance is passed, it will be used as-is.
1490            dialect: the dialect used to parse the input expressions.
1491            copy: if `False`, modify this expression instance in-place.
1492            opts: other options to use to parse the input expressions.
1493
1494        Returns:
1495            Delete: the modified expression.
1496        """
1497        return _apply_builder(
1498            expression=expression,
1499            instance=self,
1500            arg="returning",
1501            prefix="RETURNING",
1502            dialect=dialect,
1503            copy=copy,
1504            into=Returning,
1505            **opts,
1506        )

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):
1509class Create(DDL):
1510    arg_types = {
1511        "with": False,
1512        "this": True,
1513        "kind": True,
1514        "expression": False,
1515        "exists": False,
1516        "properties": False,
1517        "replace": False,
1518        "refresh": False,
1519        "unique": False,
1520        "indexes": False,
1521        "no_schema_binding": False,
1522        "begin": False,
1523        "end": False,
1524        "clone": False,
1525        "concurrently": False,
1526        "clustered": False,
1527    }
1528
1529    @property
1530    def kind(self) -> t.Optional[str]:
1531        kind = self.args.get("kind")
1532        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]
1529    @property
1530    def kind(self) -> t.Optional[str]:
1531        kind = self.args.get("kind")
1532        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1535class SequenceProperties(Expression):
1536    arg_types = {
1537        "increment": False,
1538        "minvalue": False,
1539        "maxvalue": False,
1540        "cache": False,
1541        "start": False,
1542        "owned": False,
1543        "options": False,
1544    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1547class TruncateTable(Expression):
1548    arg_types = {
1549        "expressions": True,
1550        "is_database": False,
1551        "exists": False,
1552        "only": False,
1553        "cluster": False,
1554        "identity": False,
1555        "option": False,
1556        "partition": False,
1557    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1563class Clone(Expression):
1564    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1567class Describe(Expression):
1568    arg_types = {
1569        "this": True,
1570        "style": False,
1571        "kind": False,
1572        "expressions": False,
1573        "partition": False,
1574        "format": False,
1575    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1579class Attach(Expression):
1580    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1584class Detach(Expression):
1585    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Install(Expression):
1589class Install(Expression):
1590    arg_types = {"this": True, "from": False, "force": False}
arg_types = {'this': True, 'from': False, 'force': False}
key = 'install'
class Summarize(Expression):
1594class Summarize(Expression):
1595    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1598class Kill(Expression):
1599    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1602class Pragma(Expression):
1603    pass
key = 'pragma'
class Declare(Expression):
1606class Declare(Expression):
1607    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1610class DeclareItem(Expression):
1611    arg_types = {"this": True, "kind": False, "default": False}
arg_types = {'this': True, 'kind': False, 'default': False}
key = 'declareitem'
class Set(Expression):
1614class Set(Expression):
1615    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1618class Heredoc(Expression):
1619    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1622class SetItem(Expression):
1623    arg_types = {
1624        "this": False,
1625        "expressions": False,
1626        "kind": False,
1627        "collate": False,  # MySQL SET NAMES statement
1628        "global": False,
1629    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class QueryBand(Expression):
1632class QueryBand(Expression):
1633    arg_types = {"this": True, "scope": False, "update": False}
arg_types = {'this': True, 'scope': False, 'update': False}
key = 'queryband'
class Show(Expression):
1636class Show(Expression):
1637    arg_types = {
1638        "this": True,
1639        "history": False,
1640        "terse": False,
1641        "target": False,
1642        "offset": False,
1643        "starts_with": False,
1644        "limit": False,
1645        "from": False,
1646        "like": False,
1647        "where": False,
1648        "db": False,
1649        "scope": False,
1650        "scope_kind": False,
1651        "full": False,
1652        "mutex": False,
1653        "query": False,
1654        "channel": False,
1655        "global": False,
1656        "log": False,
1657        "position": False,
1658        "types": False,
1659        "privileges": False,
1660        "for_table": False,
1661        "for_group": False,
1662        "for_user": False,
1663        "for_role": False,
1664        "into_outfile": False,
1665        "json": False,
1666    }
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, 'privileges': False, 'for_table': False, 'for_group': False, 'for_user': False, 'for_role': False, 'into_outfile': False, 'json': False}
key = 'show'
class UserDefinedFunction(Expression):
1669class UserDefinedFunction(Expression):
1670    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1673class CharacterSet(Expression):
1674    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class RecursiveWithSearch(Expression):
1677class RecursiveWithSearch(Expression):
1678    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
arg_types = {'kind': True, 'this': True, 'expression': True, 'using': False}
key = 'recursivewithsearch'
class With(Expression):
1681class With(Expression):
1682    arg_types = {"expressions": True, "recursive": False, "search": False}
1683
1684    @property
1685    def recursive(self) -> bool:
1686        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1684    @property
1685    def recursive(self) -> bool:
1686        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1689class WithinGroup(Expression):
1690    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1695class CTE(DerivedTable):
1696    arg_types = {
1697        "this": True,
1698        "alias": True,
1699        "scalar": False,
1700        "materialized": False,
1701    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1704class ProjectionDef(Expression):
1705    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1708class TableAlias(Expression):
1709    arg_types = {"this": False, "columns": False}
1710
1711    @property
1712    def columns(self):
1713        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1711    @property
1712    def columns(self):
1713        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1716class BitString(Condition):
1717    pass
key = 'bitstring'
class HexString(Condition):
1720class HexString(Condition):
1721    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
class ByteString(Condition):
1724class ByteString(Condition):
1725    pass
key = 'bytestring'
class RawString(Condition):
1728class RawString(Condition):
1729    pass
key = 'rawstring'
class UnicodeString(Condition):
1732class UnicodeString(Condition):
1733    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1736class Column(Condition):
1737    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1738
1739    @property
1740    def table(self) -> str:
1741        return self.text("table")
1742
1743    @property
1744    def db(self) -> str:
1745        return self.text("db")
1746
1747    @property
1748    def catalog(self) -> str:
1749        return self.text("catalog")
1750
1751    @property
1752    def output_name(self) -> str:
1753        return self.name
1754
1755    @property
1756    def parts(self) -> t.List[Identifier]:
1757        """Return the parts of a column in order catalog, db, table, name."""
1758        return [
1759            t.cast(Identifier, self.args[part])
1760            for part in ("catalog", "db", "table", "this")
1761            if self.args.get(part)
1762        ]
1763
1764    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1765        """Converts the column into a dot expression."""
1766        parts = self.parts
1767        parent = self.parent
1768
1769        if include_dots:
1770            while isinstance(parent, Dot):
1771                parts.append(parent.expression)
1772                parent = parent.parent
1773
1774        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
1739    @property
1740    def table(self) -> str:
1741        return self.text("table")
db: str
1743    @property
1744    def db(self) -> str:
1745        return self.text("db")
catalog: str
1747    @property
1748    def catalog(self) -> str:
1749        return self.text("catalog")
output_name: str
1751    @property
1752    def output_name(self) -> str:
1753        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]
1755    @property
1756    def parts(self) -> t.List[Identifier]:
1757        """Return the parts of a column in order catalog, db, table, name."""
1758        return [
1759            t.cast(Identifier, self.args[part])
1760            for part in ("catalog", "db", "table", "this")
1761            if self.args.get(part)
1762        ]

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

def to_dot( self, include_dots: bool = True) -> Dot | Identifier:
1764    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1765        """Converts the column into a dot expression."""
1766        parts = self.parts
1767        parent = self.parent
1768
1769        if include_dots:
1770            while isinstance(parent, Dot):
1771                parts.append(parent.expression)
1772                parent = parent.parent
1773
1774        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1777class ColumnPosition(Expression):
1778    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1781class ColumnDef(Expression):
1782    arg_types = {
1783        "this": True,
1784        "kind": False,
1785        "constraints": False,
1786        "exists": False,
1787        "position": False,
1788        "default": False,
1789        "output": False,
1790    }
1791
1792    @property
1793    def constraints(self) -> t.List[ColumnConstraint]:
1794        return self.args.get("constraints") or []
1795
1796    @property
1797    def kind(self) -> t.Optional[DataType]:
1798        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1792    @property
1793    def constraints(self) -> t.List[ColumnConstraint]:
1794        return self.args.get("constraints") or []
kind: Optional[DataType]
1796    @property
1797    def kind(self) -> t.Optional[DataType]:
1798        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1801class AlterColumn(Expression):
1802    arg_types = {
1803        "this": True,
1804        "dtype": False,
1805        "collate": False,
1806        "using": False,
1807        "default": False,
1808        "drop": False,
1809        "comment": False,
1810        "allow_null": False,
1811        "visible": False,
1812    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False, 'visible': False}
key = 'altercolumn'
class AlterIndex(Expression):
1816class AlterIndex(Expression):
1817    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1821class AlterDistStyle(Expression):
1822    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1825class AlterSortKey(Expression):
1826    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1829class AlterSet(Expression):
1830    arg_types = {
1831        "expressions": False,
1832        "option": False,
1833        "tablespace": False,
1834        "access_method": False,
1835        "file_format": False,
1836        "copy_options": False,
1837        "tag": False,
1838        "location": False,
1839        "serde": False,
1840    }
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):
1843class RenameColumn(Expression):
1844    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1847class AlterRename(Expression):
1848    pass
key = 'alterrename'
class SwapTable(Expression):
1851class SwapTable(Expression):
1852    pass
key = 'swaptable'
class Comment(Expression):
1855class Comment(Expression):
1856    arg_types = {
1857        "this": True,
1858        "kind": True,
1859        "expression": True,
1860        "exists": False,
1861        "materialized": False,
1862    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1865class Comprehension(Expression):
1866    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):
1870class MergeTreeTTLAction(Expression):
1871    arg_types = {
1872        "this": True,
1873        "delete": False,
1874        "recompress": False,
1875        "to_disk": False,
1876        "to_volume": False,
1877    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1881class MergeTreeTTL(Expression):
1882    arg_types = {
1883        "expressions": True,
1884        "where": False,
1885        "group": False,
1886        "aggregates": False,
1887    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1891class IndexConstraintOption(Expression):
1892    arg_types = {
1893        "key_block_size": False,
1894        "using": False,
1895        "parser": False,
1896        "comment": False,
1897        "visible": False,
1898        "engine_attr": False,
1899        "secondary_engine_attr": False,
1900    }
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):
1903class ColumnConstraint(Expression):
1904    arg_types = {"this": False, "kind": True}
1905
1906    @property
1907    def kind(self) -> ColumnConstraintKind:
1908        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1906    @property
1907    def kind(self) -> ColumnConstraintKind:
1908        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1911class ColumnConstraintKind(Expression):
1912    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1915class AutoIncrementColumnConstraint(ColumnConstraintKind):
1916    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1919class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1920    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1923class CaseSpecificColumnConstraint(ColumnConstraintKind):
1924    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1927class CharacterSetColumnConstraint(ColumnConstraintKind):
1928    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1931class CheckColumnConstraint(ColumnConstraintKind):
1932    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1935class ClusteredColumnConstraint(ColumnConstraintKind):
1936    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1939class CollateColumnConstraint(ColumnConstraintKind):
1940    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1943class CommentColumnConstraint(ColumnConstraintKind):
1944    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1947class CompressColumnConstraint(ColumnConstraintKind):
1948    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1951class DateFormatColumnConstraint(ColumnConstraintKind):
1952    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1955class DefaultColumnConstraint(ColumnConstraintKind):
1956    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1959class EncodeColumnConstraint(ColumnConstraintKind):
1960    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1964class ExcludeColumnConstraint(ColumnConstraintKind):
1965    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1968class EphemeralColumnConstraint(ColumnConstraintKind):
1969    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1972class WithOperator(Expression):
1973    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1976class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1977    # this: True -> ALWAYS, this: False -> BY DEFAULT
1978    arg_types = {
1979        "this": False,
1980        "expression": False,
1981        "on_null": False,
1982        "start": False,
1983        "increment": False,
1984        "minvalue": False,
1985        "maxvalue": False,
1986        "cycle": False,
1987        "order": False,
1988    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False, 'order': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1991class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1992    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1997class IndexColumnConstraint(ColumnConstraintKind):
1998    arg_types = {
1999        "this": False,
2000        "expressions": False,
2001        "kind": False,
2002        "index_type": False,
2003        "options": False,
2004        "expression": False,  # Clickhouse
2005        "granularity": False,
2006    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
2009class InlineLengthColumnConstraint(ColumnConstraintKind):
2010    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
2013class NonClusteredColumnConstraint(ColumnConstraintKind):
2014    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
2017class NotForReplicationColumnConstraint(ColumnConstraintKind):
2018    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
2022class MaskingPolicyColumnConstraint(ColumnConstraintKind):
2023    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
2026class NotNullColumnConstraint(ColumnConstraintKind):
2027    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
2031class OnUpdateColumnConstraint(ColumnConstraintKind):
2032    pass
key = 'onupdatecolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2035class PrimaryKeyColumnConstraint(ColumnConstraintKind):
2036    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
2039class TitleColumnConstraint(ColumnConstraintKind):
2040    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
2043class UniqueColumnConstraint(ColumnConstraintKind):
2044    arg_types = {
2045        "this": False,
2046        "index_type": False,
2047        "on_conflict": False,
2048        "nulls": False,
2049        "options": False,
2050    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
2053class UppercaseColumnConstraint(ColumnConstraintKind):
2054    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
2058class WatermarkColumnConstraint(Expression):
2059    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
2062class PathColumnConstraint(ColumnConstraintKind):
2063    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2067class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
2068    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
2073class ComputedColumnConstraint(ColumnConstraintKind):
2074    arg_types = {"this": True, "persisted": False, "not_null": False, "data_type": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False, 'data_type': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
2077class Constraint(Expression):
2078    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
2081class Delete(DML):
2082    arg_types = {
2083        "with": False,
2084        "this": False,
2085        "using": False,
2086        "where": False,
2087        "returning": False,
2088        "limit": False,
2089        "tables": False,  # Multiple-Table Syntax (MySQL)
2090        "cluster": False,  # Clickhouse
2091    }
2092
2093    def delete(
2094        self,
2095        table: ExpOrStr,
2096        dialect: DialectType = None,
2097        copy: bool = True,
2098        **opts,
2099    ) -> Delete:
2100        """
2101        Create a DELETE expression or replace the table on an existing DELETE expression.
2102
2103        Example:
2104            >>> delete("tbl").sql()
2105            'DELETE FROM tbl'
2106
2107        Args:
2108            table: the table from which to delete.
2109            dialect: the dialect used to parse the input expression.
2110            copy: if `False`, modify this expression instance in-place.
2111            opts: other options to use to parse the input expressions.
2112
2113        Returns:
2114            Delete: the modified expression.
2115        """
2116        return _apply_builder(
2117            expression=table,
2118            instance=self,
2119            arg="this",
2120            dialect=dialect,
2121            into=Table,
2122            copy=copy,
2123            **opts,
2124        )
2125
2126    def where(
2127        self,
2128        *expressions: t.Optional[ExpOrStr],
2129        append: bool = True,
2130        dialect: DialectType = None,
2131        copy: bool = True,
2132        **opts,
2133    ) -> Delete:
2134        """
2135        Append to or set the WHERE expressions.
2136
2137        Example:
2138            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2139            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2140
2141        Args:
2142            *expressions: the SQL code strings to parse.
2143                If an `Expression` instance is passed, it will be used as-is.
2144                Multiple expressions are combined with an AND operator.
2145            append: if `True`, AND the new expressions to any existing expression.
2146                Otherwise, this resets the expression.
2147            dialect: the dialect used to parse the input expressions.
2148            copy: if `False`, modify this expression instance in-place.
2149            opts: other options to use to parse the input expressions.
2150
2151        Returns:
2152            Delete: the modified expression.
2153        """
2154        return _apply_conjunction_builder(
2155            *expressions,
2156            instance=self,
2157            arg="where",
2158            append=append,
2159            into=Where,
2160            dialect=dialect,
2161            copy=copy,
2162            **opts,
2163        )
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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2093    def delete(
2094        self,
2095        table: ExpOrStr,
2096        dialect: DialectType = None,
2097        copy: bool = True,
2098        **opts,
2099    ) -> Delete:
2100        """
2101        Create a DELETE expression or replace the table on an existing DELETE expression.
2102
2103        Example:
2104            >>> delete("tbl").sql()
2105            'DELETE FROM tbl'
2106
2107        Args:
2108            table: the table from which to delete.
2109            dialect: the dialect used to parse the input expression.
2110            copy: if `False`, modify this expression instance in-place.
2111            opts: other options to use to parse the input expressions.
2112
2113        Returns:
2114            Delete: the modified expression.
2115        """
2116        return _apply_builder(
2117            expression=table,
2118            instance=self,
2119            arg="this",
2120            dialect=dialect,
2121            into=Table,
2122            copy=copy,
2123            **opts,
2124        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2126    def where(
2127        self,
2128        *expressions: t.Optional[ExpOrStr],
2129        append: bool = True,
2130        dialect: DialectType = None,
2131        copy: bool = True,
2132        **opts,
2133    ) -> Delete:
2134        """
2135        Append to or set the WHERE expressions.
2136
2137        Example:
2138            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2139            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2140
2141        Args:
2142            *expressions: the SQL code strings to parse.
2143                If an `Expression` instance is passed, it will be used as-is.
2144                Multiple expressions are combined with an AND operator.
2145            append: if `True`, AND the new expressions to any existing expression.
2146                Otherwise, this resets the expression.
2147            dialect: the dialect used to parse the input expressions.
2148            copy: if `False`, modify this expression instance in-place.
2149            opts: other options to use to parse the input expressions.
2150
2151        Returns:
2152            Delete: the modified expression.
2153        """
2154        return _apply_conjunction_builder(
2155            *expressions,
2156            instance=self,
2157            arg="where",
2158            append=append,
2159            into=Where,
2160            dialect=dialect,
2161            copy=copy,
2162            **opts,
2163        )

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):
2166class Drop(Expression):
2167    arg_types = {
2168        "this": False,
2169        "kind": False,
2170        "expressions": False,
2171        "exists": False,
2172        "temporary": False,
2173        "materialized": False,
2174        "cascade": False,
2175        "constraints": False,
2176        "purge": False,
2177        "cluster": False,
2178        "concurrently": False,
2179    }
2180
2181    @property
2182    def kind(self) -> t.Optional[str]:
2183        kind = self.args.get("kind")
2184        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]
2181    @property
2182    def kind(self) -> t.Optional[str]:
2183        kind = self.args.get("kind")
2184        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2188class Export(Expression):
2189    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2192class Filter(Expression):
2193    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2196class Check(Expression):
2197    pass
key = 'check'
class Changes(Expression):
2200class Changes(Expression):
2201    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2205class Connect(Expression):
2206    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2209class CopyParameter(Expression):
2210    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2213class Copy(DML):
2214    arg_types = {
2215        "this": True,
2216        "kind": True,
2217        "files": False,
2218        "credentials": False,
2219        "format": False,
2220        "params": False,
2221    }
arg_types = {'this': True, 'kind': True, 'files': False, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2224class Credentials(Expression):
2225    arg_types = {
2226        "credentials": False,
2227        "encryption": False,
2228        "storage": False,
2229        "iam_role": False,
2230        "region": False,
2231    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2234class Prior(Expression):
2235    pass
key = 'prior'
class Directory(Expression):
2238class Directory(Expression):
2239    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2240    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2243class ForeignKey(Expression):
2244    arg_types = {
2245        "expressions": False,
2246        "reference": False,
2247        "delete": False,
2248        "update": False,
2249        "options": False,
2250    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False, 'options': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2253class ColumnPrefix(Expression):
2254    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2257class PrimaryKey(Expression):
2258    arg_types = {"expressions": True, "options": False, "include": False}
arg_types = {'expressions': True, 'options': False, 'include': False}
key = 'primarykey'
class Into(Expression):
2263class Into(Expression):
2264    arg_types = {
2265        "this": False,
2266        "temporary": False,
2267        "unlogged": False,
2268        "bulk_collect": False,
2269        "expressions": False,
2270    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2273class From(Expression):
2274    @property
2275    def name(self) -> str:
2276        return self.this.name
2277
2278    @property
2279    def alias_or_name(self) -> str:
2280        return self.this.alias_or_name
name: str
2274    @property
2275    def name(self) -> str:
2276        return self.this.name
alias_or_name: str
2278    @property
2279    def alias_or_name(self) -> str:
2280        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2283class Having(Expression):
2284    pass
key = 'having'
class Hint(Expression):
2287class Hint(Expression):
2288    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2291class JoinHint(Expression):
2292    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2295class Identifier(Expression):
2296    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2297
2298    @property
2299    def quoted(self) -> bool:
2300        return bool(self.args.get("quoted"))
2301
2302    @property
2303    def hashable_args(self) -> t.Any:
2304        return (self.this, self.quoted)
2305
2306    @property
2307    def output_name(self) -> str:
2308        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2298    @property
2299    def quoted(self) -> bool:
2300        return bool(self.args.get("quoted"))
hashable_args: Any
2302    @property
2303    def hashable_args(self) -> t.Any:
2304        return (self.this, self.quoted)
output_name: str
2306    @property
2307    def output_name(self) -> str:
2308        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):
2312class Opclass(Expression):
2313    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2316class Index(Expression):
2317    arg_types = {
2318        "this": False,
2319        "table": False,
2320        "unique": False,
2321        "primary": False,
2322        "amp": False,  # teradata
2323        "params": False,
2324    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2327class IndexParameters(Expression):
2328    arg_types = {
2329        "using": False,
2330        "include": False,
2331        "columns": False,
2332        "with_storage": False,
2333        "partition_by": False,
2334        "tablespace": False,
2335        "where": False,
2336        "on": False,
2337    }
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):
2340class Insert(DDL, DML):
2341    arg_types = {
2342        "hint": False,
2343        "with": False,
2344        "is_function": False,
2345        "this": False,
2346        "expression": False,
2347        "conflict": False,
2348        "returning": False,
2349        "overwrite": False,
2350        "exists": False,
2351        "alternative": False,
2352        "where": False,
2353        "ignore": False,
2354        "by_name": False,
2355        "stored": False,
2356        "partition": False,
2357        "settings": False,
2358        "source": False,
2359    }
2360
2361    def with_(
2362        self,
2363        alias: ExpOrStr,
2364        as_: ExpOrStr,
2365        recursive: t.Optional[bool] = None,
2366        materialized: t.Optional[bool] = None,
2367        append: bool = True,
2368        dialect: DialectType = None,
2369        copy: bool = True,
2370        **opts,
2371    ) -> Insert:
2372        """
2373        Append to or set the common table expressions.
2374
2375        Example:
2376            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2377            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2378
2379        Args:
2380            alias: the SQL code string to parse as the table name.
2381                If an `Expression` instance is passed, this is used as-is.
2382            as_: the SQL code string to parse as the table expression.
2383                If an `Expression` instance is passed, it will be used as-is.
2384            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2385            materialized: set the MATERIALIZED part of the expression.
2386            append: if `True`, add to any existing expressions.
2387                Otherwise, this resets the expressions.
2388            dialect: the dialect used to parse the input expression.
2389            copy: if `False`, modify this expression instance in-place.
2390            opts: other options to use to parse the input expressions.
2391
2392        Returns:
2393            The modified expression.
2394        """
2395        return _apply_cte_builder(
2396            self,
2397            alias,
2398            as_,
2399            recursive=recursive,
2400            materialized=materialized,
2401            append=append,
2402            dialect=dialect,
2403            copy=copy,
2404            **opts,
2405        )
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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2361    def with_(
2362        self,
2363        alias: ExpOrStr,
2364        as_: ExpOrStr,
2365        recursive: t.Optional[bool] = None,
2366        materialized: t.Optional[bool] = None,
2367        append: bool = True,
2368        dialect: DialectType = None,
2369        copy: bool = True,
2370        **opts,
2371    ) -> Insert:
2372        """
2373        Append to or set the common table expressions.
2374
2375        Example:
2376            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2377            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2378
2379        Args:
2380            alias: the SQL code string to parse as the table name.
2381                If an `Expression` instance is passed, this is used as-is.
2382            as_: the SQL code string to parse as the table expression.
2383                If an `Expression` instance is passed, it will be used as-is.
2384            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2385            materialized: set the MATERIALIZED part of the expression.
2386            append: if `True`, add to any existing expressions.
2387                Otherwise, this resets the expressions.
2388            dialect: the dialect used to parse the input expression.
2389            copy: if `False`, modify this expression instance in-place.
2390            opts: other options to use to parse the input expressions.
2391
2392        Returns:
2393            The modified expression.
2394        """
2395        return _apply_cte_builder(
2396            self,
2397            alias,
2398            as_,
2399            recursive=recursive,
2400            materialized=materialized,
2401            append=append,
2402            dialect=dialect,
2403            copy=copy,
2404            **opts,
2405        )

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):
2408class ConditionalInsert(Expression):
2409    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2412class MultitableInserts(Expression):
2413    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2416class OnConflict(Expression):
2417    arg_types = {
2418        "duplicate": False,
2419        "expressions": False,
2420        "action": False,
2421        "conflict_keys": False,
2422        "constraint": False,
2423        "where": False,
2424    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2427class OnCondition(Expression):
2428    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2431class Returning(Expression):
2432    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2436class Introducer(Expression):
2437    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2441class National(Expression):
2442    pass
key = 'national'
class LoadData(Expression):
2445class LoadData(Expression):
2446    arg_types = {
2447        "this": True,
2448        "local": False,
2449        "overwrite": False,
2450        "inpath": True,
2451        "partition": False,
2452        "input_format": False,
2453        "serde": False,
2454    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2457class Partition(Expression):
2458    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2461class PartitionRange(Expression):
2462    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'partitionrange'
class PartitionId(Expression):
2466class PartitionId(Expression):
2467    pass
key = 'partitionid'
class Fetch(Expression):
2470class Fetch(Expression):
2471    arg_types = {
2472        "direction": False,
2473        "count": False,
2474        "limit_options": False,
2475    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2478class Grant(Expression):
2479    arg_types = {
2480        "privileges": True,
2481        "kind": False,
2482        "securable": True,
2483        "principals": True,
2484        "grant_option": False,
2485    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Revoke(Expression):
2488class Revoke(Expression):
2489    arg_types = {**Grant.arg_types, "cascade": False}
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False, 'cascade': False}
key = 'revoke'
class Group(Expression):
2492class Group(Expression):
2493    arg_types = {
2494        "expressions": False,
2495        "grouping_sets": False,
2496        "cube": False,
2497        "rollup": False,
2498        "totals": False,
2499        "all": False,
2500    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2503class Cube(Expression):
2504    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2507class Rollup(Expression):
2508    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2511class GroupingSets(Expression):
2512    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2515class Lambda(Expression):
2516    arg_types = {"this": True, "expressions": True, "colon": False}
arg_types = {'this': True, 'expressions': True, 'colon': False}
key = 'lambda'
class Limit(Expression):
2519class Limit(Expression):
2520    arg_types = {
2521        "this": False,
2522        "expression": True,
2523        "offset": False,
2524        "limit_options": False,
2525        "expressions": False,
2526    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2529class LimitOptions(Expression):
2530    arg_types = {
2531        "percent": False,
2532        "rows": False,
2533        "with_ties": False,
2534    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2537class Literal(Condition):
2538    arg_types = {"this": True, "is_string": True}
2539
2540    @property
2541    def hashable_args(self) -> t.Any:
2542        return (self.this, self.args.get("is_string"))
2543
2544    @classmethod
2545    def number(cls, number) -> Literal:
2546        return cls(this=str(number), is_string=False)
2547
2548    @classmethod
2549    def string(cls, string) -> Literal:
2550        return cls(this=str(string), is_string=True)
2551
2552    @property
2553    def output_name(self) -> str:
2554        return self.name
2555
2556    def to_py(self) -> int | str | Decimal:
2557        if self.is_number:
2558            try:
2559                return int(self.this)
2560            except ValueError:
2561                return Decimal(self.this)
2562        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2540    @property
2541    def hashable_args(self) -> t.Any:
2542        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2544    @classmethod
2545    def number(cls, number) -> Literal:
2546        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2548    @classmethod
2549    def string(cls, string) -> Literal:
2550        return cls(this=str(string), is_string=True)
output_name: str
2552    @property
2553    def output_name(self) -> str:
2554        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:
2556    def to_py(self) -> int | str | Decimal:
2557        if self.is_number:
2558            try:
2559                return int(self.this)
2560            except ValueError:
2561                return Decimal(self.this)
2562        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2565class Join(Expression):
2566    arg_types = {
2567        "this": True,
2568        "on": False,
2569        "side": False,
2570        "kind": False,
2571        "using": False,
2572        "method": False,
2573        "global": False,
2574        "hint": False,
2575        "match_condition": False,  # Snowflake
2576        "expressions": False,
2577        "pivots": False,
2578    }
2579
2580    @property
2581    def method(self) -> str:
2582        return self.text("method").upper()
2583
2584    @property
2585    def kind(self) -> str:
2586        return self.text("kind").upper()
2587
2588    @property
2589    def side(self) -> str:
2590        return self.text("side").upper()
2591
2592    @property
2593    def hint(self) -> str:
2594        return self.text("hint").upper()
2595
2596    @property
2597    def alias_or_name(self) -> str:
2598        return self.this.alias_or_name
2599
2600    @property
2601    def is_semi_or_anti_join(self) -> bool:
2602        return self.kind in ("SEMI", "ANTI")
2603
2604    def on(
2605        self,
2606        *expressions: t.Optional[ExpOrStr],
2607        append: bool = True,
2608        dialect: DialectType = None,
2609        copy: bool = True,
2610        **opts,
2611    ) -> Join:
2612        """
2613        Append to or set the ON expressions.
2614
2615        Example:
2616            >>> import sqlglot
2617            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2618            'JOIN x ON y = 1'
2619
2620        Args:
2621            *expressions: the SQL code strings to parse.
2622                If an `Expression` instance is passed, it will be used as-is.
2623                Multiple expressions are combined with an AND operator.
2624            append: if `True`, AND the new expressions to any existing expression.
2625                Otherwise, this resets the expression.
2626            dialect: the dialect used to parse the input expressions.
2627            copy: if `False`, modify this expression instance in-place.
2628            opts: other options to use to parse the input expressions.
2629
2630        Returns:
2631            The modified Join expression.
2632        """
2633        join = _apply_conjunction_builder(
2634            *expressions,
2635            instance=self,
2636            arg="on",
2637            append=append,
2638            dialect=dialect,
2639            copy=copy,
2640            **opts,
2641        )
2642
2643        if join.kind == "CROSS":
2644            join.set("kind", None)
2645
2646        return join
2647
2648    def using(
2649        self,
2650        *expressions: t.Optional[ExpOrStr],
2651        append: bool = True,
2652        dialect: DialectType = None,
2653        copy: bool = True,
2654        **opts,
2655    ) -> Join:
2656        """
2657        Append to or set the USING expressions.
2658
2659        Example:
2660            >>> import sqlglot
2661            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2662            'JOIN x USING (foo, bla)'
2663
2664        Args:
2665            *expressions: the SQL code strings to parse.
2666                If an `Expression` instance is passed, it will be used as-is.
2667            append: if `True`, concatenate the new expressions to the existing "using" list.
2668                Otherwise, this resets the expression.
2669            dialect: the dialect used to parse the input expressions.
2670            copy: if `False`, modify this expression instance in-place.
2671            opts: other options to use to parse the input expressions.
2672
2673        Returns:
2674            The modified Join expression.
2675        """
2676        join = _apply_list_builder(
2677            *expressions,
2678            instance=self,
2679            arg="using",
2680            append=append,
2681            dialect=dialect,
2682            copy=copy,
2683            **opts,
2684        )
2685
2686        if join.kind == "CROSS":
2687            join.set("kind", None)
2688
2689        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global': False, 'hint': False, 'match_condition': False, 'expressions': False, 'pivots': False}
method: str
2580    @property
2581    def method(self) -> str:
2582        return self.text("method").upper()
kind: str
2584    @property
2585    def kind(self) -> str:
2586        return self.text("kind").upper()
side: str
2588    @property
2589    def side(self) -> str:
2590        return self.text("side").upper()
hint: str
2592    @property
2593    def hint(self) -> str:
2594        return self.text("hint").upper()
alias_or_name: str
2596    @property
2597    def alias_or_name(self) -> str:
2598        return self.this.alias_or_name
is_semi_or_anti_join: bool
2600    @property
2601    def is_semi_or_anti_join(self) -> bool:
2602        return self.kind in ("SEMI", "ANTI")
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2604    def on(
2605        self,
2606        *expressions: t.Optional[ExpOrStr],
2607        append: bool = True,
2608        dialect: DialectType = None,
2609        copy: bool = True,
2610        **opts,
2611    ) -> Join:
2612        """
2613        Append to or set the ON expressions.
2614
2615        Example:
2616            >>> import sqlglot
2617            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2618            'JOIN x ON y = 1'
2619
2620        Args:
2621            *expressions: the SQL code strings to parse.
2622                If an `Expression` instance is passed, it will be used as-is.
2623                Multiple expressions are combined with an AND operator.
2624            append: if `True`, AND the new expressions to any existing expression.
2625                Otherwise, this resets the expression.
2626            dialect: the dialect used to parse the input expressions.
2627            copy: if `False`, modify this expression instance in-place.
2628            opts: other options to use to parse the input expressions.
2629
2630        Returns:
2631            The modified Join expression.
2632        """
2633        join = _apply_conjunction_builder(
2634            *expressions,
2635            instance=self,
2636            arg="on",
2637            append=append,
2638            dialect=dialect,
2639            copy=copy,
2640            **opts,
2641        )
2642
2643        if join.kind == "CROSS":
2644            join.set("kind", None)
2645
2646        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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2648    def using(
2649        self,
2650        *expressions: t.Optional[ExpOrStr],
2651        append: bool = True,
2652        dialect: DialectType = None,
2653        copy: bool = True,
2654        **opts,
2655    ) -> Join:
2656        """
2657        Append to or set the USING expressions.
2658
2659        Example:
2660            >>> import sqlglot
2661            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2662            'JOIN x USING (foo, bla)'
2663
2664        Args:
2665            *expressions: the SQL code strings to parse.
2666                If an `Expression` instance is passed, it will be used as-is.
2667            append: if `True`, concatenate the new expressions to the existing "using" list.
2668                Otherwise, this resets the expression.
2669            dialect: the dialect used to parse the input expressions.
2670            copy: if `False`, modify this expression instance in-place.
2671            opts: other options to use to parse the input expressions.
2672
2673        Returns:
2674            The modified Join expression.
2675        """
2676        join = _apply_list_builder(
2677            *expressions,
2678            instance=self,
2679            arg="using",
2680            append=append,
2681            dialect=dialect,
2682            copy=copy,
2683            **opts,
2684        )
2685
2686        if join.kind == "CROSS":
2687            join.set("kind", None)
2688
2689        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):
2692class Lateral(UDTF):
2693    arg_types = {
2694        "this": True,
2695        "view": False,
2696        "outer": False,
2697        "alias": False,
2698        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2699        "ordinality": False,
2700    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
class TableFromRows(UDTF):
2705class TableFromRows(UDTF):
2706    arg_types = {
2707        "this": True,
2708        "alias": False,
2709        "joins": False,
2710        "pivots": False,
2711        "sample": False,
2712    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
class MatchRecognizeMeasure(Expression):
2715class MatchRecognizeMeasure(Expression):
2716    arg_types = {
2717        "this": True,
2718        "window_frame": False,
2719    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2722class MatchRecognize(Expression):
2723    arg_types = {
2724        "partition_by": False,
2725        "order": False,
2726        "measures": False,
2727        "rows": False,
2728        "after": False,
2729        "pattern": False,
2730        "define": False,
2731        "alias": False,
2732    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2737class Final(Expression):
2738    pass
key = 'final'
class Offset(Expression):
2741class Offset(Expression):
2742    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2745class Order(Expression):
2746    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2750class WithFill(Expression):
2751    arg_types = {
2752        "from": False,
2753        "to": False,
2754        "step": False,
2755        "interpolate": False,
2756    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2761class Cluster(Order):
2762    pass
key = 'cluster'
class Distribute(Order):
2765class Distribute(Order):
2766    pass
key = 'distribute'
class Sort(Order):
2769class Sort(Order):
2770    pass
key = 'sort'
class Ordered(Expression):
2773class Ordered(Expression):
2774    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2775
2776    @property
2777    def name(self) -> str:
2778        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2776    @property
2777    def name(self) -> str:
2778        return self.this.name
key = 'ordered'
class Property(Expression):
2781class Property(Expression):
2782    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2785class GrantPrivilege(Expression):
2786    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2789class GrantPrincipal(Expression):
2790    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2793class AllowedValuesProperty(Expression):
2794    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2797class AlgorithmProperty(Property):
2798    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2801class AutoIncrementProperty(Property):
2802    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2806class AutoRefreshProperty(Property):
2807    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2810class BackupProperty(Property):
2811    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BuildProperty(Property):
2815class BuildProperty(Property):
2816    arg_types = {"this": True}
arg_types = {'this': True}
key = 'buildproperty'
class BlockCompressionProperty(Property):
2819class BlockCompressionProperty(Property):
2820    arg_types = {
2821        "autotemp": False,
2822        "always": False,
2823        "default": False,
2824        "manual": False,
2825        "never": False,
2826    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2829class CharacterSetProperty(Property):
2830    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2833class ChecksumProperty(Property):
2834    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2837class CollateProperty(Property):
2838    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2841class CopyGrantsProperty(Property):
2842    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2845class DataBlocksizeProperty(Property):
2846    arg_types = {
2847        "size": False,
2848        "units": False,
2849        "minimum": False,
2850        "maximum": False,
2851        "default": False,
2852    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2855class DataDeletionProperty(Property):
2856    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):
2859class DefinerProperty(Property):
2860    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2863class DistKeyProperty(Property):
2864    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2869class DistributedByProperty(Property):
2870    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):
2873class DistStyleProperty(Property):
2874    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2877class DuplicateKeyProperty(Property):
2878    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2881class EngineProperty(Property):
2882    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2885class HeapProperty(Property):
2886    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2889class ToTableProperty(Property):
2890    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2893class ExecuteAsProperty(Property):
2894    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2897class ExternalProperty(Property):
2898    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2901class FallbackProperty(Property):
2902    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2906class FileFormatProperty(Property):
2907    arg_types = {"this": False, "expressions": False, "hive_format": False}
arg_types = {'this': False, 'expressions': False, 'hive_format': False}
key = 'fileformatproperty'
class CredentialsProperty(Property):
2910class CredentialsProperty(Property):
2911    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'credentialsproperty'
class FreespaceProperty(Property):
2914class FreespaceProperty(Property):
2915    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2918class GlobalProperty(Property):
2919    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2922class IcebergProperty(Property):
2923    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2926class InheritsProperty(Property):
2927    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2930class InputModelProperty(Property):
2931    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2934class OutputModelProperty(Property):
2935    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2938class IsolatedLoadingProperty(Property):
2939    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2942class JournalProperty(Property):
2943    arg_types = {
2944        "no": False,
2945        "dual": False,
2946        "before": False,
2947        "local": False,
2948        "after": False,
2949    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2952class LanguageProperty(Property):
2953    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class EnviromentProperty(Property):
2956class EnviromentProperty(Property):
2957    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'enviromentproperty'
class ClusteredByProperty(Property):
2961class ClusteredByProperty(Property):
2962    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2965class DictProperty(Property):
2966    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2969class DictSubProperty(Property):
2970    pass
key = 'dictsubproperty'
class DictRange(Property):
2973class DictRange(Property):
2974    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2977class DynamicProperty(Property):
2978    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2983class OnCluster(Property):
2984    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2988class EmptyProperty(Property):
2989    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2992class LikeProperty(Property):
2993    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2996class LocationProperty(Property):
2997    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
3000class LockProperty(Property):
3001    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
3004class LockingProperty(Property):
3005    arg_types = {
3006        "this": False,
3007        "kind": True,
3008        "for_or_in": False,
3009        "lock_type": True,
3010        "override": False,
3011    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
3014class LogProperty(Property):
3015    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
3018class MaterializedProperty(Property):
3019    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
3022class MergeBlockRatioProperty(Property):
3023    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):
3026class NoPrimaryIndexProperty(Property):
3027    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
3030class OnProperty(Property):
3031    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
3034class OnCommitProperty(Property):
3035    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
3038class PartitionedByProperty(Property):
3039    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionedByBucket(Property):
3042class PartitionedByBucket(Property):
3043    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedbybucket'
class PartitionByTruncate(Property):
3046class PartitionByTruncate(Property):
3047    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionbytruncate'
class PartitionByRangeProperty(Property):
3051class PartitionByRangeProperty(Property):
3052    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
3056class PartitionByRangePropertyDynamic(Expression):
3057    arg_types = {"this": False, "start": True, "end": True, "every": True}
arg_types = {'this': False, 'start': True, 'end': True, 'every': True}
key = 'partitionbyrangepropertydynamic'
class PartitionByListProperty(Property):
3061class PartitionByListProperty(Property):
3062    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbylistproperty'
class PartitionList(Expression):
3066class PartitionList(Expression):
3067    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'partitionlist'
class RefreshTriggerProperty(Property):
3071class RefreshTriggerProperty(Property):
3072    arg_types = {
3073        "method": True,
3074        "kind": False,
3075        "every": False,
3076        "unit": False,
3077        "starts": False,
3078    }
arg_types = {'method': True, 'kind': False, 'every': False, 'unit': False, 'starts': False}
key = 'refreshtriggerproperty'
class UniqueKeyProperty(Property):
3082class UniqueKeyProperty(Property):
3083    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
3087class PartitionBoundSpec(Expression):
3088    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
3089    arg_types = {
3090        "this": False,
3091        "expression": False,
3092        "from_expressions": False,
3093        "to_expressions": False,
3094    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
3097class PartitionedOfProperty(Property):
3098    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
3099    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
3102class StreamingTableProperty(Property):
3103    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
3106class RemoteWithConnectionModelProperty(Property):
3107    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
3110class ReturnsProperty(Property):
3111    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):
3114class StrictProperty(Property):
3115    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
3118class RowFormatProperty(Property):
3119    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
3122class RowFormatDelimitedProperty(Property):
3123    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
3124    arg_types = {
3125        "fields": False,
3126        "escaped": False,
3127        "collection_items": False,
3128        "map_keys": False,
3129        "lines": False,
3130        "null": False,
3131        "serde": False,
3132    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
3135class RowFormatSerdeProperty(Property):
3136    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
3140class QueryTransform(Expression):
3141    arg_types = {
3142        "expressions": True,
3143        "command_script": True,
3144        "schema": False,
3145        "row_format_before": False,
3146        "record_writer": False,
3147        "row_format_after": False,
3148        "record_reader": False,
3149    }
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):
3152class SampleProperty(Property):
3153    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
3157class SecurityProperty(Property):
3158    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
3161class SchemaCommentProperty(Property):
3162    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SemanticView(Expression):
3165class SemanticView(Expression):
3166    arg_types = {"this": True, "metrics": False, "dimensions": False, "where": False}
arg_types = {'this': True, 'metrics': False, 'dimensions': False, 'where': False}
key = 'semanticview'
class SerdeProperties(Property):
3169class SerdeProperties(Property):
3170    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
3173class SetProperty(Property):
3174    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3177class SharingProperty(Property):
3178    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3181class SetConfigProperty(Property):
3182    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3185class SettingsProperty(Property):
3186    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3189class SortKeyProperty(Property):
3190    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3193class SqlReadWriteProperty(Property):
3194    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3197class SqlSecurityProperty(Property):
3198    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3201class StabilityProperty(Property):
3202    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class StorageHandlerProperty(Property):
3205class StorageHandlerProperty(Property):
3206    arg_types = {"this": True}
arg_types = {'this': True}
key = 'storagehandlerproperty'
class TemporaryProperty(Property):
3209class TemporaryProperty(Property):
3210    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3213class SecureProperty(Property):
3214    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3218class Tags(ColumnConstraintKind, Property):
3219    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3222class TransformModelProperty(Property):
3223    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3226class TransientProperty(Property):
3227    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3230class UnloggedProperty(Property):
3231    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class UsingTemplateProperty(Property):
3235class UsingTemplateProperty(Property):
3236    arg_types = {"this": True}
arg_types = {'this': True}
key = 'usingtemplateproperty'
class ViewAttributeProperty(Property):
3240class ViewAttributeProperty(Property):
3241    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3244class VolatileProperty(Property):
3245    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3248class WithDataProperty(Property):
3249    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3252class WithJournalTableProperty(Property):
3253    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3256class WithSchemaBindingProperty(Property):
3257    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3260class WithSystemVersioningProperty(Property):
3261    arg_types = {
3262        "on": False,
3263        "this": False,
3264        "data_consistency": False,
3265        "retention_period": False,
3266        "with": True,
3267    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3270class WithProcedureOptions(Property):
3271    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3274class EncodeProperty(Property):
3275    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3278class IncludeProperty(Property):
3279    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class ForceProperty(Property):
3282class ForceProperty(Property):
3283    arg_types = {}
arg_types = {}
key = 'forceproperty'
class Properties(Expression):
3286class Properties(Expression):
3287    arg_types = {"expressions": True}
3288
3289    NAME_TO_PROPERTY = {
3290        "ALGORITHM": AlgorithmProperty,
3291        "AUTO_INCREMENT": AutoIncrementProperty,
3292        "CHARACTER SET": CharacterSetProperty,
3293        "CLUSTERED_BY": ClusteredByProperty,
3294        "COLLATE": CollateProperty,
3295        "COMMENT": SchemaCommentProperty,
3296        "CREDENTIALS": CredentialsProperty,
3297        "DEFINER": DefinerProperty,
3298        "DISTKEY": DistKeyProperty,
3299        "DISTRIBUTED_BY": DistributedByProperty,
3300        "DISTSTYLE": DistStyleProperty,
3301        "ENGINE": EngineProperty,
3302        "EXECUTE AS": ExecuteAsProperty,
3303        "FORMAT": FileFormatProperty,
3304        "LANGUAGE": LanguageProperty,
3305        "LOCATION": LocationProperty,
3306        "LOCK": LockProperty,
3307        "PARTITIONED_BY": PartitionedByProperty,
3308        "RETURNS": ReturnsProperty,
3309        "ROW_FORMAT": RowFormatProperty,
3310        "SORTKEY": SortKeyProperty,
3311        "ENCODE": EncodeProperty,
3312        "INCLUDE": IncludeProperty,
3313    }
3314
3315    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3316
3317    # CREATE property locations
3318    # Form: schema specified
3319    #   create [POST_CREATE]
3320    #     table a [POST_NAME]
3321    #     (b int) [POST_SCHEMA]
3322    #     with ([POST_WITH])
3323    #     index (b) [POST_INDEX]
3324    #
3325    # Form: alias selection
3326    #   create [POST_CREATE]
3327    #     table a [POST_NAME]
3328    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3329    #     index (c) [POST_INDEX]
3330    class Location(AutoName):
3331        POST_CREATE = auto()
3332        POST_NAME = auto()
3333        POST_SCHEMA = auto()
3334        POST_WITH = auto()
3335        POST_ALIAS = auto()
3336        POST_EXPRESSION = auto()
3337        POST_INDEX = auto()
3338        UNSUPPORTED = auto()
3339
3340    @classmethod
3341    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3342        expressions = []
3343        for key, value in properties_dict.items():
3344            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3345            if property_cls:
3346                expressions.append(property_cls(this=convert(value)))
3347            else:
3348                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3349
3350        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'>, 'CREDENTIALS': <class 'CredentialsProperty'>, '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'>, 'ENCODE': <class 'EncodeProperty'>, 'INCLUDE': <class 'IncludeProperty'>}
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 'CredentialsProperty'>: 'CREDENTIALS', <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', <class 'EncodeProperty'>: 'ENCODE', <class 'IncludeProperty'>: 'INCLUDE'}
@classmethod
def from_dict(cls, properties_dict: Dict) -> Properties:
3340    @classmethod
3341    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3342        expressions = []
3343        for key, value in properties_dict.items():
3344            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3345            if property_cls:
3346                expressions.append(property_cls(this=convert(value)))
3347            else:
3348                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3349
3350        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3330    class Location(AutoName):
3331        POST_CREATE = auto()
3332        POST_NAME = auto()
3333        POST_SCHEMA = auto()
3334        POST_WITH = auto()
3335        POST_ALIAS = auto()
3336        POST_EXPRESSION = auto()
3337        POST_INDEX = auto()
3338        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'>
class Qualify(Expression):
3353class Qualify(Expression):
3354    pass
key = 'qualify'
class InputOutputFormat(Expression):
3357class InputOutputFormat(Expression):
3358    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3362class Return(Expression):
3363    pass
key = 'return'
class Reference(Expression):
3366class Reference(Expression):
3367    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3370class Tuple(Expression):
3371    arg_types = {"expressions": False}
3372
3373    def isin(
3374        self,
3375        *expressions: t.Any,
3376        query: t.Optional[ExpOrStr] = None,
3377        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3378        copy: bool = True,
3379        **opts,
3380    ) -> In:
3381        return In(
3382            this=maybe_copy(self, copy),
3383            expressions=[convert(e, copy=copy) for e in expressions],
3384            query=maybe_parse(query, copy=copy, **opts) if query else None,
3385            unnest=(
3386                Unnest(
3387                    expressions=[
3388                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3389                        for e in ensure_list(unnest)
3390                    ]
3391                )
3392                if unnest
3393                else None
3394            ),
3395        )
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:
3373    def isin(
3374        self,
3375        *expressions: t.Any,
3376        query: t.Optional[ExpOrStr] = None,
3377        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3378        copy: bool = True,
3379        **opts,
3380    ) -> In:
3381        return In(
3382            this=maybe_copy(self, copy),
3383            expressions=[convert(e, copy=copy) for e in expressions],
3384            query=maybe_parse(query, copy=copy, **opts) if query else None,
3385            unnest=(
3386                Unnest(
3387                    expressions=[
3388                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3389                        for e in ensure_list(unnest)
3390                    ]
3391                )
3392                if unnest
3393                else None
3394            ),
3395        )
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):
3426class QueryOption(Expression):
3427    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3431class WithTableHint(Expression):
3432    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3436class IndexTableHint(Expression):
3437    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3441class HistoricalData(Expression):
3442    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Put(Expression):
3446class Put(Expression):
3447    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'put'
class Get(Expression):
3451class Get(Expression):
3452    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key = 'get'
class Table(Expression):
3455class Table(Expression):
3456    arg_types = {
3457        "this": False,
3458        "alias": False,
3459        "db": False,
3460        "catalog": False,
3461        "laterals": False,
3462        "joins": False,
3463        "pivots": False,
3464        "hints": False,
3465        "system_time": False,
3466        "version": False,
3467        "format": False,
3468        "pattern": False,
3469        "ordinality": False,
3470        "when": False,
3471        "only": False,
3472        "partition": False,
3473        "changes": False,
3474        "rows_from": False,
3475        "sample": False,
3476    }
3477
3478    @property
3479    def name(self) -> str:
3480        if not self.this or isinstance(self.this, Func):
3481            return ""
3482        return self.this.name
3483
3484    @property
3485    def db(self) -> str:
3486        return self.text("db")
3487
3488    @property
3489    def catalog(self) -> str:
3490        return self.text("catalog")
3491
3492    @property
3493    def selects(self) -> t.List[Expression]:
3494        return []
3495
3496    @property
3497    def named_selects(self) -> t.List[str]:
3498        return []
3499
3500    @property
3501    def parts(self) -> t.List[Expression]:
3502        """Return the parts of a table in order catalog, db, table."""
3503        parts: t.List[Expression] = []
3504
3505        for arg in ("catalog", "db", "this"):
3506            part = self.args.get(arg)
3507
3508            if isinstance(part, Dot):
3509                parts.extend(part.flatten())
3510            elif isinstance(part, Expression):
3511                parts.append(part)
3512
3513        return parts
3514
3515    def to_column(self, copy: bool = True) -> Expression:
3516        parts = self.parts
3517        last_part = parts[-1]
3518
3519        if isinstance(last_part, Identifier):
3520            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3521        else:
3522            # This branch will be reached if a function or array is wrapped in a `Table`
3523            col = last_part
3524
3525        alias = self.args.get("alias")
3526        if alias:
3527            col = alias_(col, alias.this, copy=copy)
3528
3529        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
3478    @property
3479    def name(self) -> str:
3480        if not self.this or isinstance(self.this, Func):
3481            return ""
3482        return self.this.name
db: str
3484    @property
3485    def db(self) -> str:
3486        return self.text("db")
catalog: str
3488    @property
3489    def catalog(self) -> str:
3490        return self.text("catalog")
selects: List[Expression]
3492    @property
3493    def selects(self) -> t.List[Expression]:
3494        return []
named_selects: List[str]
3496    @property
3497    def named_selects(self) -> t.List[str]:
3498        return []
parts: List[Expression]
3500    @property
3501    def parts(self) -> t.List[Expression]:
3502        """Return the parts of a table in order catalog, db, table."""
3503        parts: t.List[Expression] = []
3504
3505        for arg in ("catalog", "db", "this"):
3506            part = self.args.get(arg)
3507
3508            if isinstance(part, Dot):
3509                parts.extend(part.flatten())
3510            elif isinstance(part, Expression):
3511                parts.append(part)
3512
3513        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3515    def to_column(self, copy: bool = True) -> Expression:
3516        parts = self.parts
3517        last_part = parts[-1]
3518
3519        if isinstance(last_part, Identifier):
3520            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3521        else:
3522            # This branch will be reached if a function or array is wrapped in a `Table`
3523            col = last_part
3524
3525        alias = self.args.get("alias")
3526        if alias:
3527            col = alias_(col, alias.this, copy=copy)
3528
3529        return col
key = 'table'
class SetOperation(Query):
3532class SetOperation(Query):
3533    arg_types = {
3534        "with": False,
3535        "this": True,
3536        "expression": True,
3537        "distinct": False,
3538        "by_name": False,
3539        "side": False,
3540        "kind": False,
3541        "on": False,
3542        **QUERY_MODIFIERS,
3543    }
3544
3545    def select(
3546        self: S,
3547        *expressions: t.Optional[ExpOrStr],
3548        append: bool = True,
3549        dialect: DialectType = None,
3550        copy: bool = True,
3551        **opts,
3552    ) -> S:
3553        this = maybe_copy(self, copy)
3554        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3555        this.expression.unnest().select(
3556            *expressions, append=append, dialect=dialect, copy=False, **opts
3557        )
3558        return this
3559
3560    @property
3561    def named_selects(self) -> t.List[str]:
3562        return self.this.unnest().named_selects
3563
3564    @property
3565    def is_star(self) -> bool:
3566        return self.this.is_star or self.expression.is_star
3567
3568    @property
3569    def selects(self) -> t.List[Expression]:
3570        return self.this.unnest().selects
3571
3572    @property
3573    def left(self) -> Query:
3574        return self.this
3575
3576    @property
3577    def right(self) -> Query:
3578        return self.expression
3579
3580    @property
3581    def kind(self) -> str:
3582        return self.text("kind").upper()
3583
3584    @property
3585    def side(self) -> str:
3586        return self.text("side").upper()
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'side': False, 'kind': False, 'on': 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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3545    def select(
3546        self: S,
3547        *expressions: t.Optional[ExpOrStr],
3548        append: bool = True,
3549        dialect: DialectType = None,
3550        copy: bool = True,
3551        **opts,
3552    ) -> S:
3553        this = maybe_copy(self, copy)
3554        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3555        this.expression.unnest().select(
3556            *expressions, append=append, dialect=dialect, copy=False, **opts
3557        )
3558        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]
3560    @property
3561    def named_selects(self) -> t.List[str]:
3562        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3564    @property
3565    def is_star(self) -> bool:
3566        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3568    @property
3569    def selects(self) -> t.List[Expression]:
3570        return self.this.unnest().selects

Returns the query's projections.

left: Query
3572    @property
3573    def left(self) -> Query:
3574        return self.this
right: Query
3576    @property
3577    def right(self) -> Query:
3578        return self.expression
kind: str
3580    @property
3581    def kind(self) -> str:
3582        return self.text("kind").upper()
side: str
3584    @property
3585    def side(self) -> str:
3586        return self.text("side").upper()
key = 'setoperation'
class Union(SetOperation):
3589class Union(SetOperation):
3590    pass
key = 'union'
class Except(SetOperation):
3593class Except(SetOperation):
3594    pass
key = 'except'
class Intersect(SetOperation):
3597class Intersect(SetOperation):
3598    pass
key = 'intersect'
class Update(DML):
3601class Update(DML):
3602    arg_types = {
3603        "with": False,
3604        "this": False,
3605        "expressions": True,
3606        "from": False,
3607        "where": False,
3608        "returning": False,
3609        "order": False,
3610        "limit": False,
3611    }
3612
3613    def table(
3614        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3615    ) -> Update:
3616        """
3617        Set the table to update.
3618
3619        Example:
3620            >>> Update().table("my_table").set_("x = 1").sql()
3621            'UPDATE my_table SET x = 1'
3622
3623        Args:
3624            expression : the SQL code strings to parse.
3625                If a `Table` instance is passed, this is used as-is.
3626                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3627            dialect: the dialect used to parse the input expression.
3628            copy: if `False`, modify this expression instance in-place.
3629            opts: other options to use to parse the input expressions.
3630
3631        Returns:
3632            The modified Update expression.
3633        """
3634        return _apply_builder(
3635            expression=expression,
3636            instance=self,
3637            arg="this",
3638            into=Table,
3639            prefix=None,
3640            dialect=dialect,
3641            copy=copy,
3642            **opts,
3643        )
3644
3645    def set_(
3646        self,
3647        *expressions: ExpOrStr,
3648        append: bool = True,
3649        dialect: DialectType = None,
3650        copy: bool = True,
3651        **opts,
3652    ) -> Update:
3653        """
3654        Append to or set the SET expressions.
3655
3656        Example:
3657            >>> Update().table("my_table").set_("x = 1").sql()
3658            'UPDATE my_table SET x = 1'
3659
3660        Args:
3661            *expressions: the SQL code strings to parse.
3662                If `Expression` instance(s) are passed, they will be used as-is.
3663                Multiple expressions are combined with a comma.
3664            append: if `True`, add the new expressions to any existing SET expressions.
3665                Otherwise, this resets the expressions.
3666            dialect: the dialect used to parse the input expressions.
3667            copy: if `False`, modify this expression instance in-place.
3668            opts: other options to use to parse the input expressions.
3669        """
3670        return _apply_list_builder(
3671            *expressions,
3672            instance=self,
3673            arg="expressions",
3674            append=append,
3675            into=Expression,
3676            prefix=None,
3677            dialect=dialect,
3678            copy=copy,
3679            **opts,
3680        )
3681
3682    def where(
3683        self,
3684        *expressions: t.Optional[ExpOrStr],
3685        append: bool = True,
3686        dialect: DialectType = None,
3687        copy: bool = True,
3688        **opts,
3689    ) -> Select:
3690        """
3691        Append to or set the WHERE expressions.
3692
3693        Example:
3694            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3695            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3696
3697        Args:
3698            *expressions: the SQL code strings to parse.
3699                If an `Expression` instance is passed, it will be used as-is.
3700                Multiple expressions are combined with an AND operator.
3701            append: if `True`, AND the new expressions to any existing expression.
3702                Otherwise, this resets the expression.
3703            dialect: the dialect used to parse the input expressions.
3704            copy: if `False`, modify this expression instance in-place.
3705            opts: other options to use to parse the input expressions.
3706
3707        Returns:
3708            Select: the modified expression.
3709        """
3710        return _apply_conjunction_builder(
3711            *expressions,
3712            instance=self,
3713            arg="where",
3714            append=append,
3715            into=Where,
3716            dialect=dialect,
3717            copy=copy,
3718            **opts,
3719        )
3720
3721    def from_(
3722        self,
3723        expression: t.Optional[ExpOrStr] = None,
3724        dialect: DialectType = None,
3725        copy: bool = True,
3726        **opts,
3727    ) -> Update:
3728        """
3729        Set the FROM expression.
3730
3731        Example:
3732            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3733            'UPDATE my_table SET x = 1 FROM baz'
3734
3735        Args:
3736            expression : the SQL code strings to parse.
3737                If a `From` instance is passed, this is used as-is.
3738                If another `Expression` instance is passed, it will be wrapped in a `From`.
3739                If nothing is passed in then a from is not applied to the expression
3740            dialect: the dialect used to parse the input expression.
3741            copy: if `False`, modify this expression instance in-place.
3742            opts: other options to use to parse the input expressions.
3743
3744        Returns:
3745            The modified Update expression.
3746        """
3747        if not expression:
3748            return maybe_copy(self, copy)
3749
3750        return _apply_builder(
3751            expression=expression,
3752            instance=self,
3753            arg="from",
3754            into=From,
3755            prefix="FROM",
3756            dialect=dialect,
3757            copy=copy,
3758            **opts,
3759        )
3760
3761    def with_(
3762        self,
3763        alias: ExpOrStr,
3764        as_: ExpOrStr,
3765        recursive: t.Optional[bool] = None,
3766        materialized: t.Optional[bool] = None,
3767        append: bool = True,
3768        dialect: DialectType = None,
3769        copy: bool = True,
3770        **opts,
3771    ) -> Update:
3772        """
3773        Append to or set the common table expressions.
3774
3775        Example:
3776            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3777            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3778
3779        Args:
3780            alias: the SQL code string to parse as the table name.
3781                If an `Expression` instance is passed, this is used as-is.
3782            as_: the SQL code string to parse as the table expression.
3783                If an `Expression` instance is passed, it will be used as-is.
3784            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3785            materialized: set the MATERIALIZED part of the expression.
3786            append: if `True`, add to any existing expressions.
3787                Otherwise, this resets the expressions.
3788            dialect: the dialect used to parse the input expression.
3789            copy: if `False`, modify this expression instance in-place.
3790            opts: other options to use to parse the input expressions.
3791
3792        Returns:
3793            The modified expression.
3794        """
3795        return _apply_cte_builder(
3796            self,
3797            alias,
3798            as_,
3799            recursive=recursive,
3800            materialized=materialized,
3801            append=append,
3802            dialect=dialect,
3803            copy=copy,
3804            **opts,
3805        )
arg_types = {'with': False, 'this': False, 'expressions': True, 'from': False, 'where': False, 'returning': False, 'order': False, 'limit': False}
def table( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3613    def table(
3614        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3615    ) -> Update:
3616        """
3617        Set the table to update.
3618
3619        Example:
3620            >>> Update().table("my_table").set_("x = 1").sql()
3621            'UPDATE my_table SET x = 1'
3622
3623        Args:
3624            expression : the SQL code strings to parse.
3625                If a `Table` instance is passed, this is used as-is.
3626                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3627            dialect: the dialect used to parse the input expression.
3628            copy: if `False`, modify this expression instance in-place.
3629            opts: other options to use to parse the input expressions.
3630
3631        Returns:
3632            The modified Update expression.
3633        """
3634        return _apply_builder(
3635            expression=expression,
3636            instance=self,
3637            arg="this",
3638            into=Table,
3639            prefix=None,
3640            dialect=dialect,
3641            copy=copy,
3642            **opts,
3643        )

Set the table to update.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • expression : the SQL code strings to parse. If a Table instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Table.
  • 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 Update expression.

def set_( self, *expressions: Union[str, Expression], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3645    def set_(
3646        self,
3647        *expressions: ExpOrStr,
3648        append: bool = True,
3649        dialect: DialectType = None,
3650        copy: bool = True,
3651        **opts,
3652    ) -> Update:
3653        """
3654        Append to or set the SET expressions.
3655
3656        Example:
3657            >>> Update().table("my_table").set_("x = 1").sql()
3658            'UPDATE my_table SET x = 1'
3659
3660        Args:
3661            *expressions: the SQL code strings to parse.
3662                If `Expression` instance(s) are passed, they will be used as-is.
3663                Multiple expressions are combined with a comma.
3664            append: if `True`, add the new expressions to any existing SET expressions.
3665                Otherwise, this resets the expressions.
3666            dialect: the dialect used to parse the input expressions.
3667            copy: if `False`, modify this expression instance in-place.
3668            opts: other options to use to parse the input expressions.
3669        """
3670        return _apply_list_builder(
3671            *expressions,
3672            instance=self,
3673            arg="expressions",
3674            append=append,
3675            into=Expression,
3676            prefix=None,
3677            dialect=dialect,
3678            copy=copy,
3679            **opts,
3680        )

Append to or set the SET expressions.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If Expression instance(s) are passed, they will be used as-is. Multiple expressions are combined with a comma.
  • append: if True, add the new expressions to any existing SET 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.
def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3682    def where(
3683        self,
3684        *expressions: t.Optional[ExpOrStr],
3685        append: bool = True,
3686        dialect: DialectType = None,
3687        copy: bool = True,
3688        **opts,
3689    ) -> Select:
3690        """
3691        Append to or set the WHERE expressions.
3692
3693        Example:
3694            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3695            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3696
3697        Args:
3698            *expressions: the SQL code strings to parse.
3699                If an `Expression` instance is passed, it will be used as-is.
3700                Multiple expressions are combined with an AND operator.
3701            append: if `True`, AND the new expressions to any existing expression.
3702                Otherwise, this resets the expression.
3703            dialect: the dialect used to parse the input expressions.
3704            copy: if `False`, modify this expression instance in-place.
3705            opts: other options to use to parse the input expressions.
3706
3707        Returns:
3708            Select: the modified expression.
3709        """
3710        return _apply_conjunction_builder(
3711            *expressions,
3712            instance=self,
3713            arg="where",
3714            append=append,
3715            into=Where,
3716            dialect=dialect,
3717            copy=copy,
3718            **opts,
3719        )

Append to or set the WHERE expressions.

Example:
>>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
"UPDATE tbl SET x = 1 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 from_( self, expression: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3721    def from_(
3722        self,
3723        expression: t.Optional[ExpOrStr] = None,
3724        dialect: DialectType = None,
3725        copy: bool = True,
3726        **opts,
3727    ) -> Update:
3728        """
3729        Set the FROM expression.
3730
3731        Example:
3732            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3733            'UPDATE my_table SET x = 1 FROM baz'
3734
3735        Args:
3736            expression : the SQL code strings to parse.
3737                If a `From` instance is passed, this is used as-is.
3738                If another `Expression` instance is passed, it will be wrapped in a `From`.
3739                If nothing is passed in then a from is not applied to the expression
3740            dialect: the dialect used to parse the input expression.
3741            copy: if `False`, modify this expression instance in-place.
3742            opts: other options to use to parse the input expressions.
3743
3744        Returns:
3745            The modified Update expression.
3746        """
3747        if not expression:
3748            return maybe_copy(self, copy)
3749
3750        return _apply_builder(
3751            expression=expression,
3752            instance=self,
3753            arg="from",
3754            into=From,
3755            prefix="FROM",
3756            dialect=dialect,
3757            copy=copy,
3758            **opts,
3759        )

Set the FROM expression.

Example:
>>> Update().table("my_table").set_("x = 1").from_("baz").sql()
'UPDATE my_table SET x = 1 FROM baz'
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. If nothing is passed in then a from is not applied to the 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 Update expression.

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3761    def with_(
3762        self,
3763        alias: ExpOrStr,
3764        as_: ExpOrStr,
3765        recursive: t.Optional[bool] = None,
3766        materialized: t.Optional[bool] = None,
3767        append: bool = True,
3768        dialect: DialectType = None,
3769        copy: bool = True,
3770        **opts,
3771    ) -> Update:
3772        """
3773        Append to or set the common table expressions.
3774
3775        Example:
3776            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3777            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3778
3779        Args:
3780            alias: the SQL code string to parse as the table name.
3781                If an `Expression` instance is passed, this is used as-is.
3782            as_: the SQL code string to parse as the table expression.
3783                If an `Expression` instance is passed, it will be used as-is.
3784            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3785            materialized: set the MATERIALIZED part of the expression.
3786            append: if `True`, add to any existing expressions.
3787                Otherwise, this resets the expressions.
3788            dialect: the dialect used to parse the input expression.
3789            copy: if `False`, modify this expression instance in-place.
3790            opts: other options to use to parse the input expressions.
3791
3792        Returns:
3793            The modified expression.
3794        """
3795        return _apply_cte_builder(
3796            self,
3797            alias,
3798            as_,
3799            recursive=recursive,
3800            materialized=materialized,
3801            append=append,
3802            dialect=dialect,
3803            copy=copy,
3804            **opts,
3805        )

Append to or set the common table expressions.

Example:
>>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
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 = 'update'
class Values(UDTF):
3808class Values(UDTF):
3809    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3812class Var(Expression):
3813    pass
key = 'var'
class Version(Expression):
3816class Version(Expression):
3817    """
3818    Time travel, iceberg, bigquery etc
3819    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3820    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3821    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3822    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3823    this is either TIMESTAMP or VERSION
3824    kind is ("AS OF", "BETWEEN")
3825    """
3826
3827    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3830class Schema(Expression):
3831    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3836class Lock(Expression):
3837    arg_types = {"update": True, "expressions": False, "wait": False, "key": False}
arg_types = {'update': True, 'expressions': False, 'wait': False, 'key': False}
key = 'lock'
class Select(Query):
3840class Select(Query):
3841    arg_types = {
3842        "with": False,
3843        "kind": False,
3844        "expressions": False,
3845        "hint": False,
3846        "distinct": False,
3847        "into": False,
3848        "from": False,
3849        "operation_modifiers": False,
3850        **QUERY_MODIFIERS,
3851    }
3852
3853    def from_(
3854        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3855    ) -> Select:
3856        """
3857        Set the FROM expression.
3858
3859        Example:
3860            >>> Select().from_("tbl").select("x").sql()
3861            'SELECT x FROM tbl'
3862
3863        Args:
3864            expression : the SQL code strings to parse.
3865                If a `From` instance is passed, this is used as-is.
3866                If another `Expression` instance is passed, it will be wrapped in a `From`.
3867            dialect: the dialect used to parse the input expression.
3868            copy: if `False`, modify this expression instance in-place.
3869            opts: other options to use to parse the input expressions.
3870
3871        Returns:
3872            The modified Select expression.
3873        """
3874        return _apply_builder(
3875            expression=expression,
3876            instance=self,
3877            arg="from",
3878            into=From,
3879            prefix="FROM",
3880            dialect=dialect,
3881            copy=copy,
3882            **opts,
3883        )
3884
3885    def group_by(
3886        self,
3887        *expressions: t.Optional[ExpOrStr],
3888        append: bool = True,
3889        dialect: DialectType = None,
3890        copy: bool = True,
3891        **opts,
3892    ) -> Select:
3893        """
3894        Set the GROUP BY expression.
3895
3896        Example:
3897            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3898            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3899
3900        Args:
3901            *expressions: the SQL code strings to parse.
3902                If a `Group` instance is passed, this is used as-is.
3903                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3904                If nothing is passed in then a group by is not applied to the expression
3905            append: if `True`, add to any existing expressions.
3906                Otherwise, this flattens all the `Group` expression into a single expression.
3907            dialect: the dialect used to parse the input expression.
3908            copy: if `False`, modify this expression instance in-place.
3909            opts: other options to use to parse the input expressions.
3910
3911        Returns:
3912            The modified Select expression.
3913        """
3914        if not expressions:
3915            return self if not copy else self.copy()
3916
3917        return _apply_child_list_builder(
3918            *expressions,
3919            instance=self,
3920            arg="group",
3921            append=append,
3922            copy=copy,
3923            prefix="GROUP BY",
3924            into=Group,
3925            dialect=dialect,
3926            **opts,
3927        )
3928
3929    def sort_by(
3930        self,
3931        *expressions: t.Optional[ExpOrStr],
3932        append: bool = True,
3933        dialect: DialectType = None,
3934        copy: bool = True,
3935        **opts,
3936    ) -> Select:
3937        """
3938        Set the SORT BY expression.
3939
3940        Example:
3941            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3942            'SELECT x FROM tbl SORT BY x DESC'
3943
3944        Args:
3945            *expressions: the SQL code strings to parse.
3946                If a `Group` instance is passed, this is used as-is.
3947                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3948            append: if `True`, add to any existing expressions.
3949                Otherwise, this flattens all the `Order` expression into a single expression.
3950            dialect: the dialect used to parse the input expression.
3951            copy: if `False`, modify this expression instance in-place.
3952            opts: other options to use to parse the input expressions.
3953
3954        Returns:
3955            The modified Select expression.
3956        """
3957        return _apply_child_list_builder(
3958            *expressions,
3959            instance=self,
3960            arg="sort",
3961            append=append,
3962            copy=copy,
3963            prefix="SORT BY",
3964            into=Sort,
3965            dialect=dialect,
3966            **opts,
3967        )
3968
3969    def cluster_by(
3970        self,
3971        *expressions: t.Optional[ExpOrStr],
3972        append: bool = True,
3973        dialect: DialectType = None,
3974        copy: bool = True,
3975        **opts,
3976    ) -> Select:
3977        """
3978        Set the CLUSTER BY expression.
3979
3980        Example:
3981            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3982            'SELECT x FROM tbl CLUSTER BY x DESC'
3983
3984        Args:
3985            *expressions: the SQL code strings to parse.
3986                If a `Group` instance is passed, this is used as-is.
3987                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3988            append: if `True`, add to any existing expressions.
3989                Otherwise, this flattens all the `Order` expression into a single expression.
3990            dialect: the dialect used to parse the input expression.
3991            copy: if `False`, modify this expression instance in-place.
3992            opts: other options to use to parse the input expressions.
3993
3994        Returns:
3995            The modified Select expression.
3996        """
3997        return _apply_child_list_builder(
3998            *expressions,
3999            instance=self,
4000            arg="cluster",
4001            append=append,
4002            copy=copy,
4003            prefix="CLUSTER BY",
4004            into=Cluster,
4005            dialect=dialect,
4006            **opts,
4007        )
4008
4009    def select(
4010        self,
4011        *expressions: t.Optional[ExpOrStr],
4012        append: bool = True,
4013        dialect: DialectType = None,
4014        copy: bool = True,
4015        **opts,
4016    ) -> Select:
4017        return _apply_list_builder(
4018            *expressions,
4019            instance=self,
4020            arg="expressions",
4021            append=append,
4022            dialect=dialect,
4023            into=Expression,
4024            copy=copy,
4025            **opts,
4026        )
4027
4028    def lateral(
4029        self,
4030        *expressions: t.Optional[ExpOrStr],
4031        append: bool = True,
4032        dialect: DialectType = None,
4033        copy: bool = True,
4034        **opts,
4035    ) -> Select:
4036        """
4037        Append to or set the LATERAL expressions.
4038
4039        Example:
4040            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
4041            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
4042
4043        Args:
4044            *expressions: the SQL code strings to parse.
4045                If an `Expression` instance is passed, it will be used as-is.
4046            append: if `True`, add to any existing expressions.
4047                Otherwise, this resets the expressions.
4048            dialect: the dialect used to parse the input expressions.
4049            copy: if `False`, modify this expression instance in-place.
4050            opts: other options to use to parse the input expressions.
4051
4052        Returns:
4053            The modified Select expression.
4054        """
4055        return _apply_list_builder(
4056            *expressions,
4057            instance=self,
4058            arg="laterals",
4059            append=append,
4060            into=Lateral,
4061            prefix="LATERAL VIEW",
4062            dialect=dialect,
4063            copy=copy,
4064            **opts,
4065        )
4066
4067    def join(
4068        self,
4069        expression: ExpOrStr,
4070        on: t.Optional[ExpOrStr] = None,
4071        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4072        append: bool = True,
4073        join_type: t.Optional[str] = None,
4074        join_alias: t.Optional[Identifier | str] = None,
4075        dialect: DialectType = None,
4076        copy: bool = True,
4077        **opts,
4078    ) -> Select:
4079        """
4080        Append to or set the JOIN expressions.
4081
4082        Example:
4083            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4084            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4085
4086            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4087            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4088
4089            Use `join_type` to change the type of join:
4090
4091            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4092            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4093
4094        Args:
4095            expression: the SQL code string to parse.
4096                If an `Expression` instance is passed, it will be used as-is.
4097            on: optionally specify the join "on" criteria as a SQL string.
4098                If an `Expression` instance is passed, it will be used as-is.
4099            using: optionally specify the join "using" criteria as a SQL string.
4100                If an `Expression` instance is passed, it will be used as-is.
4101            append: if `True`, add to any existing expressions.
4102                Otherwise, this resets the expressions.
4103            join_type: if set, alter the parsed join type.
4104            join_alias: an optional alias for the joined source.
4105            dialect: the dialect used to parse the input expressions.
4106            copy: if `False`, modify this expression instance in-place.
4107            opts: other options to use to parse the input expressions.
4108
4109        Returns:
4110            Select: the modified expression.
4111        """
4112        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4113
4114        try:
4115            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4116        except ParseError:
4117            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4118
4119        join = expression if isinstance(expression, Join) else Join(this=expression)
4120
4121        if isinstance(join.this, Select):
4122            join.this.replace(join.this.subquery())
4123
4124        if join_type:
4125            method: t.Optional[Token]
4126            side: t.Optional[Token]
4127            kind: t.Optional[Token]
4128
4129            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4130
4131            if method:
4132                join.set("method", method.text)
4133            if side:
4134                join.set("side", side.text)
4135            if kind:
4136                join.set("kind", kind.text)
4137
4138        if on:
4139            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4140            join.set("on", on)
4141
4142        if using:
4143            join = _apply_list_builder(
4144                *ensure_list(using),
4145                instance=join,
4146                arg="using",
4147                append=append,
4148                copy=copy,
4149                into=Identifier,
4150                **opts,
4151            )
4152
4153        if join_alias:
4154            join.set("this", alias_(join.this, join_alias, table=True))
4155
4156        return _apply_list_builder(
4157            join,
4158            instance=self,
4159            arg="joins",
4160            append=append,
4161            copy=copy,
4162            **opts,
4163        )
4164
4165    def having(
4166        self,
4167        *expressions: t.Optional[ExpOrStr],
4168        append: bool = True,
4169        dialect: DialectType = None,
4170        copy: bool = True,
4171        **opts,
4172    ) -> Select:
4173        """
4174        Append to or set the HAVING expressions.
4175
4176        Example:
4177            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4178            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4179
4180        Args:
4181            *expressions: the SQL code strings to parse.
4182                If an `Expression` instance is passed, it will be used as-is.
4183                Multiple expressions are combined with an AND operator.
4184            append: if `True`, AND the new expressions to any existing expression.
4185                Otherwise, this resets the expression.
4186            dialect: the dialect used to parse the input expressions.
4187            copy: if `False`, modify this expression instance in-place.
4188            opts: other options to use to parse the input expressions.
4189
4190        Returns:
4191            The modified Select expression.
4192        """
4193        return _apply_conjunction_builder(
4194            *expressions,
4195            instance=self,
4196            arg="having",
4197            append=append,
4198            into=Having,
4199            dialect=dialect,
4200            copy=copy,
4201            **opts,
4202        )
4203
4204    def window(
4205        self,
4206        *expressions: t.Optional[ExpOrStr],
4207        append: bool = True,
4208        dialect: DialectType = None,
4209        copy: bool = True,
4210        **opts,
4211    ) -> Select:
4212        return _apply_list_builder(
4213            *expressions,
4214            instance=self,
4215            arg="windows",
4216            append=append,
4217            into=Window,
4218            dialect=dialect,
4219            copy=copy,
4220            **opts,
4221        )
4222
4223    def qualify(
4224        self,
4225        *expressions: t.Optional[ExpOrStr],
4226        append: bool = True,
4227        dialect: DialectType = None,
4228        copy: bool = True,
4229        **opts,
4230    ) -> Select:
4231        return _apply_conjunction_builder(
4232            *expressions,
4233            instance=self,
4234            arg="qualify",
4235            append=append,
4236            into=Qualify,
4237            dialect=dialect,
4238            copy=copy,
4239            **opts,
4240        )
4241
4242    def distinct(
4243        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4244    ) -> Select:
4245        """
4246        Set the OFFSET expression.
4247
4248        Example:
4249            >>> Select().from_("tbl").select("x").distinct().sql()
4250            'SELECT DISTINCT x FROM tbl'
4251
4252        Args:
4253            ons: the expressions to distinct on
4254            distinct: whether the Select should be distinct
4255            copy: if `False`, modify this expression instance in-place.
4256
4257        Returns:
4258            Select: the modified expression.
4259        """
4260        instance = maybe_copy(self, copy)
4261        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4262        instance.set("distinct", Distinct(on=on) if distinct else None)
4263        return instance
4264
4265    def ctas(
4266        self,
4267        table: ExpOrStr,
4268        properties: t.Optional[t.Dict] = None,
4269        dialect: DialectType = None,
4270        copy: bool = True,
4271        **opts,
4272    ) -> Create:
4273        """
4274        Convert this expression to a CREATE TABLE AS statement.
4275
4276        Example:
4277            >>> Select().select("*").from_("tbl").ctas("x").sql()
4278            'CREATE TABLE x AS SELECT * FROM tbl'
4279
4280        Args:
4281            table: the SQL code string to parse as the table name.
4282                If another `Expression` instance is passed, it will be used as-is.
4283            properties: an optional mapping of table properties
4284            dialect: the dialect used to parse the input table.
4285            copy: if `False`, modify this expression instance in-place.
4286            opts: other options to use to parse the input table.
4287
4288        Returns:
4289            The new Create expression.
4290        """
4291        instance = maybe_copy(self, copy)
4292        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4293
4294        properties_expression = None
4295        if properties:
4296            properties_expression = Properties.from_dict(properties)
4297
4298        return Create(
4299            this=table_expression,
4300            kind="TABLE",
4301            expression=instance,
4302            properties=properties_expression,
4303        )
4304
4305    def lock(self, update: bool = True, copy: bool = True) -> Select:
4306        """
4307        Set the locking read mode for this expression.
4308
4309        Examples:
4310            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4311            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4312
4313            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4314            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4315
4316        Args:
4317            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4318            copy: if `False`, modify this expression instance in-place.
4319
4320        Returns:
4321            The modified expression.
4322        """
4323        inst = maybe_copy(self, copy)
4324        inst.set("locks", [Lock(update=update)])
4325
4326        return inst
4327
4328    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4329        """
4330        Set hints for this expression.
4331
4332        Examples:
4333            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4334            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4335
4336        Args:
4337            hints: The SQL code strings to parse as the hints.
4338                If an `Expression` instance is passed, it will be used as-is.
4339            dialect: The dialect used to parse the hints.
4340            copy: If `False`, modify this expression instance in-place.
4341
4342        Returns:
4343            The modified expression.
4344        """
4345        inst = maybe_copy(self, copy)
4346        inst.set(
4347            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4348        )
4349
4350        return inst
4351
4352    @property
4353    def named_selects(self) -> t.List[str]:
4354        selects = []
4355
4356        for e in self.expressions:
4357            if e.alias_or_name:
4358                selects.append(e.output_name)
4359            elif isinstance(e, Aliases):
4360                selects.extend([a.name for a in e.aliases])
4361        return selects
4362
4363    @property
4364    def is_star(self) -> bool:
4365        return any(expression.is_star for expression in self.expressions)
4366
4367    @property
4368    def selects(self) -> t.List[Expression]:
4369        return self.expressions
arg_types = {'with': False, 'kind': False, 'expressions': False, 'hint': False, 'distinct': False, 'into': False, 'from': False, 'operation_modifiers': 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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3853    def from_(
3854        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3855    ) -> Select:
3856        """
3857        Set the FROM expression.
3858
3859        Example:
3860            >>> Select().from_("tbl").select("x").sql()
3861            'SELECT x FROM tbl'
3862
3863        Args:
3864            expression : the SQL code strings to parse.
3865                If a `From` instance is passed, this is used as-is.
3866                If another `Expression` instance is passed, it will be wrapped in a `From`.
3867            dialect: the dialect used to parse the input expression.
3868            copy: if `False`, modify this expression instance in-place.
3869            opts: other options to use to parse the input expressions.
3870
3871        Returns:
3872            The modified Select expression.
3873        """
3874        return _apply_builder(
3875            expression=expression,
3876            instance=self,
3877            arg="from",
3878            into=From,
3879            prefix="FROM",
3880            dialect=dialect,
3881            copy=copy,
3882            **opts,
3883        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3885    def group_by(
3886        self,
3887        *expressions: t.Optional[ExpOrStr],
3888        append: bool = True,
3889        dialect: DialectType = None,
3890        copy: bool = True,
3891        **opts,
3892    ) -> Select:
3893        """
3894        Set the GROUP BY expression.
3895
3896        Example:
3897            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3898            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3899
3900        Args:
3901            *expressions: the SQL code strings to parse.
3902                If a `Group` instance is passed, this is used as-is.
3903                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3904                If nothing is passed in then a group by is not applied to the expression
3905            append: if `True`, add to any existing expressions.
3906                Otherwise, this flattens all the `Group` expression into a single expression.
3907            dialect: the dialect used to parse the input expression.
3908            copy: if `False`, modify this expression instance in-place.
3909            opts: other options to use to parse the input expressions.
3910
3911        Returns:
3912            The modified Select expression.
3913        """
3914        if not expressions:
3915            return self if not copy else self.copy()
3916
3917        return _apply_child_list_builder(
3918            *expressions,
3919            instance=self,
3920            arg="group",
3921            append=append,
3922            copy=copy,
3923            prefix="GROUP BY",
3924            into=Group,
3925            dialect=dialect,
3926            **opts,
3927        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3929    def sort_by(
3930        self,
3931        *expressions: t.Optional[ExpOrStr],
3932        append: bool = True,
3933        dialect: DialectType = None,
3934        copy: bool = True,
3935        **opts,
3936    ) -> Select:
3937        """
3938        Set the SORT BY expression.
3939
3940        Example:
3941            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3942            'SELECT x FROM tbl SORT BY x DESC'
3943
3944        Args:
3945            *expressions: the SQL code strings to parse.
3946                If a `Group` instance is passed, this is used as-is.
3947                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3948            append: if `True`, add to any existing expressions.
3949                Otherwise, this flattens all the `Order` expression into a single expression.
3950            dialect: the dialect used to parse the input expression.
3951            copy: if `False`, modify this expression instance in-place.
3952            opts: other options to use to parse the input expressions.
3953
3954        Returns:
3955            The modified Select expression.
3956        """
3957        return _apply_child_list_builder(
3958            *expressions,
3959            instance=self,
3960            arg="sort",
3961            append=append,
3962            copy=copy,
3963            prefix="SORT BY",
3964            into=Sort,
3965            dialect=dialect,
3966            **opts,
3967        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3969    def cluster_by(
3970        self,
3971        *expressions: t.Optional[ExpOrStr],
3972        append: bool = True,
3973        dialect: DialectType = None,
3974        copy: bool = True,
3975        **opts,
3976    ) -> Select:
3977        """
3978        Set the CLUSTER BY expression.
3979
3980        Example:
3981            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3982            'SELECT x FROM tbl CLUSTER BY x DESC'
3983
3984        Args:
3985            *expressions: the SQL code strings to parse.
3986                If a `Group` instance is passed, this is used as-is.
3987                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3988            append: if `True`, add to any existing expressions.
3989                Otherwise, this flattens all the `Order` expression into a single expression.
3990            dialect: the dialect used to parse the input expression.
3991            copy: if `False`, modify this expression instance in-place.
3992            opts: other options to use to parse the input expressions.
3993
3994        Returns:
3995            The modified Select expression.
3996        """
3997        return _apply_child_list_builder(
3998            *expressions,
3999            instance=self,
4000            arg="cluster",
4001            append=append,
4002            copy=copy,
4003            prefix="CLUSTER BY",
4004            into=Cluster,
4005            dialect=dialect,
4006            **opts,
4007        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4009    def select(
4010        self,
4011        *expressions: t.Optional[ExpOrStr],
4012        append: bool = True,
4013        dialect: DialectType = None,
4014        copy: bool = True,
4015        **opts,
4016    ) -> Select:
4017        return _apply_list_builder(
4018            *expressions,
4019            instance=self,
4020            arg="expressions",
4021            append=append,
4022            dialect=dialect,
4023            into=Expression,
4024            copy=copy,
4025            **opts,
4026        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4028    def lateral(
4029        self,
4030        *expressions: t.Optional[ExpOrStr],
4031        append: bool = True,
4032        dialect: DialectType = None,
4033        copy: bool = True,
4034        **opts,
4035    ) -> Select:
4036        """
4037        Append to or set the LATERAL expressions.
4038
4039        Example:
4040            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
4041            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
4042
4043        Args:
4044            *expressions: the SQL code strings to parse.
4045                If an `Expression` instance is passed, it will be used as-is.
4046            append: if `True`, add to any existing expressions.
4047                Otherwise, this resets the expressions.
4048            dialect: the dialect used to parse the input expressions.
4049            copy: if `False`, modify this expression instance in-place.
4050            opts: other options to use to parse the input expressions.
4051
4052        Returns:
4053            The modified Select expression.
4054        """
4055        return _apply_list_builder(
4056            *expressions,
4057            instance=self,
4058            arg="laterals",
4059            append=append,
4060            into=Lateral,
4061            prefix="LATERAL VIEW",
4062            dialect=dialect,
4063            copy=copy,
4064            **opts,
4065        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4067    def join(
4068        self,
4069        expression: ExpOrStr,
4070        on: t.Optional[ExpOrStr] = None,
4071        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
4072        append: bool = True,
4073        join_type: t.Optional[str] = None,
4074        join_alias: t.Optional[Identifier | str] = None,
4075        dialect: DialectType = None,
4076        copy: bool = True,
4077        **opts,
4078    ) -> Select:
4079        """
4080        Append to or set the JOIN expressions.
4081
4082        Example:
4083            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
4084            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
4085
4086            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
4087            'SELECT 1 FROM a JOIN b USING (x, y, z)'
4088
4089            Use `join_type` to change the type of join:
4090
4091            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
4092            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
4093
4094        Args:
4095            expression: the SQL code string to parse.
4096                If an `Expression` instance is passed, it will be used as-is.
4097            on: optionally specify the join "on" criteria as a SQL string.
4098                If an `Expression` instance is passed, it will be used as-is.
4099            using: optionally specify the join "using" criteria as a SQL string.
4100                If an `Expression` instance is passed, it will be used as-is.
4101            append: if `True`, add to any existing expressions.
4102                Otherwise, this resets the expressions.
4103            join_type: if set, alter the parsed join type.
4104            join_alias: an optional alias for the joined source.
4105            dialect: the dialect used to parse the input expressions.
4106            copy: if `False`, modify this expression instance in-place.
4107            opts: other options to use to parse the input expressions.
4108
4109        Returns:
4110            Select: the modified expression.
4111        """
4112        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
4113
4114        try:
4115            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
4116        except ParseError:
4117            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
4118
4119        join = expression if isinstance(expression, Join) else Join(this=expression)
4120
4121        if isinstance(join.this, Select):
4122            join.this.replace(join.this.subquery())
4123
4124        if join_type:
4125            method: t.Optional[Token]
4126            side: t.Optional[Token]
4127            kind: t.Optional[Token]
4128
4129            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
4130
4131            if method:
4132                join.set("method", method.text)
4133            if side:
4134                join.set("side", side.text)
4135            if kind:
4136                join.set("kind", kind.text)
4137
4138        if on:
4139            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
4140            join.set("on", on)
4141
4142        if using:
4143            join = _apply_list_builder(
4144                *ensure_list(using),
4145                instance=join,
4146                arg="using",
4147                append=append,
4148                copy=copy,
4149                into=Identifier,
4150                **opts,
4151            )
4152
4153        if join_alias:
4154            join.set("this", alias_(join.this, join_alias, table=True))
4155
4156        return _apply_list_builder(
4157            join,
4158            instance=self,
4159            arg="joins",
4160            append=append,
4161            copy=copy,
4162            **opts,
4163        )

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 having( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4165    def having(
4166        self,
4167        *expressions: t.Optional[ExpOrStr],
4168        append: bool = True,
4169        dialect: DialectType = None,
4170        copy: bool = True,
4171        **opts,
4172    ) -> Select:
4173        """
4174        Append to or set the HAVING expressions.
4175
4176        Example:
4177            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4178            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4179
4180        Args:
4181            *expressions: the SQL code strings to parse.
4182                If an `Expression` instance is passed, it will be used as-is.
4183                Multiple expressions are combined with an AND operator.
4184            append: if `True`, AND the new expressions to any existing expression.
4185                Otherwise, this resets the expression.
4186            dialect: the dialect used to parse the input expressions.
4187            copy: if `False`, modify this expression instance in-place.
4188            opts: other options to use to parse the input expressions.
4189
4190        Returns:
4191            The modified Select expression.
4192        """
4193        return _apply_conjunction_builder(
4194            *expressions,
4195            instance=self,
4196            arg="having",
4197            append=append,
4198            into=Having,
4199            dialect=dialect,
4200            copy=copy,
4201            **opts,
4202        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4204    def window(
4205        self,
4206        *expressions: t.Optional[ExpOrStr],
4207        append: bool = True,
4208        dialect: DialectType = None,
4209        copy: bool = True,
4210        **opts,
4211    ) -> Select:
4212        return _apply_list_builder(
4213            *expressions,
4214            instance=self,
4215            arg="windows",
4216            append=append,
4217            into=Window,
4218            dialect=dialect,
4219            copy=copy,
4220            **opts,
4221        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4223    def qualify(
4224        self,
4225        *expressions: t.Optional[ExpOrStr],
4226        append: bool = True,
4227        dialect: DialectType = None,
4228        copy: bool = True,
4229        **opts,
4230    ) -> Select:
4231        return _apply_conjunction_builder(
4232            *expressions,
4233            instance=self,
4234            arg="qualify",
4235            append=append,
4236            into=Qualify,
4237            dialect=dialect,
4238            copy=copy,
4239            **opts,
4240        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4242    def distinct(
4243        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4244    ) -> Select:
4245        """
4246        Set the OFFSET expression.
4247
4248        Example:
4249            >>> Select().from_("tbl").select("x").distinct().sql()
4250            'SELECT DISTINCT x FROM tbl'
4251
4252        Args:
4253            ons: the expressions to distinct on
4254            distinct: whether the Select should be distinct
4255            copy: if `False`, modify this expression instance in-place.
4256
4257        Returns:
4258            Select: the modified expression.
4259        """
4260        instance = maybe_copy(self, copy)
4261        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4262        instance.set("distinct", Distinct(on=on) if distinct else None)
4263        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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
4265    def ctas(
4266        self,
4267        table: ExpOrStr,
4268        properties: t.Optional[t.Dict] = None,
4269        dialect: DialectType = None,
4270        copy: bool = True,
4271        **opts,
4272    ) -> Create:
4273        """
4274        Convert this expression to a CREATE TABLE AS statement.
4275
4276        Example:
4277            >>> Select().select("*").from_("tbl").ctas("x").sql()
4278            'CREATE TABLE x AS SELECT * FROM tbl'
4279
4280        Args:
4281            table: the SQL code string to parse as the table name.
4282                If another `Expression` instance is passed, it will be used as-is.
4283            properties: an optional mapping of table properties
4284            dialect: the dialect used to parse the input table.
4285            copy: if `False`, modify this expression instance in-place.
4286            opts: other options to use to parse the input table.
4287
4288        Returns:
4289            The new Create expression.
4290        """
4291        instance = maybe_copy(self, copy)
4292        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4293
4294        properties_expression = None
4295        if properties:
4296            properties_expression = Properties.from_dict(properties)
4297
4298        return Create(
4299            this=table_expression,
4300            kind="TABLE",
4301            expression=instance,
4302            properties=properties_expression,
4303        )

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:
4305    def lock(self, update: bool = True, copy: bool = True) -> Select:
4306        """
4307        Set the locking read mode for this expression.
4308
4309        Examples:
4310            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4311            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4312
4313            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4314            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4315
4316        Args:
4317            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4318            copy: if `False`, modify this expression instance in-place.
4319
4320        Returns:
4321            The modified expression.
4322        """
4323        inst = maybe_copy(self, copy)
4324        inst.set("locks", [Lock(update=update)])
4325
4326        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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Select:
4328    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4329        """
4330        Set hints for this expression.
4331
4332        Examples:
4333            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4334            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4335
4336        Args:
4337            hints: The SQL code strings to parse as the hints.
4338                If an `Expression` instance is passed, it will be used as-is.
4339            dialect: The dialect used to parse the hints.
4340            copy: If `False`, modify this expression instance in-place.
4341
4342        Returns:
4343            The modified expression.
4344        """
4345        inst = maybe_copy(self, copy)
4346        inst.set(
4347            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4348        )
4349
4350        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]
4352    @property
4353    def named_selects(self) -> t.List[str]:
4354        selects = []
4355
4356        for e in self.expressions:
4357            if e.alias_or_name:
4358                selects.append(e.output_name)
4359            elif isinstance(e, Aliases):
4360                selects.extend([a.name for a in e.aliases])
4361        return selects

Returns the output names of the query's projections.

is_star: bool
4363    @property
4364    def is_star(self) -> bool:
4365        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4367    @property
4368    def selects(self) -> t.List[Expression]:
4369        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4375class Subquery(DerivedTable, Query):
4376    arg_types = {
4377        "this": True,
4378        "alias": False,
4379        "with": False,
4380        **QUERY_MODIFIERS,
4381    }
4382
4383    def unnest(self):
4384        """Returns the first non subquery."""
4385        expression = self
4386        while isinstance(expression, Subquery):
4387            expression = expression.this
4388        return expression
4389
4390    def unwrap(self) -> Subquery:
4391        expression = self
4392        while expression.same_parent and expression.is_wrapper:
4393            expression = t.cast(Subquery, expression.parent)
4394        return expression
4395
4396    def select(
4397        self,
4398        *expressions: t.Optional[ExpOrStr],
4399        append: bool = True,
4400        dialect: DialectType = None,
4401        copy: bool = True,
4402        **opts,
4403    ) -> Subquery:
4404        this = maybe_copy(self, copy)
4405        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4406        return this
4407
4408    @property
4409    def is_wrapper(self) -> bool:
4410        """
4411        Whether this Subquery acts as a simple wrapper around another expression.
4412
4413        SELECT * FROM (((SELECT * FROM t)))
4414                      ^
4415                      This corresponds to a "wrapper" Subquery node
4416        """
4417        return all(v is None for k, v in self.args.items() if k != "this")
4418
4419    @property
4420    def is_star(self) -> bool:
4421        return self.this.is_star
4422
4423    @property
4424    def output_name(self) -> str:
4425        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):
4383    def unnest(self):
4384        """Returns the first non subquery."""
4385        expression = self
4386        while isinstance(expression, Subquery):
4387            expression = expression.this
4388        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4390    def unwrap(self) -> Subquery:
4391        expression = self
4392        while expression.same_parent and expression.is_wrapper:
4393            expression = t.cast(Subquery, expression.parent)
4394        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
4396    def select(
4397        self,
4398        *expressions: t.Optional[ExpOrStr],
4399        append: bool = True,
4400        dialect: DialectType = None,
4401        copy: bool = True,
4402        **opts,
4403    ) -> Subquery:
4404        this = maybe_copy(self, copy)
4405        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4406        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
4408    @property
4409    def is_wrapper(self) -> bool:
4410        """
4411        Whether this Subquery acts as a simple wrapper around another expression.
4412
4413        SELECT * FROM (((SELECT * FROM t)))
4414                      ^
4415                      This corresponds to a "wrapper" Subquery node
4416        """
4417        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
4419    @property
4420    def is_star(self) -> bool:
4421        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4423    @property
4424    def output_name(self) -> str:
4425        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):
4428class TableSample(Expression):
4429    arg_types = {
4430        "expressions": False,
4431        "method": False,
4432        "bucket_numerator": False,
4433        "bucket_denominator": False,
4434        "bucket_field": False,
4435        "percent": False,
4436        "rows": False,
4437        "size": False,
4438        "seed": False,
4439    }
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):
4442class Tag(Expression):
4443    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4444
4445    arg_types = {
4446        "this": False,
4447        "prefix": False,
4448        "postfix": False,
4449    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4454class Pivot(Expression):
4455    arg_types = {
4456        "this": False,
4457        "alias": False,
4458        "expressions": False,
4459        "fields": False,
4460        "unpivot": False,
4461        "using": False,
4462        "group": False,
4463        "columns": False,
4464        "include_nulls": False,
4465        "default_on_null": False,
4466        "into": False,
4467    }
4468
4469    @property
4470    def unpivot(self) -> bool:
4471        return bool(self.args.get("unpivot"))
4472
4473    @property
4474    def fields(self) -> t.List[Expression]:
4475        return self.args.get("fields", [])
arg_types = {'this': False, 'alias': False, 'expressions': False, 'fields': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False, 'into': False}
unpivot: bool
4469    @property
4470    def unpivot(self) -> bool:
4471        return bool(self.args.get("unpivot"))
fields: List[Expression]
4473    @property
4474    def fields(self) -> t.List[Expression]:
4475        return self.args.get("fields", [])
key = 'pivot'
class UnpivotColumns(Expression):
4480class UnpivotColumns(Expression):
4481    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4484class Window(Condition):
4485    arg_types = {
4486        "this": True,
4487        "partition_by": False,
4488        "order": False,
4489        "spec": False,
4490        "alias": False,
4491        "over": False,
4492        "first": False,
4493    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4496class WindowSpec(Expression):
4497    arg_types = {
4498        "kind": False,
4499        "start": False,
4500        "start_side": False,
4501        "end": False,
4502        "end_side": False,
4503        "exclude": False,
4504    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False, 'exclude': False}
key = 'windowspec'
class PreWhere(Expression):
4507class PreWhere(Expression):
4508    pass
key = 'prewhere'
class Where(Expression):
4511class Where(Expression):
4512    pass
key = 'where'
class Star(Expression):
4515class Star(Expression):
4516    arg_types = {"except": False, "replace": False, "rename": False}
4517
4518    @property
4519    def name(self) -> str:
4520        return "*"
4521
4522    @property
4523    def output_name(self) -> str:
4524        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4518    @property
4519    def name(self) -> str:
4520        return "*"
output_name: str
4522    @property
4523    def output_name(self) -> str:
4524        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):
4527class Parameter(Condition):
4528    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4531class SessionParameter(Condition):
4532    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4537class Placeholder(Condition):
4538    arg_types = {"this": False, "kind": False, "widget": False, "jdbc": False}
4539
4540    @property
4541    def name(self) -> str:
4542        return self.this or "?"
arg_types = {'this': False, 'kind': False, 'widget': False, 'jdbc': False}
name: str
4540    @property
4541    def name(self) -> str:
4542        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4545class Null(Condition):
4546    arg_types: t.Dict[str, t.Any] = {}
4547
4548    @property
4549    def name(self) -> str:
4550        return "NULL"
4551
4552    def to_py(self) -> Lit[None]:
4553        return None
arg_types: Dict[str, Any] = {}
name: str
4548    @property
4549    def name(self) -> str:
4550        return "NULL"
def to_py(self) -> Literal[None]:
4552    def to_py(self) -> Lit[None]:
4553        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4556class Boolean(Condition):
4557    def to_py(self) -> bool:
4558        return self.this
def to_py(self) -> bool:
4557    def to_py(self) -> bool:
4558        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4561class DataTypeParam(Expression):
4562    arg_types = {"this": True, "expression": False}
4563
4564    @property
4565    def name(self) -> str:
4566        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4564    @property
4565    def name(self) -> str:
4566        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4571class DataType(Expression):
4572    arg_types = {
4573        "this": True,
4574        "expressions": False,
4575        "nested": False,
4576        "values": False,
4577        "prefix": False,
4578        "kind": False,
4579        "nullable": False,
4580    }
4581
4582    class Type(AutoName):
4583        ARRAY = auto()
4584        AGGREGATEFUNCTION = auto()
4585        SIMPLEAGGREGATEFUNCTION = auto()
4586        BIGDECIMAL = auto()
4587        BIGINT = auto()
4588        BIGSERIAL = auto()
4589        BINARY = auto()
4590        BIT = auto()
4591        BLOB = auto()
4592        BOOLEAN = auto()
4593        BPCHAR = auto()
4594        CHAR = auto()
4595        DATE = auto()
4596        DATE32 = auto()
4597        DATEMULTIRANGE = auto()
4598        DATERANGE = auto()
4599        DATETIME = auto()
4600        DATETIME2 = auto()
4601        DATETIME64 = auto()
4602        DECIMAL = auto()
4603        DECIMAL32 = auto()
4604        DECIMAL64 = auto()
4605        DECIMAL128 = auto()
4606        DECIMAL256 = auto()
4607        DOUBLE = auto()
4608        DYNAMIC = auto()
4609        ENUM = auto()
4610        ENUM8 = auto()
4611        ENUM16 = auto()
4612        FIXEDSTRING = auto()
4613        FLOAT = auto()
4614        GEOGRAPHY = auto()
4615        GEOGRAPHYPOINT = auto()
4616        GEOMETRY = auto()
4617        POINT = auto()
4618        RING = auto()
4619        LINESTRING = auto()
4620        MULTILINESTRING = auto()
4621        POLYGON = auto()
4622        MULTIPOLYGON = auto()
4623        HLLSKETCH = auto()
4624        HSTORE = auto()
4625        IMAGE = auto()
4626        INET = auto()
4627        INT = auto()
4628        INT128 = auto()
4629        INT256 = auto()
4630        INT4MULTIRANGE = auto()
4631        INT4RANGE = auto()
4632        INT8MULTIRANGE = auto()
4633        INT8RANGE = auto()
4634        INTERVAL = auto()
4635        IPADDRESS = auto()
4636        IPPREFIX = auto()
4637        IPV4 = auto()
4638        IPV6 = auto()
4639        JSON = auto()
4640        JSONB = auto()
4641        LIST = auto()
4642        LONGBLOB = auto()
4643        LONGTEXT = auto()
4644        LOWCARDINALITY = auto()
4645        MAP = auto()
4646        MEDIUMBLOB = auto()
4647        MEDIUMINT = auto()
4648        MEDIUMTEXT = auto()
4649        MONEY = auto()
4650        NAME = auto()
4651        NCHAR = auto()
4652        NESTED = auto()
4653        NOTHING = auto()
4654        NULL = auto()
4655        NUMMULTIRANGE = auto()
4656        NUMRANGE = auto()
4657        NVARCHAR = auto()
4658        OBJECT = auto()
4659        RANGE = auto()
4660        ROWVERSION = auto()
4661        SERIAL = auto()
4662        SET = auto()
4663        SMALLDATETIME = auto()
4664        SMALLINT = auto()
4665        SMALLMONEY = auto()
4666        SMALLSERIAL = auto()
4667        STRUCT = auto()
4668        SUPER = auto()
4669        TEXT = auto()
4670        TINYBLOB = auto()
4671        TINYTEXT = auto()
4672        TIME = auto()
4673        TIMETZ = auto()
4674        TIMESTAMP = auto()
4675        TIMESTAMPNTZ = auto()
4676        TIMESTAMPLTZ = auto()
4677        TIMESTAMPTZ = auto()
4678        TIMESTAMP_S = auto()
4679        TIMESTAMP_MS = auto()
4680        TIMESTAMP_NS = auto()
4681        TINYINT = auto()
4682        TSMULTIRANGE = auto()
4683        TSRANGE = auto()
4684        TSTZMULTIRANGE = auto()
4685        TSTZRANGE = auto()
4686        UBIGINT = auto()
4687        UINT = auto()
4688        UINT128 = auto()
4689        UINT256 = auto()
4690        UMEDIUMINT = auto()
4691        UDECIMAL = auto()
4692        UDOUBLE = auto()
4693        UNION = auto()
4694        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4695        USERDEFINED = "USER-DEFINED"
4696        USMALLINT = auto()
4697        UTINYINT = auto()
4698        UUID = auto()
4699        VARBINARY = auto()
4700        VARCHAR = auto()
4701        VARIANT = auto()
4702        VECTOR = auto()
4703        XML = auto()
4704        YEAR = auto()
4705        TDIGEST = auto()
4706
4707    STRUCT_TYPES = {
4708        Type.NESTED,
4709        Type.OBJECT,
4710        Type.STRUCT,
4711        Type.UNION,
4712    }
4713
4714    ARRAY_TYPES = {
4715        Type.ARRAY,
4716        Type.LIST,
4717    }
4718
4719    NESTED_TYPES = {
4720        *STRUCT_TYPES,
4721        *ARRAY_TYPES,
4722        Type.MAP,
4723    }
4724
4725    TEXT_TYPES = {
4726        Type.CHAR,
4727        Type.NCHAR,
4728        Type.NVARCHAR,
4729        Type.TEXT,
4730        Type.VARCHAR,
4731        Type.NAME,
4732    }
4733
4734    SIGNED_INTEGER_TYPES = {
4735        Type.BIGINT,
4736        Type.INT,
4737        Type.INT128,
4738        Type.INT256,
4739        Type.MEDIUMINT,
4740        Type.SMALLINT,
4741        Type.TINYINT,
4742    }
4743
4744    UNSIGNED_INTEGER_TYPES = {
4745        Type.UBIGINT,
4746        Type.UINT,
4747        Type.UINT128,
4748        Type.UINT256,
4749        Type.UMEDIUMINT,
4750        Type.USMALLINT,
4751        Type.UTINYINT,
4752    }
4753
4754    INTEGER_TYPES = {
4755        *SIGNED_INTEGER_TYPES,
4756        *UNSIGNED_INTEGER_TYPES,
4757        Type.BIT,
4758    }
4759
4760    FLOAT_TYPES = {
4761        Type.DOUBLE,
4762        Type.FLOAT,
4763    }
4764
4765    REAL_TYPES = {
4766        *FLOAT_TYPES,
4767        Type.BIGDECIMAL,
4768        Type.DECIMAL,
4769        Type.DECIMAL32,
4770        Type.DECIMAL64,
4771        Type.DECIMAL128,
4772        Type.DECIMAL256,
4773        Type.MONEY,
4774        Type.SMALLMONEY,
4775        Type.UDECIMAL,
4776        Type.UDOUBLE,
4777    }
4778
4779    NUMERIC_TYPES = {
4780        *INTEGER_TYPES,
4781        *REAL_TYPES,
4782    }
4783
4784    TEMPORAL_TYPES = {
4785        Type.DATE,
4786        Type.DATE32,
4787        Type.DATETIME,
4788        Type.DATETIME2,
4789        Type.DATETIME64,
4790        Type.SMALLDATETIME,
4791        Type.TIME,
4792        Type.TIMESTAMP,
4793        Type.TIMESTAMPNTZ,
4794        Type.TIMESTAMPLTZ,
4795        Type.TIMESTAMPTZ,
4796        Type.TIMESTAMP_MS,
4797        Type.TIMESTAMP_NS,
4798        Type.TIMESTAMP_S,
4799        Type.TIMETZ,
4800    }
4801
4802    @classmethod
4803    def build(
4804        cls,
4805        dtype: DATA_TYPE,
4806        dialect: DialectType = None,
4807        udt: bool = False,
4808        copy: bool = True,
4809        **kwargs,
4810    ) -> DataType:
4811        """
4812        Constructs a DataType object.
4813
4814        Args:
4815            dtype: the data type of interest.
4816            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4817            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4818                DataType, thus creating a user-defined type.
4819            copy: whether to copy the data type.
4820            kwargs: additional arguments to pass in the constructor of DataType.
4821
4822        Returns:
4823            The constructed DataType object.
4824        """
4825        from sqlglot import parse_one
4826
4827        if isinstance(dtype, str):
4828            if dtype.upper() == "UNKNOWN":
4829                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4830
4831            try:
4832                data_type_exp = parse_one(
4833                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4834                )
4835            except ParseError:
4836                if udt:
4837                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4838                raise
4839        elif isinstance(dtype, (Identifier, Dot)) and udt:
4840            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4841        elif isinstance(dtype, DataType.Type):
4842            data_type_exp = DataType(this=dtype)
4843        elif isinstance(dtype, DataType):
4844            return maybe_copy(dtype, copy)
4845        else:
4846            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4847
4848        return DataType(**{**data_type_exp.args, **kwargs})
4849
4850    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4851        """
4852        Checks whether this DataType matches one of the provided data types. Nested types or precision
4853        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4854
4855        Args:
4856            dtypes: the data types to compare this DataType to.
4857            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4858                If false, it means that NULLABLE<INT> is equivalent to INT.
4859
4860        Returns:
4861            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4862        """
4863        self_is_nullable = self.args.get("nullable")
4864        for dtype in dtypes:
4865            other_type = DataType.build(dtype, copy=False, udt=True)
4866            other_is_nullable = other_type.args.get("nullable")
4867            if (
4868                other_type.expressions
4869                or (check_nullable and (self_is_nullable or other_is_nullable))
4870                or self.this == DataType.Type.USERDEFINED
4871                or other_type.this == DataType.Type.USERDEFINED
4872            ):
4873                matches = self == other_type
4874            else:
4875                matches = self.this == other_type.this
4876
4877            if matches:
4878                return True
4879        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.UNION: 'UNION'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.UNION: 'UNION'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.STRUCT: 'STRUCT'>, <Type.ARRAY: 'ARRAY'>, <Type.MAP: 'MAP'>, <Type.LIST: 'LIST'>}
TEXT_TYPES = {<Type.TEXT: 'TEXT'>, <Type.CHAR: 'CHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.NAME: 'NAME'>, <Type.NCHAR: 'NCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.TINYINT: 'TINYINT'>, <Type.INT256: 'INT256'>, <Type.BIGINT: 'BIGINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.SMALLINT: 'SMALLINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT: 'UINT'>, <Type.UINT128: 'UINT128'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT256: 'UINT256'>}
INTEGER_TYPES = {<Type.USMALLINT: 'USMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.INT256: 'INT256'>, <Type.UINT: 'UINT'>, <Type.BIGINT: 'BIGINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UINT128: 'UINT128'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.BIT: 'BIT'>, <Type.UINT256: 'UINT256'>, <Type.SMALLINT: 'SMALLINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL: 'DECIMAL'>, <Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.MONEY: 'MONEY'>}
NUMERIC_TYPES = {<Type.UINT: 'UINT'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.INT128: 'INT128'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL: 'DECIMAL'>, <Type.FLOAT: 'FLOAT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.MONEY: 'MONEY'>, <Type.USMALLINT: 'USMALLINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.INT256: 'INT256'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.BIGINT: 'BIGINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UINT128: 'UINT128'>, <Type.INT: 'INT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.BIT: 'BIT'>, <Type.UINT256: 'UINT256'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLINT: 'SMALLINT'>}
TEMPORAL_TYPES = {<Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATETIME: 'DATETIME'>, <Type.TIMETZ: 'TIMETZ'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.DATETIME2: 'DATETIME2'>, <Type.TIME: 'TIME'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>}
@classmethod
def build( cls, dtype: Union[str, Identifier, Dot, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4802    @classmethod
4803    def build(
4804        cls,
4805        dtype: DATA_TYPE,
4806        dialect: DialectType = None,
4807        udt: bool = False,
4808        copy: bool = True,
4809        **kwargs,
4810    ) -> DataType:
4811        """
4812        Constructs a DataType object.
4813
4814        Args:
4815            dtype: the data type of interest.
4816            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4817            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4818                DataType, thus creating a user-defined type.
4819            copy: whether to copy the data type.
4820            kwargs: additional arguments to pass in the constructor of DataType.
4821
4822        Returns:
4823            The constructed DataType object.
4824        """
4825        from sqlglot import parse_one
4826
4827        if isinstance(dtype, str):
4828            if dtype.upper() == "UNKNOWN":
4829                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4830
4831            try:
4832                data_type_exp = parse_one(
4833                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4834                )
4835            except ParseError:
4836                if udt:
4837                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4838                raise
4839        elif isinstance(dtype, (Identifier, Dot)) and udt:
4840            return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4841        elif isinstance(dtype, DataType.Type):
4842            data_type_exp = DataType(this=dtype)
4843        elif isinstance(dtype, DataType):
4844            return maybe_copy(dtype, copy)
4845        else:
4846            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4847
4848        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, Identifier, Dot, DataType, DataType.Type], check_nullable: bool = False) -> bool:
4850    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4851        """
4852        Checks whether this DataType matches one of the provided data types. Nested types or precision
4853        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4854
4855        Args:
4856            dtypes: the data types to compare this DataType to.
4857            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4858                If false, it means that NULLABLE<INT> is equivalent to INT.
4859
4860        Returns:
4861            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4862        """
4863        self_is_nullable = self.args.get("nullable")
4864        for dtype in dtypes:
4865            other_type = DataType.build(dtype, copy=False, udt=True)
4866            other_is_nullable = other_type.args.get("nullable")
4867            if (
4868                other_type.expressions
4869                or (check_nullable and (self_is_nullable or other_is_nullable))
4870                or self.this == DataType.Type.USERDEFINED
4871                or other_type.this == DataType.Type.USERDEFINED
4872            ):
4873                matches = self == other_type
4874            else:
4875                matches = self.this == other_type.this
4876
4877            if matches:
4878                return True
4879        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):
4582    class Type(AutoName):
4583        ARRAY = auto()
4584        AGGREGATEFUNCTION = auto()
4585        SIMPLEAGGREGATEFUNCTION = auto()
4586        BIGDECIMAL = auto()
4587        BIGINT = auto()
4588        BIGSERIAL = auto()
4589        BINARY = auto()
4590        BIT = auto()
4591        BLOB = auto()
4592        BOOLEAN = auto()
4593        BPCHAR = auto()
4594        CHAR = auto()
4595        DATE = auto()
4596        DATE32 = auto()
4597        DATEMULTIRANGE = auto()
4598        DATERANGE = auto()
4599        DATETIME = auto()
4600        DATETIME2 = auto()
4601        DATETIME64 = auto()
4602        DECIMAL = auto()
4603        DECIMAL32 = auto()
4604        DECIMAL64 = auto()
4605        DECIMAL128 = auto()
4606        DECIMAL256 = auto()
4607        DOUBLE = auto()
4608        DYNAMIC = auto()
4609        ENUM = auto()
4610        ENUM8 = auto()
4611        ENUM16 = auto()
4612        FIXEDSTRING = auto()
4613        FLOAT = auto()
4614        GEOGRAPHY = auto()
4615        GEOGRAPHYPOINT = auto()
4616        GEOMETRY = auto()
4617        POINT = auto()
4618        RING = auto()
4619        LINESTRING = auto()
4620        MULTILINESTRING = auto()
4621        POLYGON = auto()
4622        MULTIPOLYGON = auto()
4623        HLLSKETCH = auto()
4624        HSTORE = auto()
4625        IMAGE = auto()
4626        INET = auto()
4627        INT = auto()
4628        INT128 = auto()
4629        INT256 = auto()
4630        INT4MULTIRANGE = auto()
4631        INT4RANGE = auto()
4632        INT8MULTIRANGE = auto()
4633        INT8RANGE = auto()
4634        INTERVAL = auto()
4635        IPADDRESS = auto()
4636        IPPREFIX = auto()
4637        IPV4 = auto()
4638        IPV6 = auto()
4639        JSON = auto()
4640        JSONB = auto()
4641        LIST = auto()
4642        LONGBLOB = auto()
4643        LONGTEXT = auto()
4644        LOWCARDINALITY = auto()
4645        MAP = auto()
4646        MEDIUMBLOB = auto()
4647        MEDIUMINT = auto()
4648        MEDIUMTEXT = auto()
4649        MONEY = auto()
4650        NAME = auto()
4651        NCHAR = auto()
4652        NESTED = auto()
4653        NOTHING = auto()
4654        NULL = auto()
4655        NUMMULTIRANGE = auto()
4656        NUMRANGE = auto()
4657        NVARCHAR = auto()
4658        OBJECT = auto()
4659        RANGE = auto()
4660        ROWVERSION = auto()
4661        SERIAL = auto()
4662        SET = auto()
4663        SMALLDATETIME = auto()
4664        SMALLINT = auto()
4665        SMALLMONEY = auto()
4666        SMALLSERIAL = auto()
4667        STRUCT = auto()
4668        SUPER = auto()
4669        TEXT = auto()
4670        TINYBLOB = auto()
4671        TINYTEXT = auto()
4672        TIME = auto()
4673        TIMETZ = auto()
4674        TIMESTAMP = auto()
4675        TIMESTAMPNTZ = auto()
4676        TIMESTAMPLTZ = auto()
4677        TIMESTAMPTZ = auto()
4678        TIMESTAMP_S = auto()
4679        TIMESTAMP_MS = auto()
4680        TIMESTAMP_NS = auto()
4681        TINYINT = auto()
4682        TSMULTIRANGE = auto()
4683        TSRANGE = auto()
4684        TSTZMULTIRANGE = auto()
4685        TSTZRANGE = auto()
4686        UBIGINT = auto()
4687        UINT = auto()
4688        UINT128 = auto()
4689        UINT256 = auto()
4690        UMEDIUMINT = auto()
4691        UDECIMAL = auto()
4692        UDOUBLE = auto()
4693        UNION = auto()
4694        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4695        USERDEFINED = "USER-DEFINED"
4696        USMALLINT = auto()
4697        UTINYINT = auto()
4698        UUID = auto()
4699        VARBINARY = auto()
4700        VARCHAR = auto()
4701        VARIANT = auto()
4702        VECTOR = auto()
4703        XML = auto()
4704        YEAR = auto()
4705        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'>
BLOB = <Type.BLOB: 'BLOB'>
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'>
DATETIME2 = <Type.DATETIME2: 'DATETIME2'>
DATETIME64 = <Type.DATETIME64: 'DATETIME64'>
DECIMAL = <Type.DECIMAL: 'DECIMAL'>
DECIMAL32 = <Type.DECIMAL32: 'DECIMAL32'>
DECIMAL64 = <Type.DECIMAL64: 'DECIMAL64'>
DECIMAL128 = <Type.DECIMAL128: 'DECIMAL128'>
DECIMAL256 = <Type.DECIMAL256: 'DECIMAL256'>
DOUBLE = <Type.DOUBLE: 'DOUBLE'>
DYNAMIC = <Type.DYNAMIC: 'DYNAMIC'>
ENUM = <Type.ENUM: 'ENUM'>
ENUM8 = <Type.ENUM8: 'ENUM8'>
ENUM16 = <Type.ENUM16: 'ENUM16'>
FIXEDSTRING = <Type.FIXEDSTRING: 'FIXEDSTRING'>
FLOAT = <Type.FLOAT: 'FLOAT'>
GEOGRAPHY = <Type.GEOGRAPHY: 'GEOGRAPHY'>
GEOGRAPHYPOINT = <Type.GEOGRAPHYPOINT: 'GEOGRAPHYPOINT'>
GEOMETRY = <Type.GEOMETRY: 'GEOMETRY'>
POINT = <Type.POINT: 'POINT'>
RING = <Type.RING: 'RING'>
LINESTRING = <Type.LINESTRING: 'LINESTRING'>
MULTILINESTRING = <Type.MULTILINESTRING: 'MULTILINESTRING'>
POLYGON = <Type.POLYGON: 'POLYGON'>
MULTIPOLYGON = <Type.MULTIPOLYGON: 'MULTIPOLYGON'>
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'>
NOTHING = <Type.NOTHING: 'NOTHING'>
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'>
SMALLDATETIME = <Type.SMALLDATETIME: 'SMALLDATETIME'>
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'>
UDOUBLE = <Type.UDOUBLE: 'UDOUBLE'>
UNION = <Type.UNION: 'UNION'>
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'>
class PseudoType(DataType):
4883class PseudoType(DataType):
4884    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4888class ObjectIdentifier(DataType):
4889    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4893class SubqueryPredicate(Predicate):
4894    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4897class All(SubqueryPredicate):
4898    pass
key = 'all'
class Any(SubqueryPredicate):
4901class Any(SubqueryPredicate):
4902    pass
key = 'any'
class Command(Expression):
4907class Command(Expression):
4908    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4911class Transaction(Expression):
4912    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4915class Commit(Expression):
4916    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4919class Rollback(Expression):
4920    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4923class Alter(Expression):
4924    arg_types = {
4925        "this": False,
4926        "kind": True,
4927        "actions": True,
4928        "exists": False,
4929        "only": False,
4930        "options": False,
4931        "cluster": False,
4932        "not_valid": False,
4933        "check": False,
4934    }
4935
4936    @property
4937    def kind(self) -> t.Optional[str]:
4938        kind = self.args.get("kind")
4939        return kind and kind.upper()
4940
4941    @property
4942    def actions(self) -> t.List[Expression]:
4943        return self.args.get("actions") or []
arg_types = {'this': False, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False, 'not_valid': False, 'check': False}
kind: Optional[str]
4936    @property
4937    def kind(self) -> t.Optional[str]:
4938        kind = self.args.get("kind")
4939        return kind and kind.upper()
actions: List[Expression]
4941    @property
4942    def actions(self) -> t.List[Expression]:
4943        return self.args.get("actions") or []
key = 'alter'
class AlterSession(Expression):
4946class AlterSession(Expression):
4947    arg_types = {"expressions": True, "unset": False}
arg_types = {'expressions': True, 'unset': False}
key = 'altersession'
class Analyze(Expression):
4950class Analyze(Expression):
4951    arg_types = {
4952        "kind": False,
4953        "this": False,
4954        "options": False,
4955        "mode": False,
4956        "partition": False,
4957        "expression": False,
4958        "properties": False,
4959    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4962class AnalyzeStatistics(Expression):
4963    arg_types = {
4964        "kind": True,
4965        "option": False,
4966        "this": False,
4967        "expressions": False,
4968    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4971class AnalyzeHistogram(Expression):
4972    arg_types = {
4973        "this": True,
4974        "expressions": True,
4975        "expression": False,
4976        "update_options": False,
4977    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4980class AnalyzeSample(Expression):
4981    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4984class AnalyzeListChainedRows(Expression):
4985    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4988class AnalyzeDelete(Expression):
4989    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4992class AnalyzeWith(Expression):
4993    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4996class AnalyzeValidate(Expression):
4997    arg_types = {
4998        "kind": True,
4999        "this": False,
5000        "expression": False,
5001    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
5004class AnalyzeColumns(Expression):
5005    pass
key = 'analyzecolumns'
class UsingData(Expression):
5008class UsingData(Expression):
5009    pass
key = 'usingdata'
class AddConstraint(Expression):
5012class AddConstraint(Expression):
5013    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AddPartition(Expression):
5016class AddPartition(Expression):
5017    arg_types = {"this": True, "exists": False, "location": False}
arg_types = {'this': True, 'exists': False, 'location': False}
key = 'addpartition'
class AttachOption(Expression):
5020class AttachOption(Expression):
5021    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
5024class DropPartition(Expression):
5025    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
5029class ReplacePartition(Expression):
5030    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
5034class Binary(Condition):
5035    arg_types = {"this": True, "expression": True}
5036
5037    @property
5038    def left(self) -> Expression:
5039        return self.this
5040
5041    @property
5042    def right(self) -> Expression:
5043        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
5037    @property
5038    def left(self) -> Expression:
5039        return self.this
right: Expression
5041    @property
5042    def right(self) -> Expression:
5043        return self.expression
key = 'binary'
class Add(Binary):
5046class Add(Binary):
5047    pass
key = 'add'
class Connector(Binary):
5050class Connector(Binary):
5051    pass
key = 'connector'
class BitwiseAnd(Binary):
5054class BitwiseAnd(Binary):
5055    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
5058class BitwiseLeftShift(Binary):
5059    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
5062class BitwiseOr(Binary):
5063    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
5066class BitwiseRightShift(Binary):
5067    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
5070class BitwiseXor(Binary):
5071    pass
key = 'bitwisexor'
class Div(Binary):
5074class Div(Binary):
5075    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):
5078class Overlaps(Binary):
5079    pass
key = 'overlaps'
class Dot(Binary):
5082class Dot(Binary):
5083    @property
5084    def is_star(self) -> bool:
5085        return self.expression.is_star
5086
5087    @property
5088    def name(self) -> str:
5089        return self.expression.name
5090
5091    @property
5092    def output_name(self) -> str:
5093        return self.name
5094
5095    @classmethod
5096    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5097        """Build a Dot object with a sequence of expressions."""
5098        if len(expressions) < 2:
5099            raise ValueError("Dot requires >= 2 expressions.")
5100
5101        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
5102
5103    @property
5104    def parts(self) -> t.List[Expression]:
5105        """Return the parts of a table / column in order catalog, db, table."""
5106        this, *parts = self.flatten()
5107
5108        parts.reverse()
5109
5110        for arg in COLUMN_PARTS:
5111            part = this.args.get(arg)
5112
5113            if isinstance(part, Expression):
5114                parts.append(part)
5115
5116        parts.reverse()
5117        return parts
is_star: bool
5083    @property
5084    def is_star(self) -> bool:
5085        return self.expression.is_star

Checks whether an expression is a star.

name: str
5087    @property
5088    def name(self) -> str:
5089        return self.expression.name
output_name: str
5091    @property
5092    def output_name(self) -> str:
5093        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:
5095    @classmethod
5096    def build(self, expressions: t.Sequence[Expression]) -> Dot:
5097        """Build a Dot object with a sequence of expressions."""
5098        if len(expressions) < 2:
5099            raise ValueError("Dot requires >= 2 expressions.")
5100
5101        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]
5103    @property
5104    def parts(self) -> t.List[Expression]:
5105        """Return the parts of a table / column in order catalog, db, table."""
5106        this, *parts = self.flatten()
5107
5108        parts.reverse()
5109
5110        for arg in COLUMN_PARTS:
5111            part = this.args.get(arg)
5112
5113            if isinstance(part, Expression):
5114                parts.append(part)
5115
5116        parts.reverse()
5117        return parts

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

key = 'dot'
DATA_TYPE = typing.Union[str, Identifier, Dot, DataType, DataType.Type]
class DPipe(Binary):
5123class DPipe(Binary):
5124    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
5127class EQ(Binary, Predicate):
5128    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
5131class NullSafeEQ(Binary, Predicate):
5132    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
5135class NullSafeNEQ(Binary, Predicate):
5136    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
5140class PropertyEQ(Binary):
5141    pass
key = 'propertyeq'
class Distance(Binary):
5144class Distance(Binary):
5145    pass
key = 'distance'
class Escape(Binary):
5148class Escape(Binary):
5149    pass
key = 'escape'
class Glob(Binary, Predicate):
5152class Glob(Binary, Predicate):
5153    pass
key = 'glob'
class GT(Binary, Predicate):
5156class GT(Binary, Predicate):
5157    pass
key = 'gt'
class GTE(Binary, Predicate):
5160class GTE(Binary, Predicate):
5161    pass
key = 'gte'
class ILike(Binary, Predicate):
5164class ILike(Binary, Predicate):
5165    pass
key = 'ilike'
class IntDiv(Binary):
5168class IntDiv(Binary):
5169    pass
key = 'intdiv'
class Is(Binary, Predicate):
5172class Is(Binary, Predicate):
5173    pass
key = 'is'
class Kwarg(Binary):
5176class Kwarg(Binary):
5177    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
5180class Like(Binary, Predicate):
5181    pass
key = 'like'
class LT(Binary, Predicate):
5184class LT(Binary, Predicate):
5185    pass
key = 'lt'
class LTE(Binary, Predicate):
5188class LTE(Binary, Predicate):
5189    pass
key = 'lte'
class Mod(Binary):
5192class Mod(Binary):
5193    pass
key = 'mod'
class Mul(Binary):
5196class Mul(Binary):
5197    pass
key = 'mul'
class NEQ(Binary, Predicate):
5200class NEQ(Binary, Predicate):
5201    pass
key = 'neq'
class Operator(Binary):
5205class Operator(Binary):
5206    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5209class SimilarTo(Binary, Predicate):
5210    pass
key = 'similarto'
class Slice(Binary):
5213class Slice(Binary):
5214    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5217class Sub(Binary):
5218    pass
key = 'sub'
class Unary(Condition):
5223class Unary(Condition):
5224    pass
key = 'unary'
class BitwiseNot(Unary):
5227class BitwiseNot(Unary):
5228    pass
key = 'bitwisenot'
class Not(Unary):
5231class Not(Unary):
5232    pass
key = 'not'
class Paren(Unary):
5235class Paren(Unary):
5236    @property
5237    def output_name(self) -> str:
5238        return self.this.name
output_name: str
5236    @property
5237    def output_name(self) -> str:
5238        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):
5241class Neg(Unary):
5242    def to_py(self) -> int | Decimal:
5243        if self.is_number:
5244            return self.this.to_py() * -1
5245        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5242    def to_py(self) -> int | Decimal:
5243        if self.is_number:
5244            return self.this.to_py() * -1
5245        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5248class Alias(Expression):
5249    arg_types = {"this": True, "alias": False}
5250
5251    @property
5252    def output_name(self) -> str:
5253        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5251    @property
5252    def output_name(self) -> str:
5253        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):
5258class PivotAlias(Alias):
5259    pass
key = 'pivotalias'
class PivotAny(Expression):
5264class PivotAny(Expression):
5265    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5268class Aliases(Expression):
5269    arg_types = {"this": True, "expressions": True}
5270
5271    @property
5272    def aliases(self):
5273        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5271    @property
5272    def aliases(self):
5273        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5277class AtIndex(Expression):
5278    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5281class AtTimeZone(Expression):
5282    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5285class FromTimeZone(Expression):
5286    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class FormatPhrase(Expression):
5289class FormatPhrase(Expression):
5290    """Format override for a column in Teradata.
5291    Can be expanded to additional dialects as needed
5292
5293    https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT
5294    """
5295
5296    arg_types = {"this": True, "format": True}

Format override for a column in Teradata. Can be expanded to additional dialects as needed

https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Data-Types-and-Literals/Data-Type-Formats-and-Format-Phrases/FORMAT

arg_types = {'this': True, 'format': True}
key = 'formatphrase'
class Between(Predicate):
5299class Between(Predicate):
5300    arg_types = {"this": True, "low": True, "high": True, "symmetric": False}
arg_types = {'this': True, 'low': True, 'high': True, 'symmetric': False}
key = 'between'
class Bracket(Condition):
5303class Bracket(Condition):
5304    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5305    arg_types = {
5306        "this": True,
5307        "expressions": True,
5308        "offset": False,
5309        "safe": False,
5310        "returns_list_for_maps": False,
5311    }
5312
5313    @property
5314    def output_name(self) -> str:
5315        if len(self.expressions) == 1:
5316            return self.expressions[0].output_name
5317
5318        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5313    @property
5314    def output_name(self) -> str:
5315        if len(self.expressions) == 1:
5316            return self.expressions[0].output_name
5317
5318        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):
5321class Distinct(Expression):
5322    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5325class In(Predicate):
5326    arg_types = {
5327        "this": True,
5328        "expressions": False,
5329        "query": False,
5330        "unnest": False,
5331        "field": False,
5332        "is_global": False,
5333    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5337class ForIn(Expression):
5338    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5341class TimeUnit(Expression):
5342    """Automatically converts unit arg into a var."""
5343
5344    arg_types = {"unit": False}
5345
5346    UNABBREVIATED_UNIT_NAME = {
5347        "D": "DAY",
5348        "H": "HOUR",
5349        "M": "MINUTE",
5350        "MS": "MILLISECOND",
5351        "NS": "NANOSECOND",
5352        "Q": "QUARTER",
5353        "S": "SECOND",
5354        "US": "MICROSECOND",
5355        "W": "WEEK",
5356        "Y": "YEAR",
5357    }
5358
5359    VAR_LIKE = (Column, Literal, Var)
5360
5361    def __init__(self, **args):
5362        unit = args.get("unit")
5363        if type(unit) in self.VAR_LIKE:
5364            args["unit"] = Var(
5365                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5366            )
5367        elif isinstance(unit, Week):
5368            unit.set("this", Var(this=unit.this.name.upper()))
5369
5370        super().__init__(**args)
5371
5372    @property
5373    def unit(self) -> t.Optional[Var | IntervalSpan]:
5374        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5361    def __init__(self, **args):
5362        unit = args.get("unit")
5363        if type(unit) in self.VAR_LIKE:
5364            args["unit"] = Var(
5365                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5366            )
5367        elif isinstance(unit, Week):
5368            unit.set("this", Var(this=unit.this.name.upper()))
5369
5370        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]
5372    @property
5373    def unit(self) -> t.Optional[Var | IntervalSpan]:
5374        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5377class IntervalOp(TimeUnit):
5378    arg_types = {"unit": False, "expression": True}
5379
5380    def interval(self):
5381        return Interval(
5382            this=self.expression.copy(),
5383            unit=self.unit.copy() if self.unit else None,
5384        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5380    def interval(self):
5381        return Interval(
5382            this=self.expression.copy(),
5383            unit=self.unit.copy() if self.unit else None,
5384        )
key = 'intervalop'
class IntervalSpan(DataType):
5390class IntervalSpan(DataType):
5391    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5394class Interval(TimeUnit):
5395    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5398class IgnoreNulls(Expression):
5399    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5402class RespectNulls(Expression):
5403    pass
key = 'respectnulls'
class HavingMax(Expression):
5407class HavingMax(Expression):
5408    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5412class Func(Condition):
5413    """
5414    The base class for all function expressions.
5415
5416    Attributes:
5417        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5418            treated as a variable length argument and the argument's value will be stored as a list.
5419        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5420            function expression. These values are used to map this node to a name during parsing as
5421            well as to provide the function's name during SQL string generation. By default the SQL
5422            name is set to the expression's class name transformed to snake case.
5423    """
5424
5425    is_var_len_args = False
5426
5427    @classmethod
5428    def from_arg_list(cls, args):
5429        if cls.is_var_len_args:
5430            all_arg_keys = list(cls.arg_types)
5431            # If this function supports variable length argument treat the last argument as such.
5432            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5433            num_non_var = len(non_var_len_arg_keys)
5434
5435            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5436            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5437        else:
5438            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5439
5440        return cls(**args_dict)
5441
5442    @classmethod
5443    def sql_names(cls):
5444        if cls is Func:
5445            raise NotImplementedError(
5446                "SQL name is only supported by concrete function implementations"
5447            )
5448        if "_sql_names" not in cls.__dict__:
5449            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5450        return cls._sql_names
5451
5452    @classmethod
5453    def sql_name(cls):
5454        sql_names = cls.sql_names()
5455        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5456        return sql_names[0]
5457
5458    @classmethod
5459    def default_parser_mappings(cls):
5460        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):
5427    @classmethod
5428    def from_arg_list(cls, args):
5429        if cls.is_var_len_args:
5430            all_arg_keys = list(cls.arg_types)
5431            # If this function supports variable length argument treat the last argument as such.
5432            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5433            num_non_var = len(non_var_len_arg_keys)
5434
5435            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5436            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5437        else:
5438            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5439
5440        return cls(**args_dict)
@classmethod
def sql_names(cls):
5442    @classmethod
5443    def sql_names(cls):
5444        if cls is Func:
5445            raise NotImplementedError(
5446                "SQL name is only supported by concrete function implementations"
5447            )
5448        if "_sql_names" not in cls.__dict__:
5449            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5450        return cls._sql_names
@classmethod
def sql_name(cls):
5452    @classmethod
5453    def sql_name(cls):
5454        sql_names = cls.sql_names()
5455        assert sql_names, f"Expected non-empty 'sql_names' for Func: {cls.__name__}."
5456        return sql_names[0]
@classmethod
def default_parser_mappings(cls):
5458    @classmethod
5459    def default_parser_mappings(cls):
5460        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class Typeof(Func):
5463class Typeof(Func):
5464    pass
key = 'typeof'
class Acos(Func):
5467class Acos(Func):
5468    pass
key = 'acos'
class Acosh(Func):
5471class Acosh(Func):
5472    pass
key = 'acosh'
class Asin(Func):
5475class Asin(Func):
5476    pass
key = 'asin'
class Asinh(Func):
5479class Asinh(Func):
5480    pass
key = 'asinh'
class Atan(Func):
5483class Atan(Func):
5484    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'atan'
class Atanh(Func):
5487class Atanh(Func):
5488    pass
key = 'atanh'
class Atan2(Func):
5491class Atan2(Func):
5492    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atan2'
class Cot(Func):
5495class Cot(Func):
5496    pass
key = 'cot'
class Coth(Func):
5499class Coth(Func):
5500    pass
key = 'coth'
class Csc(Func):
5503class Csc(Func):
5504    pass
key = 'csc'
class Csch(Func):
5507class Csch(Func):
5508    pass
key = 'csch'
class Sec(Func):
5511class Sec(Func):
5512    pass
key = 'sec'
class Sech(Func):
5515class Sech(Func):
5516    pass
key = 'sech'
class Sin(Func):
5519class Sin(Func):
5520    pass
key = 'sin'
class Sinh(Func):
5523class Sinh(Func):
5524    pass
key = 'sinh'
class CosineDistance(Func):
5527class CosineDistance(Func):
5528    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'cosinedistance'
class EuclideanDistance(Func):
5531class EuclideanDistance(Func):
5532    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'euclideandistance'
class JarowinklerSimilarity(Func):
5535class JarowinklerSimilarity(Func):
5536    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jarowinklersimilarity'
class AggFunc(Func):
5539class AggFunc(Func):
5540    pass
key = 'aggfunc'
class BitwiseAndAgg(AggFunc):
5543class BitwiseAndAgg(AggFunc):
5544    pass
key = 'bitwiseandagg'
class BitwiseOrAgg(AggFunc):
5547class BitwiseOrAgg(AggFunc):
5548    pass
key = 'bitwiseoragg'
class BitwiseXorAgg(AggFunc):
5551class BitwiseXorAgg(AggFunc):
5552    pass
key = 'bitwisexoragg'
class BitwiseCountAgg(AggFunc):
5555class BitwiseCountAgg(AggFunc):
5556    pass
key = 'bitwisecountagg'
class ByteLength(Func):
5559class ByteLength(Func):
5560    pass
key = 'bytelength'
class JSONBool(Func):
5564class JSONBool(Func):
5565    pass
key = 'jsonbool'
class ArrayRemove(Func):
5568class ArrayRemove(Func):
5569    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayremove'
class ParameterizedAgg(AggFunc):
5572class ParameterizedAgg(AggFunc):
5573    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5576class Abs(Func):
5577    pass
key = 'abs'
class ArgMax(AggFunc):
5580class ArgMax(AggFunc):
5581    arg_types = {"this": True, "expression": True, "count": False}
5582    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5585class ArgMin(AggFunc):
5586    arg_types = {"this": True, "expression": True, "count": False}
5587    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5590class ApproxTopK(AggFunc):
5591    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class ApproxTopSum(AggFunc):
5594class ApproxTopSum(AggFunc):
5595    arg_types = {"this": True, "expression": True, "count": True}
arg_types = {'this': True, 'expression': True, 'count': True}
key = 'approxtopsum'
class ApproxQuantiles(AggFunc):
5598class ApproxQuantiles(AggFunc):
5599    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'approxquantiles'
class FarmFingerprint(Func):
5602class FarmFingerprint(Func):
5603    arg_types = {"expressions": True}
5604    is_var_len_args = True
5605    _sql_names = ["FARM_FINGERPRINT", "FARMFINGERPRINT64"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'farmfingerprint'
class Flatten(Func):
5608class Flatten(Func):
5609    pass
key = 'flatten'
class Float64(Func):
5612class Float64(Func):
5613    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'float64'
class Transform(Func):
5617class Transform(Func):
5618    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Translate(Func):
5621class Translate(Func):
5622    arg_types = {"this": True, "from": True, "to": True}
arg_types = {'this': True, 'from': True, 'to': True}
key = 'translate'
class Grouping(AggFunc):
5625class Grouping(AggFunc):
5626    arg_types = {"expressions": True}
5627    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'grouping'
class Anonymous(Func):
5630class Anonymous(Func):
5631    arg_types = {"this": True, "expressions": False}
5632    is_var_len_args = True
5633
5634    @property
5635    def name(self) -> str:
5636        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
5634    @property
5635    def name(self) -> str:
5636        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5639class AnonymousAggFunc(AggFunc):
5640    arg_types = {"this": True, "expressions": False}
5641    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5645class CombinedAggFunc(AnonymousAggFunc):
5646    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5649class CombinedParameterizedAgg(ParameterizedAgg):
5650    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5655class Hll(AggFunc):
5656    arg_types = {"this": True, "expressions": False}
5657    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5660class ApproxDistinct(AggFunc):
5661    arg_types = {"this": True, "accuracy": False}
5662    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5665class Apply(Func):
5666    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5669class Array(Func):
5670    arg_types = {"expressions": False, "bracket_notation": False}
5671    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class Ascii(Func):
5674class Ascii(Func):
5675    pass
key = 'ascii'
class ToArray(Func):
5679class ToArray(Func):
5680    pass
key = 'toarray'
class List(Func):
5684class List(Func):
5685    arg_types = {"expressions": False}
5686    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5690class Pad(Func):
5691    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):
5696class ToChar(Func):
5697    arg_types = {
5698        "this": True,
5699        "format": False,
5700        "nlsparam": False,
5701        "is_numeric": False,
5702    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'is_numeric': False}
key = 'tochar'
class ToCodePoints(Func):
5705class ToCodePoints(Func):
5706    pass
key = 'tocodepoints'
class ToNumber(Func):
5711class ToNumber(Func):
5712    arg_types = {
5713        "this": True,
5714        "format": False,
5715        "nlsparam": False,
5716        "precision": False,
5717        "scale": False,
5718    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5722class ToDouble(Func):
5723    arg_types = {
5724        "this": True,
5725        "format": False,
5726    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class CodePointsToBytes(Func):
5729class CodePointsToBytes(Func):
5730    pass
key = 'codepointstobytes'
class Columns(Func):
5733class Columns(Func):
5734    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5738class Convert(Func):
5739    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertToCharset(Func):
5743class ConvertToCharset(Func):
5744    arg_types = {"this": True, "dest": True, "source": False}
arg_types = {'this': True, 'dest': True, 'source': False}
key = 'converttocharset'
class ConvertTimezone(Func):
5747class ConvertTimezone(Func):
5748    arg_types = {
5749        "source_tz": False,
5750        "target_tz": True,
5751        "timestamp": True,
5752        "options": False,
5753    }
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True, 'options': False}
key = 'converttimezone'
class CodePointsToString(Func):
5756class CodePointsToString(Func):
5757    pass
key = 'codepointstostring'
class GenerateSeries(Func):
5760class GenerateSeries(Func):
5761    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):
5767class ExplodingGenerateSeries(GenerateSeries):
5768    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5771class ArrayAgg(AggFunc):
5772    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5775class ArrayUniqueAgg(AggFunc):
5776    pass
key = 'arrayuniqueagg'
class AIAgg(AggFunc):
5779class AIAgg(AggFunc):
5780    arg_types = {"this": True, "expression": True}
5781    _sql_names = ["AI_AGG"]
arg_types = {'this': True, 'expression': True}
key = 'aiagg'
class AISummarizeAgg(AggFunc):
5784class AISummarizeAgg(AggFunc):
5785    _sql_names = ["AI_SUMMARIZE_AGG"]
key = 'aisummarizeagg'
class AIClassify(Func):
5788class AIClassify(Func):
5789    arg_types = {"this": True, "categories": True, "config": False}
5790    _sql_names = ["AI_CLASSIFY"]
arg_types = {'this': True, 'categories': True, 'config': False}
key = 'aiclassify'
class ArrayAll(Func):
5793class ArrayAll(Func):
5794    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5798class ArrayAny(Func):
5799    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5802class ArrayConcat(Func):
5803    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5804    arg_types = {"this": True, "expressions": False}
5805    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConcatAgg(AggFunc):
5808class ArrayConcatAgg(AggFunc):
5809    pass
key = 'arrayconcatagg'
class ArrayConstructCompact(Func):
5812class ArrayConstructCompact(Func):
5813    arg_types = {"expressions": True}
5814    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5817class ArrayContains(Binary, Func):
5818    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5821class ArrayContainsAll(Binary, Func):
5822    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5825class ArrayFilter(Func):
5826    arg_types = {"this": True, "expression": True}
5827    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayFirst(Func):
5830class ArrayFirst(Func):
5831    pass
key = 'arrayfirst'
class ArrayLast(Func):
5834class ArrayLast(Func):
5835    pass
key = 'arraylast'
class ArrayReverse(Func):
5838class ArrayReverse(Func):
5839    pass
key = 'arrayreverse'
class ArraySlice(Func):
5842class ArraySlice(Func):
5843    arg_types = {"this": True, "start": True, "end": False, "step": False}
arg_types = {'this': True, 'start': True, 'end': False, 'step': False}
key = 'arrayslice'
class ArrayToString(Func):
5846class ArrayToString(Func):
5847    arg_types = {"this": True, "expression": True, "null": False}
5848    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class ArrayIntersect(Func):
5851class ArrayIntersect(Func):
5852    arg_types = {"expressions": True}
5853    is_var_len_args = True
5854    _sql_names = ["ARRAY_INTERSECT", "ARRAY_INTERSECTION"]
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayintersect'
class StPoint(Func):
5857class StPoint(Func):
5858    arg_types = {"this": True, "expression": True, "null": False}
5859    _sql_names = ["ST_POINT", "ST_MAKEPOINT"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stpoint'
class StDistance(Func):
5862class StDistance(Func):
5863    arg_types = {"this": True, "expression": True, "use_spheroid": False}
arg_types = {'this': True, 'expression': True, 'use_spheroid': False}
key = 'stdistance'
class String(Func):
5867class String(Func):
5868    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5871class StringToArray(Func):
5872    arg_types = {"this": True, "expression": False, "null": False}
5873    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING", "STRTOK_TO_ARRAY"]
arg_types = {'this': True, 'expression': False, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5876class ArrayOverlaps(Binary, Func):
5877    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5880class ArraySize(Func):
5881    arg_types = {"this": True, "expression": False}
5882    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5885class ArraySort(Func):
5886    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5889class ArraySum(Func):
5890    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5893class ArrayUnionAgg(AggFunc):
5894    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5897class Avg(AggFunc):
5898    pass
key = 'avg'
class AnyValue(AggFunc):
5901class AnyValue(AggFunc):
5902    pass
key = 'anyvalue'
class Lag(AggFunc):
5905class Lag(AggFunc):
5906    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5909class Lead(AggFunc):
5910    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5915class First(AggFunc):
5916    pass
key = 'first'
class Last(AggFunc):
5919class Last(AggFunc):
5920    pass
key = 'last'
class FirstValue(AggFunc):
5923class FirstValue(AggFunc):
5924    pass
key = 'firstvalue'
class LastValue(AggFunc):
5927class LastValue(AggFunc):
5928    pass
key = 'lastvalue'
class NthValue(AggFunc):
5931class NthValue(AggFunc):
5932    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5935class Case(Func):
5936    arg_types = {"this": False, "ifs": True, "default": False}
5937
5938    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5939        instance = maybe_copy(self, copy)
5940        instance.append(
5941            "ifs",
5942            If(
5943                this=maybe_parse(condition, copy=copy, **opts),
5944                true=maybe_parse(then, copy=copy, **opts),
5945            ),
5946        )
5947        return instance
5948
5949    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5950        instance = maybe_copy(self, copy)
5951        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5952        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:
5938    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5939        instance = maybe_copy(self, copy)
5940        instance.append(
5941            "ifs",
5942            If(
5943                this=maybe_parse(condition, copy=copy, **opts),
5944                true=maybe_parse(then, copy=copy, **opts),
5945            ),
5946        )
5947        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5949    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5950        instance = maybe_copy(self, copy)
5951        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5952        return instance
key = 'case'
class Cast(Func):
5955class Cast(Func):
5956    arg_types = {
5957        "this": True,
5958        "to": True,
5959        "format": False,
5960        "safe": False,
5961        "action": False,
5962        "default": False,
5963    }
5964
5965    @property
5966    def name(self) -> str:
5967        return self.this.name
5968
5969    @property
5970    def to(self) -> DataType:
5971        return self.args["to"]
5972
5973    @property
5974    def output_name(self) -> str:
5975        return self.name
5976
5977    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5978        """
5979        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5980        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5981        array<int> != array<float>.
5982
5983        Args:
5984            dtypes: the data types to compare this Cast's DataType to.
5985
5986        Returns:
5987            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5988        """
5989        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5965    @property
5966    def name(self) -> str:
5967        return self.this.name
to: DataType
5969    @property
5970    def to(self) -> DataType:
5971        return self.args["to"]
output_name: str
5973    @property
5974    def output_name(self) -> str:
5975        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, Identifier, Dot, DataType, DataType.Type]) -> bool:
5977    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5978        """
5979        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5980        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5981        array<int> != array<float>.
5982
5983        Args:
5984            dtypes: the data types to compare this Cast's DataType to.
5985
5986        Returns:
5987            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5988        """
5989        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):
5992class TryCast(Cast):
5993    arg_types = {**Cast.arg_types, "requires_string": False}
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False, 'requires_string': False}
key = 'trycast'
class JSONCast(Cast):
5997class JSONCast(Cast):
5998    pass
key = 'jsoncast'
class JustifyDays(Func):
6001class JustifyDays(Func):
6002    pass
key = 'justifydays'
class JustifyHours(Func):
6005class JustifyHours(Func):
6006    pass
key = 'justifyhours'
class JustifyInterval(Func):
6009class JustifyInterval(Func):
6010    pass
key = 'justifyinterval'
class Try(Func):
6013class Try(Func):
6014    pass
key = 'try'
class CastToStrType(Func):
6017class CastToStrType(Func):
6018    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class TranslateCharacters(Expression):
6022class TranslateCharacters(Expression):
6023    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key = 'translatecharacters'
class Collate(Binary, Func):
6026class Collate(Binary, Func):
6027    pass
key = 'collate'
class Collation(Func):
6030class Collation(Func):
6031    pass
key = 'collation'
class Ceil(Func):
6034class Ceil(Func):
6035    arg_types = {"this": True, "decimals": False, "to": False}
6036    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
6039class Coalesce(Func):
6040    arg_types = {"this": True, "expressions": False, "is_nvl": False, "is_null": False}
6041    is_var_len_args = True
6042    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False, 'is_null': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
6045class Chr(Func):
6046    arg_types = {"expressions": True, "charset": False}
6047    is_var_len_args = True
6048    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
6051class Concat(Func):
6052    arg_types = {"expressions": True, "safe": False, "coalesce": False}
6053    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
6056class ConcatWs(Concat):
6057    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
6061class Contains(Func):
6062    arg_types = {"this": True, "expression": True, "json_scope": False}
arg_types = {'this': True, 'expression': True, 'json_scope': False}
key = 'contains'
class ConnectByRoot(Func):
6066class ConnectByRoot(Func):
6067    pass
key = 'connectbyroot'
class Count(AggFunc):
6070class Count(AggFunc):
6071    arg_types = {"this": False, "expressions": False, "big_int": False}
6072    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
6075class CountIf(AggFunc):
6076    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
6080class Cbrt(Func):
6081    pass
key = 'cbrt'
class CurrentDate(Func):
6084class CurrentDate(Func):
6085    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
6088class CurrentDatetime(Func):
6089    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
6092class CurrentTime(Func):
6093    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
6096class CurrentTimestamp(Func):
6097    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentTimestampLTZ(Func):
6100class CurrentTimestampLTZ(Func):
6101    arg_types = {}
arg_types = {}
key = 'currenttimestampltz'
class CurrentSchema(Func):
6104class CurrentSchema(Func):
6105    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
6108class CurrentUser(Func):
6109    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class UtcDate(Func):
6112class UtcDate(Func):
6113    arg_types = {}
arg_types = {}
key = 'utcdate'
class UtcTime(Func):
6116class UtcTime(Func):
6117    arg_types = {"this": False}
arg_types = {'this': False}
key = 'utctime'
class UtcTimestamp(Func):
6120class UtcTimestamp(Func):
6121    arg_types = {"this": False}
arg_types = {'this': False}
key = 'utctimestamp'
class DateAdd(Func, IntervalOp):
6124class DateAdd(Func, IntervalOp):
6125    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
6128class DateBin(Func, IntervalOp):
6129    arg_types = {"this": True, "expression": True, "unit": False, "zone": False, "origin": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False, 'origin': False}
key = 'datebin'
class DateSub(Func, IntervalOp):
6132class DateSub(Func, IntervalOp):
6133    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
6136class DateDiff(Func, TimeUnit):
6137    _sql_names = ["DATEDIFF", "DATE_DIFF"]
6138    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datediff'
class DateTrunc(Func):
6141class DateTrunc(Func):
6142    arg_types = {"unit": True, "this": True, "zone": False}
6143
6144    def __init__(self, **args):
6145        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
6146        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
6147        unabbreviate = args.pop("unabbreviate", True)
6148
6149        unit = args.get("unit")
6150        if isinstance(unit, TimeUnit.VAR_LIKE):
6151            unit_name = unit.name.upper()
6152            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
6153                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
6154
6155            args["unit"] = Literal.string(unit_name)
6156
6157        super().__init__(**args)
6158
6159    @property
6160    def unit(self) -> Expression:
6161        return self.args["unit"]
DateTrunc(**args)
6144    def __init__(self, **args):
6145        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
6146        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
6147        unabbreviate = args.pop("unabbreviate", True)
6148
6149        unit = args.get("unit")
6150        if isinstance(unit, TimeUnit.VAR_LIKE):
6151            unit_name = unit.name.upper()
6152            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
6153                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
6154
6155            args["unit"] = Literal.string(unit_name)
6156
6157        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
6159    @property
6160    def unit(self) -> Expression:
6161        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
6166class Datetime(Func):
6167    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
6170class DatetimeAdd(Func, IntervalOp):
6171    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
6174class DatetimeSub(Func, IntervalOp):
6175    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
6178class DatetimeDiff(Func, TimeUnit):
6179    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
6182class DatetimeTrunc(Func, TimeUnit):
6183    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DateFromUnixDate(Func):
6186class DateFromUnixDate(Func):
6187    pass
key = 'datefromunixdate'
class DayOfWeek(Func):
6190class DayOfWeek(Func):
6191    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
6196class DayOfWeekIso(Func):
6197    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
6200class DayOfMonth(Func):
6201    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
6204class DayOfYear(Func):
6205    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
6208class ToDays(Func):
6209    pass
key = 'todays'
class WeekOfYear(Func):
6212class WeekOfYear(Func):
6213    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
6216class MonthsBetween(Func):
6217    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
6220class MakeInterval(Func):
6221    arg_types = {
6222        "year": False,
6223        "month": False,
6224        "day": False,
6225        "hour": False,
6226        "minute": False,
6227        "second": False,
6228    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
6231class LastDay(Func, TimeUnit):
6232    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
6233    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class LaxBool(Func):
6236class LaxBool(Func):
6237    pass
key = 'laxbool'
class LaxFloat64(Func):
6240class LaxFloat64(Func):
6241    pass
key = 'laxfloat64'
class LaxInt64(Func):
6244class LaxInt64(Func):
6245    pass
key = 'laxint64'
class LaxString(Func):
6248class LaxString(Func):
6249    pass
key = 'laxstring'
class Extract(Func):
6252class Extract(Func):
6253    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
6256class Exists(Func, SubqueryPredicate):
6257    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
6260class Timestamp(Func):
6261    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
6264class TimestampAdd(Func, TimeUnit):
6265    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
6268class TimestampSub(Func, TimeUnit):
6269    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
6272class TimestampDiff(Func, TimeUnit):
6273    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
6274    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
6277class TimestampTrunc(Func, TimeUnit):
6278    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
6281class TimeAdd(Func, TimeUnit):
6282    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
6285class TimeSub(Func, TimeUnit):
6286    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
6289class TimeDiff(Func, TimeUnit):
6290    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
6293class TimeTrunc(Func, TimeUnit):
6294    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
6297class DateFromParts(Func):
6298    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
6299    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
6302class TimeFromParts(Func):
6303    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
6304    arg_types = {
6305        "hour": True,
6306        "min": True,
6307        "sec": True,
6308        "nano": False,
6309        "fractions": False,
6310        "precision": False,
6311    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
6314class DateStrToDate(Func):
6315    pass
key = 'datestrtodate'
class DateToDateStr(Func):
6318class DateToDateStr(Func):
6319    pass
key = 'datetodatestr'
class DateToDi(Func):
6322class DateToDi(Func):
6323    pass
key = 'datetodi'
class Date(Func):
6327class Date(Func):
6328    arg_types = {"this": False, "zone": False, "expressions": False}
6329    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
6332class Day(Func):
6333    pass
key = 'day'
class Decode(Func):
6336class Decode(Func):
6337    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DecodeCase(Func):
6340class DecodeCase(Func):
6341    arg_types = {"expressions": True}
6342    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'decodecase'
class DenseRank(AggFunc):
6345class DenseRank(AggFunc):
6346    arg_types = {"expressions": False}
6347    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'denserank'
class DiToDate(Func):
6350class DiToDate(Func):
6351    pass
key = 'ditodate'
class Encode(Func):
6354class Encode(Func):
6355    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
6358class Exp(Func):
6359    pass
key = 'exp'
class Explode(Func, UDTF):
6363class Explode(Func, UDTF):
6364    arg_types = {"this": True, "expressions": False}
6365    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
6369class Inline(Func):
6370    pass
key = 'inline'
class ExplodeOuter(Explode):
6373class ExplodeOuter(Explode):
6374    pass
key = 'explodeouter'
class Posexplode(Explode):
6377class Posexplode(Explode):
6378    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
6381class PosexplodeOuter(Posexplode, ExplodeOuter):
6382    pass
key = 'posexplodeouter'
class PositionalColumn(Expression):
6385class PositionalColumn(Expression):
6386    pass
key = 'positionalcolumn'
class Unnest(Func, UDTF):
6389class Unnest(Func, UDTF):
6390    arg_types = {
6391        "expressions": True,
6392        "alias": False,
6393        "offset": False,
6394        "explode_array": False,
6395    }
6396
6397    @property
6398    def selects(self) -> t.List[Expression]:
6399        columns = super().selects
6400        offset = self.args.get("offset")
6401        if offset:
6402            columns = columns + [to_identifier("offset") if offset is True else offset]
6403        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
6397    @property
6398    def selects(self) -> t.List[Expression]:
6399        columns = super().selects
6400        offset = self.args.get("offset")
6401        if offset:
6402            columns = columns + [to_identifier("offset") if offset is True else offset]
6403        return columns
key = 'unnest'
class Floor(Func):
6406class Floor(Func):
6407    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase32(Func):
6410class FromBase32(Func):
6411    pass
key = 'frombase32'
class FromBase64(Func):
6414class FromBase64(Func):
6415    pass
key = 'frombase64'
class ToBase32(Func):
6418class ToBase32(Func):
6419    pass
key = 'tobase32'
class ToBase64(Func):
6422class ToBase64(Func):
6423    pass
key = 'tobase64'
class Base64DecodeBinary(Func):
6427class Base64DecodeBinary(Func):
6428    arg_types = {"this": True, "alphabet": False}
arg_types = {'this': True, 'alphabet': False}
key = 'base64decodebinary'
class Base64DecodeString(Func):
6431class Base64DecodeString(Func):
6432    arg_types = {"this": True, "alphabet": False}
arg_types = {'this': True, 'alphabet': False}
key = 'base64decodestring'
class Base64Encode(Func):
6435class Base64Encode(Func):
6436    arg_types = {"this": True, "max_line_length": False, "alphabet": False}
arg_types = {'this': True, 'max_line_length': False, 'alphabet': False}
key = 'base64encode'
class FromISO8601Timestamp(Func):
6440class FromISO8601Timestamp(Func):
6441    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
6444class GapFill(Func):
6445    arg_types = {
6446        "this": True,
6447        "ts_column": True,
6448        "bucket_width": True,
6449        "partitioning_columns": False,
6450        "value_columns": False,
6451        "origin": False,
6452        "ignore_nulls": False,
6453    }
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):
6457class GenerateDateArray(Func):
6458    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
6462class GenerateTimestampArray(Func):
6463    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class GetExtract(Func):
6467class GetExtract(Func):
6468    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'getextract'
class Greatest(Func):
6471class Greatest(Func):
6472    arg_types = {"this": True, "expressions": False}
6473    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
6478class OverflowTruncateBehavior(Expression):
6479    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
6482class GroupConcat(AggFunc):
6483    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
6486class Hex(Func):
6487    pass
key = 'hex'
class HexDecodeString(Func):
6491class HexDecodeString(Func):
6492    pass
key = 'hexdecodestring'
class HexEncode(Func):
6496class HexEncode(Func):
6497    arg_types = {"this": True, "case": False}
arg_types = {'this': True, 'case': False}
key = 'hexencode'
class Compress(Func):
6502class Compress(Func):
6503    arg_types = {"this": True, "method": False}
arg_types = {'this': True, 'method': False}
key = 'compress'
class DecompressBinary(Func):
6507class DecompressBinary(Func):
6508    arg_types = {"this": True, "method": True}
arg_types = {'this': True, 'method': True}
key = 'decompressbinary'
class DecompressString(Func):
6512class DecompressString(Func):
6513    arg_types = {"this": True, "method": True}
arg_types = {'this': True, 'method': True}
key = 'decompressstring'
class LowerHex(Hex):
6516class LowerHex(Hex):
6517    pass
key = 'lowerhex'
class And(Connector, Func):
6520class And(Connector, Func):
6521    pass
key = 'and'
class Or(Connector, Func):
6524class Or(Connector, Func):
6525    pass
key = 'or'
class Xor(Connector, Func):
6528class Xor(Connector, Func):
6529    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
6532class If(Func):
6533    arg_types = {"this": True, "true": True, "false": False}
6534    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6537class Nullif(Func):
6538    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6541class Initcap(Func):
6542    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6545class IsAscii(Func):
6546    pass
key = 'isascii'
class IsNan(Func):
6549class IsNan(Func):
6550    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6554class Int64(Func):
6555    pass
key = 'int64'
class IsInf(Func):
6558class IsInf(Func):
6559    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6563class JSON(Expression):
6564    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6567class JSONPath(Expression):
6568    arg_types = {"expressions": True, "escape": False}
6569
6570    @property
6571    def output_name(self) -> str:
6572        last_segment = self.expressions[-1].this
6573        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6570    @property
6571    def output_name(self) -> str:
6572        last_segment = self.expressions[-1].this
6573        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):
6576class JSONPathPart(Expression):
6577    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6580class JSONPathFilter(JSONPathPart):
6581    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6584class JSONPathKey(JSONPathPart):
6585    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6588class JSONPathRecursive(JSONPathPart):
6589    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6592class JSONPathRoot(JSONPathPart):
6593    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6596class JSONPathScript(JSONPathPart):
6597    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6600class JSONPathSlice(JSONPathPart):
6601    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6604class JSONPathSelector(JSONPathPart):
6605    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6608class JSONPathSubscript(JSONPathPart):
6609    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6612class JSONPathUnion(JSONPathPart):
6613    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6616class JSONPathWildcard(JSONPathPart):
6617    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6620class FormatJson(Expression):
6621    pass
key = 'formatjson'
class Format(Func):
6624class Format(Func):
6625    arg_types = {"this": True, "expressions": True}
6626    is_var_len_args = True
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'format'
class JSONKeyValue(Expression):
6629class JSONKeyValue(Expression):
6630    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONKeysAtDepth(Func):
6634class JSONKeysAtDepth(Func):
6635    arg_types = {"this": True, "expression": False, "mode": False}
arg_types = {'this': True, 'expression': False, 'mode': False}
key = 'jsonkeysatdepth'
class JSONObject(Func):
6638class JSONObject(Func):
6639    arg_types = {
6640        "expressions": False,
6641        "null_handling": False,
6642        "unique_keys": False,
6643        "return_type": False,
6644        "encoding": False,
6645    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6648class JSONObjectAgg(AggFunc):
6649    arg_types = {
6650        "expressions": False,
6651        "null_handling": False,
6652        "unique_keys": False,
6653        "return_type": False,
6654        "encoding": False,
6655    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6659class JSONBObjectAgg(AggFunc):
6660    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6664class JSONArray(Func):
6665    arg_types = {
6666        "expressions": False,
6667        "null_handling": False,
6668        "return_type": False,
6669        "strict": False,
6670    }
arg_types = {'expressions': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6674class JSONArrayAgg(Func):
6675    arg_types = {
6676        "this": True,
6677        "order": False,
6678        "null_handling": False,
6679        "return_type": False,
6680        "strict": False,
6681    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6684class JSONExists(Func):
6685    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):
6690class JSONColumnDef(Expression):
6691    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):
6694class JSONSchema(Expression):
6695    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONSet(Func):
6698class JSONSet(Func):
6699    arg_types = {"this": True, "expressions": True}
6700    is_var_len_args = True
6701    _sql_names = ["JSON_SET"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonset'
class JSONStripNulls(Func):
6705class JSONStripNulls(Func):
6706    arg_types = {
6707        "this": True,
6708        "expression": False,
6709        "include_arrays": False,
6710        "remove_empty": False,
6711    }
6712    _sql_names = ["JSON_STRIP_NULLS"]
arg_types = {'this': True, 'expression': False, 'include_arrays': False, 'remove_empty': False}
key = 'jsonstripnulls'
class JSONValue(Expression):
6716class JSONValue(Expression):
6717    arg_types = {
6718        "this": True,
6719        "path": True,
6720        "returning": False,
6721        "on_condition": False,
6722    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6725class JSONValueArray(Func):
6726    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONRemove(Func):
6729class JSONRemove(Func):
6730    arg_types = {"this": True, "expressions": True}
6731    is_var_len_args = True
6732    _sql_names = ["JSON_REMOVE"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonremove'
class JSONTable(Func):
6736class JSONTable(Func):
6737    arg_types = {
6738        "this": True,
6739        "schema": True,
6740        "path": False,
6741        "error_handling": False,
6742        "empty_handling": False,
6743    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class JSONType(Func):
6748class JSONType(Func):
6749    arg_types = {"this": True, "expression": False}
6750    _sql_names = ["JSON_TYPE"]
arg_types = {'this': True, 'expression': False}
key = 'jsontype'
class ObjectInsert(Func):
6754class ObjectInsert(Func):
6755    arg_types = {
6756        "this": True,
6757        "key": True,
6758        "value": True,
6759        "update_flag": False,
6760    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6763class OpenJSONColumnDef(Expression):
6764    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):
6767class OpenJSON(Func):
6768    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6771class JSONBContains(Binary, Func):
6772    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBContainsAnyTopKeys(Binary, Func):
6776class JSONBContainsAnyTopKeys(Binary, Func):
6777    pass
key = 'jsonbcontainsanytopkeys'
class JSONBContainsAllTopKeys(Binary, Func):
6781class JSONBContainsAllTopKeys(Binary, Func):
6782    pass
key = 'jsonbcontainsalltopkeys'
class JSONBExists(Func):
6785class JSONBExists(Func):
6786    arg_types = {"this": True, "path": True}
6787    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONBDeleteAtPath(Binary, Func):
6791class JSONBDeleteAtPath(Binary, Func):
6792    pass
key = 'jsonbdeleteatpath'
class JSONExtract(Binary, Func):
6795class JSONExtract(Binary, Func):
6796    arg_types = {
6797        "this": True,
6798        "expression": True,
6799        "only_json_types": False,
6800        "expressions": False,
6801        "variant_extract": False,
6802        "json_query": False,
6803        "option": False,
6804        "quote": False,
6805        "on_condition": False,
6806        "requires_json": False,
6807    }
6808    _sql_names = ["JSON_EXTRACT"]
6809    is_var_len_args = True
6810
6811    @property
6812    def output_name(self) -> str:
6813        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, 'json_query': False, 'option': False, 'quote': False, 'on_condition': False, 'requires_json': False}
is_var_len_args = True
output_name: str
6811    @property
6812    def output_name(self) -> str:
6813        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 JSONExtractQuote(Expression):
6817class JSONExtractQuote(Expression):
6818    arg_types = {
6819        "option": True,
6820        "scalar": False,
6821    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6824class JSONExtractArray(Func):
6825    arg_types = {"this": True, "expression": False}
6826    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6829class JSONExtractScalar(Binary, Func):
6830    arg_types = {
6831        "this": True,
6832        "expression": True,
6833        "only_json_types": False,
6834        "expressions": False,
6835        "json_type": False,
6836    }
6837    _sql_names = ["JSON_EXTRACT_SCALAR"]
6838    is_var_len_args = True
6839
6840    @property
6841    def output_name(self) -> str:
6842        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False, 'json_type': False}
is_var_len_args = True
output_name: str
6840    @property
6841    def output_name(self) -> str:
6842        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):
6845class JSONBExtract(Binary, Func):
6846    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6849class JSONBExtractScalar(Binary, Func):
6850    arg_types = {"this": True, "expression": True, "json_type": False}
6851    _sql_names = ["JSONB_EXTRACT_SCALAR"]
arg_types = {'this': True, 'expression': True, 'json_type': False}
key = 'jsonbextractscalar'
class JSONFormat(Func):
6854class JSONFormat(Func):
6855    arg_types = {"this": False, "options": False, "is_json": False, "to_json": False}
6856    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False, 'is_json': False, 'to_json': False}
key = 'jsonformat'
class JSONArrayAppend(Func):
6859class JSONArrayAppend(Func):
6860    arg_types = {"this": True, "expressions": True}
6861    is_var_len_args = True
6862    _sql_names = ["JSON_ARRAY_APPEND"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonarrayappend'
class JSONArrayContains(Binary, Predicate, Func):
6866class JSONArrayContains(Binary, Predicate, Func):
6867    arg_types = {"this": True, "expression": True, "json_type": False}
6868    _sql_names = ["JSON_ARRAY_CONTAINS"]
arg_types = {'this': True, 'expression': True, 'json_type': False}
key = 'jsonarraycontains'
class JSONArrayInsert(Func):
6871class JSONArrayInsert(Func):
6872    arg_types = {"this": True, "expressions": True}
6873    is_var_len_args = True
6874    _sql_names = ["JSON_ARRAY_INSERT"]
arg_types = {'this': True, 'expressions': True}
is_var_len_args = True
key = 'jsonarrayinsert'
class ParseBignumeric(Func):
6877class ParseBignumeric(Func):
6878    pass
key = 'parsebignumeric'
class ParseNumeric(Func):
6881class ParseNumeric(Func):
6882    pass
key = 'parsenumeric'
class ParseJSON(Func):
6885class ParseJSON(Func):
6886    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6887    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6888    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6889    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class ParseUrl(Func):
6894class ParseUrl(Func):
6895    arg_types = {"this": True, "part_to_extract": False, "key": False, "permissive": False}
arg_types = {'this': True, 'part_to_extract': False, 'key': False, 'permissive': False}
key = 'parseurl'
class ParseIp(Func):
6898class ParseIp(Func):
6899    arg_types = {"this": True, "type": True, "permissive": False}
arg_types = {'this': True, 'type': True, 'permissive': False}
key = 'parseip'
class ParseTime(Func):
6902class ParseTime(Func):
6903    arg_types = {"this": True, "format": True}
arg_types = {'this': True, 'format': True}
key = 'parsetime'
class ParseDatetime(Func):
6906class ParseDatetime(Func):
6907    arg_types = {"this": True, "format": False, "zone": False}
arg_types = {'this': True, 'format': False, 'zone': False}
key = 'parsedatetime'
class Least(Func):
6910class Least(Func):
6911    arg_types = {"this": True, "expressions": False}
6912    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6915class Left(Func):
6916    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Reverse(Func):
6923class Reverse(Func):
6924    pass
key = 'reverse'
class Length(Func):
6927class Length(Func):
6928    arg_types = {"this": True, "binary": False, "encoding": False}
6929    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class RtrimmedLength(Func):
6932class RtrimmedLength(Func):
6933    pass
key = 'rtrimmedlength'
class BitLength(Func):
6936class BitLength(Func):
6937    pass
key = 'bitlength'
class Levenshtein(Func):
6940class Levenshtein(Func):
6941    arg_types = {
6942        "this": True,
6943        "expression": False,
6944        "ins_cost": False,
6945        "del_cost": False,
6946        "sub_cost": False,
6947        "max_dist": False,
6948    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6951class Ln(Func):
6952    pass
key = 'ln'
class Log(Func):
6955class Log(Func):
6956    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6959class LogicalOr(AggFunc):
6960    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6963class LogicalAnd(AggFunc):
6964    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6967class Lower(Func):
6968    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6971class Map(Func):
6972    arg_types = {"keys": False, "values": False}
6973
6974    @property
6975    def keys(self) -> t.List[Expression]:
6976        keys = self.args.get("keys")
6977        return keys.expressions if keys else []
6978
6979    @property
6980    def values(self) -> t.List[Expression]:
6981        values = self.args.get("values")
6982        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6974    @property
6975    def keys(self) -> t.List[Expression]:
6976        keys = self.args.get("keys")
6977        return keys.expressions if keys else []
values: List[Expression]
6979    @property
6980    def values(self) -> t.List[Expression]:
6981        values = self.args.get("values")
6982        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6986class ToMap(Func):
6987    pass
key = 'tomap'
class MapFromEntries(Func):
6990class MapFromEntries(Func):
6991    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6995class ScopeResolution(Expression):
6996    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6999class Stream(Expression):
7000    pass
key = 'stream'
class StarMap(Func):
7003class StarMap(Func):
7004    pass
key = 'starmap'
class VarMap(Func):
7007class VarMap(Func):
7008    arg_types = {"keys": True, "values": True}
7009    is_var_len_args = True
7010
7011    @property
7012    def keys(self) -> t.List[Expression]:
7013        return self.args["keys"].expressions
7014
7015    @property
7016    def values(self) -> t.List[Expression]:
7017        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
7011    @property
7012    def keys(self) -> t.List[Expression]:
7013        return self.args["keys"].expressions
values: List[Expression]
7015    @property
7016    def values(self) -> t.List[Expression]:
7017        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
7021class MatchAgainst(Func):
7022    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
7025class Max(AggFunc):
7026    arg_types = {"this": True, "expressions": False}
7027    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
7030class MD5(Func):
7031    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
7035class MD5Digest(Func):
7036    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class MD5NumberLower64(Func):
7040class MD5NumberLower64(Func):
7041    pass
key = 'md5numberlower64'
class MD5NumberUpper64(Func):
7045class MD5NumberUpper64(Func):
7046    pass
key = 'md5numberupper64'
class Median(AggFunc):
7049class Median(AggFunc):
7050    pass
key = 'median'
class Min(AggFunc):
7053class Min(AggFunc):
7054    arg_types = {"this": True, "expressions": False}
7055    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
7058class Month(Func):
7059    pass
key = 'month'
class AddMonths(Func):
7062class AddMonths(Func):
7063    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
7066class Nvl2(Func):
7067    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Ntile(AggFunc):
7070class Ntile(AggFunc):
7071    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ntile'
class Normalize(Func):
7074class Normalize(Func):
7075    arg_types = {"this": True, "form": False, "is_casefold": False}
arg_types = {'this': True, 'form': False, 'is_casefold': False}
key = 'normalize'
class Overlay(Func):
7078class Overlay(Func):
7079    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):
7083class Predict(Func):
7084    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class MLTranslate(Func):
7088class MLTranslate(Func):
7089    arg_types = {"this": True, "expression": True, "params_struct": True}
arg_types = {'this': True, 'expression': True, 'params_struct': True}
key = 'mltranslate'
class FeaturesAtTime(Func):
7093class FeaturesAtTime(Func):
7094    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
arg_types = {'this': True, 'time': False, 'num_rows': False, 'ignore_feature_nulls': False}
key = 'featuresattime'
class GenerateEmbedding(Func):
7098class GenerateEmbedding(Func):
7099    arg_types = {"this": True, "expression": True, "params_struct": False, "is_text": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False, 'is_text': False}
key = 'generateembedding'
class MLForecast(Func):
7102class MLForecast(Func):
7103    arg_types = {"this": True, "expression": False, "params_struct": False}
arg_types = {'this': True, 'expression': False, 'params_struct': False}
key = 'mlforecast'
class ModelAttribute(Expression):
7108class ModelAttribute(Expression):
7109    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'modelattribute'
class VectorSearch(Func):
7113class VectorSearch(Func):
7114    arg_types = {
7115        "this": True,
7116        "column_to_search": True,
7117        "query_table": True,
7118        "query_column_to_search": False,
7119        "top_k": False,
7120        "distance_type": False,
7121        "options": False,
7122    }
arg_types = {'this': True, 'column_to_search': True, 'query_table': True, 'query_column_to_search': False, 'top_k': False, 'distance_type': False, 'options': False}
key = 'vectorsearch'
class Pow(Binary, Func):
7125class Pow(Binary, Func):
7126    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
7129class PercentileCont(AggFunc):
7130    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
7133class PercentileDisc(AggFunc):
7134    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class PercentRank(AggFunc):
7137class PercentRank(AggFunc):
7138    arg_types = {"expressions": False}
7139    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'percentrank'
class Quantile(AggFunc):
7142class Quantile(AggFunc):
7143    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
7146class ApproxQuantile(Quantile):
7147    arg_types = {
7148        "this": True,
7149        "quantile": True,
7150        "accuracy": False,
7151        "weight": False,
7152        "error_tolerance": False,
7153    }
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False, 'error_tolerance': False}
key = 'approxquantile'
class Quarter(Func):
7156class Quarter(Func):
7157    pass
key = 'quarter'
class Rand(Func):
7162class Rand(Func):
7163    _sql_names = ["RAND", "RANDOM"]
7164    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
7167class Randn(Func):
7168    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
7171class RangeN(Func):
7172    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class RangeBucket(Func):
7175class RangeBucket(Func):
7176    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'rangebucket'
class Rank(AggFunc):
7179class Rank(AggFunc):
7180    arg_types = {"expressions": False}
7181    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'rank'
class ReadCSV(Func):
7184class ReadCSV(Func):
7185    _sql_names = ["READ_CSV"]
7186    is_var_len_args = True
7187    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
7190class Reduce(Func):
7191    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):
7194class RegexpExtract(Func):
7195    arg_types = {
7196        "this": True,
7197        "expression": True,
7198        "position": False,
7199        "occurrence": False,
7200        "parameters": False,
7201        "group": False,
7202    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
7205class RegexpExtractAll(Func):
7206    arg_types = {
7207        "this": True,
7208        "expression": True,
7209        "position": False,
7210        "occurrence": False,
7211        "parameters": False,
7212        "group": False,
7213    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
7216class RegexpReplace(Func):
7217    arg_types = {
7218        "this": True,
7219        "expression": True,
7220        "replacement": False,
7221        "position": False,
7222        "occurrence": False,
7223        "modifiers": False,
7224    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
7227class RegexpLike(Binary, Func):
7228    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
7231class RegexpILike(Binary, Func):
7232    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpInstr(Func):
7235class RegexpInstr(Func):
7236    arg_types = {
7237        "this": True,
7238        "expression": True,
7239        "position": False,
7240        "occurrence": False,
7241        "option": False,
7242        "parameters": False,
7243        "group": False,
7244    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'option': False, 'parameters': False, 'group': False}
key = 'regexpinstr'
class RegexpSplit(Func):
7249class RegexpSplit(Func):
7250    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
7253class Repeat(Func):
7254    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Replace(Func):
7258class Replace(Func):
7259    arg_types = {"this": True, "expression": True, "replacement": False}
arg_types = {'this': True, 'expression': True, 'replacement': False}
key = 'replace'
class Round(Func):
7264class Round(Func):
7265    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
7268class RowNumber(Func):
7269    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeAdd(Func):
7272class SafeAdd(Func):
7273    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safeadd'
class SafeDivide(Func):
7276class SafeDivide(Func):
7277    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SafeMultiply(Func):
7280class SafeMultiply(Func):
7281    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safemultiply'
class SafeNegate(Func):
7284class SafeNegate(Func):
7285    pass
key = 'safenegate'
class SafeSubtract(Func):
7288class SafeSubtract(Func):
7289    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safesubtract'
class SafeConvertBytesToString(Func):
7292class SafeConvertBytesToString(Func):
7293    pass
key = 'safeconvertbytestostring'
class SHA(Func):
7296class SHA(Func):
7297    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
7300class SHA2(Func):
7301    _sql_names = ["SHA2"]
7302    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class SHA1Digest(Func):
7306class SHA1Digest(Func):
7307    pass
key = 'sha1digest'
class SHA2Digest(Func):
7311class SHA2Digest(Func):
7312    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2digest'
class Sign(Func):
7315class Sign(Func):
7316    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
7319class SortArray(Func):
7320    arg_types = {"this": True, "asc": False, "nulls_first": False}
arg_types = {'this': True, 'asc': False, 'nulls_first': False}
key = 'sortarray'
class Soundex(Func):
7323class Soundex(Func):
7324    pass
key = 'soundex'
class Split(Func):
7327class Split(Func):
7328    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
7332class SplitPart(Func):
7333    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
7338class Substring(Func):
7339    _sql_names = ["SUBSTRING", "SUBSTR"]
7340    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class SubstringIndex(Func):
7343class SubstringIndex(Func):
7344    """
7345    SUBSTRING_INDEX(str, delim, count)
7346
7347    *count* > 0  → left slice before the *count*-th delimiter
7348    *count* < 0  → right slice after the |count|-th delimiter
7349    """
7350
7351    arg_types = {"this": True, "delimiter": True, "count": True}

SUBSTRING_INDEX(str, delim, count)

count > 0 → left slice before the count-th delimiter count < 0 → right slice after the |count|-th delimiter

arg_types = {'this': True, 'delimiter': True, 'count': True}
key = 'substringindex'
class StandardHash(Func):
7354class StandardHash(Func):
7355    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
7358class StartsWith(Func):
7359    _sql_names = ["STARTS_WITH", "STARTSWITH"]
7360    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class EndsWith(Func):
7363class EndsWith(Func):
7364    _sql_names = ["ENDS_WITH", "ENDSWITH"]
7365    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'endswith'
class StrPosition(Func):
7368class StrPosition(Func):
7369    arg_types = {
7370        "this": True,
7371        "substr": True,
7372        "position": False,
7373        "occurrence": False,
7374    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
7377class StrToDate(Func):
7378    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
7381class StrToTime(Func):
7382    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):
7387class StrToUnix(Func):
7388    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
7393class StrToMap(Func):
7394    arg_types = {
7395        "this": True,
7396        "pair_delim": False,
7397        "key_value_delim": False,
7398        "duplicate_resolution_callback": False,
7399    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
7402class NumberToStr(Func):
7403    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
7406class FromBase(Func):
7407    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Space(Func):
7410class Space(Func):
7411    """
7412    SPACE(n) → string consisting of n blank characters
7413    """
7414
7415    pass

SPACE(n) → string consisting of n blank characters

key = 'space'
class Struct(Func):
7418class Struct(Func):
7419    arg_types = {"expressions": False}
7420    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
7423class StructExtract(Func):
7424    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
7429class Stuff(Func):
7430    _sql_names = ["STUFF", "INSERT"]
7431    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):
7434class Sum(AggFunc):
7435    pass
key = 'sum'
class Sqrt(Func):
7438class Sqrt(Func):
7439    pass
key = 'sqrt'
class Stddev(AggFunc):
7442class Stddev(AggFunc):
7443    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
7446class StddevPop(AggFunc):
7447    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
7450class StddevSamp(AggFunc):
7451    pass
key = 'stddevsamp'
class Time(Func):
7455class Time(Func):
7456    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
7459class TimeToStr(Func):
7460    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):
7463class TimeToTimeStr(Func):
7464    pass
key = 'timetotimestr'
class TimeToUnix(Func):
7467class TimeToUnix(Func):
7468    pass
key = 'timetounix'
class TimeStrToDate(Func):
7471class TimeStrToDate(Func):
7472    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
7475class TimeStrToTime(Func):
7476    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
7479class TimeStrToUnix(Func):
7480    pass
key = 'timestrtounix'
class Trim(Func):
7483class Trim(Func):
7484    arg_types = {
7485        "this": True,
7486        "expression": False,
7487        "position": False,
7488        "collation": False,
7489    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
7492class TsOrDsAdd(Func, TimeUnit):
7493    # return_type is used to correctly cast the arguments of this expression when transpiling it
7494    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
7495
7496    @property
7497    def return_type(self) -> DataType:
7498        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
7496    @property
7497    def return_type(self) -> DataType:
7498        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
7501class TsOrDsDiff(Func, TimeUnit):
7502    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
7505class TsOrDsToDateStr(Func):
7506    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
7509class TsOrDsToDate(Func):
7510    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
7513class TsOrDsToDatetime(Func):
7514    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
7517class TsOrDsToTime(Func):
7518    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
7521class TsOrDsToTimestamp(Func):
7522    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
7525class TsOrDiToDi(Func):
7526    pass
key = 'tsorditodi'
class Unhex(Func):
7529class Unhex(Func):
7530    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
7533class Unicode(Func):
7534    pass
key = 'unicode'
class UnixDate(Func):
7538class UnixDate(Func):
7539    pass
key = 'unixdate'
class UnixToStr(Func):
7542class UnixToStr(Func):
7543    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
7548class UnixToTime(Func):
7549    arg_types = {
7550        "this": True,
7551        "scale": False,
7552        "zone": False,
7553        "hours": False,
7554        "minutes": False,
7555        "format": False,
7556    }
7557
7558    SECONDS = Literal.number(0)
7559    DECIS = Literal.number(1)
7560    CENTIS = Literal.number(2)
7561    MILLIS = Literal.number(3)
7562    DECIMILLIS = Literal.number(4)
7563    CENTIMILLIS = Literal.number(5)
7564    MICROS = Literal.number(6)
7565    DECIMICROS = Literal.number(7)
7566    CENTIMICROS = Literal.number(8)
7567    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):
7570class UnixToTimeStr(Func):
7571    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
7574class UnixSeconds(Func):
7575    pass
key = 'unixseconds'
class UnixMicros(Func):
7578class UnixMicros(Func):
7579    pass
key = 'unixmicros'
class UnixMillis(Func):
7582class UnixMillis(Func):
7583    pass
key = 'unixmillis'
class Uuid(Func):
7586class Uuid(Func):
7587    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
7588
7589    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
7592class TimestampFromParts(Func):
7593    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
7594    arg_types = {
7595        "year": True,
7596        "month": True,
7597        "day": True,
7598        "hour": True,
7599        "min": True,
7600        "sec": True,
7601        "nano": False,
7602        "zone": False,
7603        "milli": False,
7604    }
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):
7607class Upper(Func):
7608    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
7611class Corr(Binary, AggFunc):
7612    pass
key = 'corr'
class CumeDist(AggFunc):
7616class CumeDist(AggFunc):
7617    arg_types = {"expressions": False}
7618    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'cumedist'
class Variance(AggFunc):
7621class Variance(AggFunc):
7622    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
7625class VariancePop(AggFunc):
7626    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
7629class CovarSamp(Binary, AggFunc):
7630    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
7633class CovarPop(Binary, AggFunc):
7634    pass
key = 'covarpop'
class Week(Func):
7637class Week(Func):
7638    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class WeekStart(Expression):
7641class WeekStart(Expression):
7642    pass
key = 'weekstart'
class XMLElement(Func):
7645class XMLElement(Func):
7646    _sql_names = ["XMLELEMENT"]
7647    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
7650class XMLTable(Func):
7651    arg_types = {
7652        "this": True,
7653        "namespaces": False,
7654        "passing": False,
7655        "columns": False,
7656        "by_ref": False,
7657    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
7660class XMLNamespace(Expression):
7661    pass
key = 'xmlnamespace'
class XMLKeyValueOption(Expression):
7665class XMLKeyValueOption(Expression):
7666    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'xmlkeyvalueoption'
class Year(Func):
7669class Year(Func):
7670    pass
key = 'year'
class Use(Expression):
7673class Use(Expression):
7674    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
7677class Merge(DML):
7678    arg_types = {
7679        "this": True,
7680        "using": True,
7681        "on": True,
7682        "whens": True,
7683        "with": False,
7684        "returning": False,
7685    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
7688class When(Expression):
7689    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
arg_types = {'matched': True, 'source': False, 'condition': False, 'then': True}
key = 'when'
class Whens(Expression):
7692class Whens(Expression):
7693    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
7694
7695    arg_types = {"expressions": True}

Wraps around one or more WHEN [NOT] MATCHED [...] clauses.

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
7700class NextValueFor(Func):
7701    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
7706class Semicolon(Expression):
7707    arg_types = {}
arg_types = {}
key = 'semicolon'
class TableColumn(Expression):
7712class TableColumn(Expression):
7713    pass
key = 'tablecolumn'
ALL_FUNCTIONS = [<class 'AIAgg'>, <class 'AIClassify'>, <class 'AISummarizeAgg'>, <class 'Abs'>, <class 'Acos'>, <class 'Acosh'>, <class 'AddMonths'>, <class 'And'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxQuantiles'>, <class 'ApproxTopK'>, <class 'ApproxTopSum'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConcatAgg'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayFirst'>, <class 'ArrayIntersect'>, <class 'ArrayLast'>, <class 'ArrayOverlaps'>, <class 'ArrayRemove'>, <class 'ArrayReverse'>, <class 'ArraySize'>, <class 'ArraySlice'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Ascii'>, <class 'Asin'>, <class 'Asinh'>, <class 'Atan'>, <class 'Atan2'>, <class 'Atanh'>, <class 'Avg'>, <class 'Base64DecodeBinary'>, <class 'Base64DecodeString'>, <class 'Base64Encode'>, <class 'BitLength'>, <class 'BitwiseAndAgg'>, <class 'BitwiseCountAgg'>, <class 'BitwiseOrAgg'>, <class 'BitwiseXorAgg'>, <class 'ByteLength'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'CodePointsToBytes'>, <class 'CodePointsToString'>, <class 'Collate'>, <class 'Collation'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Compress'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'ConvertToCharset'>, <class 'Corr'>, <class 'CosineDistance'>, <class 'Cot'>, <class 'Coth'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'Csc'>, <class 'Csch'>, <class 'CumeDist'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentSchema'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentTimestampLTZ'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateBin'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateFromUnixDate'>, <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 'DecodeCase'>, <class 'DecompressBinary'>, <class 'DecompressString'>, <class 'DenseRank'>, <class 'DiToDate'>, <class 'Encode'>, <class 'EndsWith'>, <class 'EuclideanDistance'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'FarmFingerprint'>, <class 'FeaturesAtTime'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Float64'>, <class 'Floor'>, <class 'Format'>, <class 'FromBase'>, <class 'FromBase32'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateEmbedding'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'GetExtract'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Grouping'>, <class 'Hex'>, <class 'HexDecodeString'>, <class 'HexEncode'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'Inline'>, <class 'Int64'>, <class 'IsAscii'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayAppend'>, <class 'JSONArrayContains'>, <class 'JSONArrayInsert'>, <class 'JSONBContains'>, <class 'JSONBContainsAllTopKeys'>, <class 'JSONBContainsAnyTopKeys'>, <class 'JSONBDeleteAtPath'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONBObjectAgg'>, <class 'JSONBool'>, <class 'JSONCast'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONKeysAtDepth'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONRemove'>, <class 'JSONSet'>, <class 'JSONStripNulls'>, <class 'JSONTable'>, <class 'JSONType'>, <class 'JSONValueArray'>, <class 'JarowinklerSimilarity'>, <class 'JustifyDays'>, <class 'JustifyHours'>, <class 'JustifyInterval'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'LaxBool'>, <class 'LaxFloat64'>, <class 'LaxInt64'>, <class 'LaxString'>, <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 'MD5NumberLower64'>, <class 'MD5NumberUpper64'>, <class 'MLForecast'>, <class 'MLTranslate'>, <class 'MakeInterval'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Median'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Normalize'>, <class 'NthValue'>, <class 'Ntile'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Or'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseBignumeric'>, <class 'ParseDatetime'>, <class 'ParseIp'>, <class 'ParseJSON'>, <class 'ParseNumeric'>, <class 'ParseTime'>, <class 'ParseUrl'>, <class 'PercentRank'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeBucket'>, <class 'RangeN'>, <class 'Rank'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpInstr'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Replace'>, <class 'Reverse'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'RtrimmedLength'>, <class 'SHA'>, <class 'SHA1Digest'>, <class 'SHA2'>, <class 'SHA2Digest'>, <class 'SafeAdd'>, <class 'SafeConvertBytesToString'>, <class 'SafeDivide'>, <class 'SafeMultiply'>, <class 'SafeNegate'>, <class 'SafeSubtract'>, <class 'Sec'>, <class 'Sech'>, <class 'Sign'>, <class 'Sin'>, <class 'Sinh'>, <class 'SortArray'>, <class 'Soundex'>, <class 'Space'>, <class 'Split'>, <class 'SplitPart'>, <class 'Sqrt'>, <class 'StDistance'>, <class 'StPoint'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'String'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'SubstringIndex'>, <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 'ToBase32'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToCodePoints'>, <class 'ToDays'>, <class 'ToDouble'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Translate'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToDatetime'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Typeof'>, <class 'Unhex'>, <class 'Unicode'>, <class 'UnixDate'>, <class 'UnixMicros'>, <class 'UnixMillis'>, <class 'UnixSeconds'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'UtcDate'>, <class 'UtcTime'>, <class 'UtcTimestamp'>, <class 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'VectorSearch'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'XMLElement'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'AI_AGG': <class 'AIAgg'>, 'AI_CLASSIFY': <class 'AIClassify'>, 'AI_SUMMARIZE_AGG': <class 'AISummarizeAgg'>, 'ABS': <class 'Abs'>, 'ACOS': <class 'Acos'>, 'ACOSH': <class 'Acosh'>, 'ADD_MONTHS': <class 'AddMonths'>, 'AND': <class 'And'>, '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_QUANTILES': <class 'ApproxQuantiles'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'APPROX_TOP_SUM': <class 'ApproxTopSum'>, '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_CONCAT_AGG': <class 'ArrayConcatAgg'>, '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_FIRST': <class 'ArrayFirst'>, 'ARRAY_INTERSECT': <class 'ArrayIntersect'>, 'ARRAY_INTERSECTION': <class 'ArrayIntersect'>, 'ARRAY_LAST': <class 'ArrayLast'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_REMOVE': <class 'ArrayRemove'>, 'ARRAY_REVERSE': <class 'ArrayReverse'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SLICE': <class 'ArraySlice'>, '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'>, 'ASCII': <class 'Ascii'>, 'ASIN': <class 'Asin'>, 'ASINH': <class 'Asinh'>, 'ATAN': <class 'Atan'>, 'ATAN2': <class 'Atan2'>, 'ATANH': <class 'Atanh'>, 'AVG': <class 'Avg'>, 'BASE64_DECODE_BINARY': <class 'Base64DecodeBinary'>, 'BASE64_DECODE_STRING': <class 'Base64DecodeString'>, 'BASE64_ENCODE': <class 'Base64Encode'>, 'BIT_LENGTH': <class 'BitLength'>, 'BITWISE_AND_AGG': <class 'BitwiseAndAgg'>, 'BITWISE_COUNT_AGG': <class 'BitwiseCountAgg'>, 'BITWISE_OR_AGG': <class 'BitwiseOrAgg'>, 'BITWISE_XOR_AGG': <class 'BitwiseXorAgg'>, 'BYTE_LENGTH': <class 'ByteLength'>, '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'>, 'CODE_POINTS_TO_BYTES': <class 'CodePointsToBytes'>, 'CODE_POINTS_TO_STRING': <class 'CodePointsToString'>, 'COLLATE': <class 'Collate'>, 'COLLATION': <class 'Collation'>, 'COLUMNS': <class 'Columns'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'COMPRESS': <class 'Compress'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONTAINS': <class 'Contains'>, 'CONVERT': <class 'Convert'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CONVERT_TO_CHARSET': <class 'ConvertToCharset'>, 'CORR': <class 'Corr'>, 'COSINE_DISTANCE': <class 'CosineDistance'>, 'COT': <class 'Cot'>, 'COTH': <class 'Coth'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CSC': <class 'Csc'>, 'CSCH': <class 'Csch'>, 'CUME_DIST': <class 'CumeDist'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_SCHEMA': <class 'CurrentSchema'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_TIMESTAMP_L_T_Z': <class 'CurrentTimestampLTZ'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATE_BIN': <class 'DateBin'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_FROM_UNIX_DATE': <class 'DateFromUnixDate'>, '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'>, 'DECODE_CASE': <class 'DecodeCase'>, 'DECOMPRESS_BINARY': <class 'DecompressBinary'>, 'DECOMPRESS_STRING': <class 'DecompressString'>, 'DENSE_RANK': <class 'DenseRank'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'ENDS_WITH': <class 'EndsWith'>, 'ENDSWITH': <class 'EndsWith'>, 'EUCLIDEAN_DISTANCE': <class 'EuclideanDistance'>, 'EXISTS': <class 'Exists'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FARM_FINGERPRINT': <class 'FarmFingerprint'>, 'FARMFINGERPRINT64': <class 'FarmFingerprint'>, 'FEATURES_AT_TIME': <class 'FeaturesAtTime'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOAT64': <class 'Float64'>, 'FLOOR': <class 'Floor'>, 'FORMAT': <class 'Format'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE32': <class 'FromBase32'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_EMBEDDING': <class 'GenerateEmbedding'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GET_EXTRACT': <class 'GetExtract'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'GROUPING': <class 'Grouping'>, 'HEX': <class 'Hex'>, 'HEX_DECODE_STRING': <class 'HexDecodeString'>, 'HEX_ENCODE': <class 'HexEncode'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'INLINE': <class 'Inline'>, 'INT64': <class 'Int64'>, 'IS_ASCII': <class 'IsAscii'>, '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_APPEND': <class 'JSONArrayAppend'>, 'JSON_ARRAY_CONTAINS': <class 'JSONArrayContains'>, 'JSON_ARRAY_INSERT': <class 'JSONArrayInsert'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'J_S_O_N_B_CONTAINS_ALL_TOP_KEYS': <class 'JSONBContainsAllTopKeys'>, 'J_S_O_N_B_CONTAINS_ANY_TOP_KEYS': <class 'JSONBContainsAnyTopKeys'>, 'J_S_O_N_B_DELETE_AT_PATH': <class 'JSONBDeleteAtPath'>, 'JSONB_EXISTS': <class 'JSONBExists'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, 'J_S_O_N_B_OBJECT_AGG': <class 'JSONBObjectAgg'>, 'J_S_O_N_BOOL': <class 'JSONBool'>, 'J_S_O_N_CAST': <class 'JSONCast'>, 'J_S_O_N_EXISTS': <class 'JSONExists'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_ARRAY': <class 'JSONExtractArray'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_KEYS_AT_DEPTH': <class 'JSONKeysAtDepth'>, 'J_S_O_N_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'JSON_REMOVE': <class 'JSONRemove'>, 'JSON_SET': <class 'JSONSet'>, 'JSON_STRIP_NULLS': <class 'JSONStripNulls'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'JSON_TYPE': <class 'JSONType'>, 'J_S_O_N_VALUE_ARRAY': <class 'JSONValueArray'>, 'JAROWINKLER_SIMILARITY': <class 'JarowinklerSimilarity'>, 'JUSTIFY_DAYS': <class 'JustifyDays'>, 'JUSTIFY_HOURS': <class 'JustifyHours'>, 'JUSTIFY_INTERVAL': <class 'JustifyInterval'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LAX_BOOL': <class 'LaxBool'>, 'LAX_FLOAT64': <class 'LaxFloat64'>, 'LAX_INT64': <class 'LaxInt64'>, 'LAX_STRING': <class 'LaxString'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, 'CHAR_LENGTH': <class 'Length'>, 'CHARACTER_LENGTH': <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'>, 'M_D5_NUMBER_LOWER64': <class 'MD5NumberLower64'>, 'M_D5_NUMBER_UPPER64': <class 'MD5NumberUpper64'>, 'M_L_FORECAST': <class 'MLForecast'>, 'M_L_TRANSLATE': <class 'MLTranslate'>, 'MAKE_INTERVAL': <class 'MakeInterval'>, 'MAP': <class 'Map'>, 'MAP_FROM_ENTRIES': <class 'MapFromEntries'>, 'MATCH_AGAINST': <class 'MatchAgainst'>, 'MAX': <class 'Max'>, 'MEDIAN': <class 'Median'>, 'MIN': <class 'Min'>, 'MONTH': <class 'Month'>, 'MONTHS_BETWEEN': <class 'MonthsBetween'>, 'NEXT_VALUE_FOR': <class 'NextValueFor'>, 'NORMALIZE': <class 'Normalize'>, 'NTH_VALUE': <class 'NthValue'>, 'NTILE': <class 'Ntile'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'OR': <class 'Or'>, 'OVERLAY': <class 'Overlay'>, 'PAD': <class 'Pad'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_BIGNUMERIC': <class 'ParseBignumeric'>, 'PARSE_DATETIME': <class 'ParseDatetime'>, 'PARSE_IP': <class 'ParseIp'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PARSE_NUMERIC': <class 'ParseNumeric'>, 'PARSE_TIME': <class 'ParseTime'>, 'PARSE_URL': <class 'ParseUrl'>, 'PERCENT_RANK': <class 'PercentRank'>, '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_BUCKET': <class 'RangeBucket'>, 'RANGE_N': <class 'RangeN'>, 'RANK': <class 'Rank'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_INSTR': <class 'RegexpInstr'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'REPLACE': <class 'Replace'>, 'REVERSE': <class 'Reverse'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'RTRIMMED_LENGTH': <class 'RtrimmedLength'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'S_H_A1_DIGEST': <class 'SHA1Digest'>, 'SHA2': <class 'SHA2'>, 'S_H_A2_DIGEST': <class 'SHA2Digest'>, 'SAFE_ADD': <class 'SafeAdd'>, 'SAFE_CONVERT_BYTES_TO_STRING': <class 'SafeConvertBytesToString'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SAFE_MULTIPLY': <class 'SafeMultiply'>, 'SAFE_NEGATE': <class 'SafeNegate'>, 'SAFE_SUBTRACT': <class 'SafeSubtract'>, 'SEC': <class 'Sec'>, 'SECH': <class 'Sech'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SIN': <class 'Sin'>, 'SINH': <class 'Sinh'>, 'SORT_ARRAY': <class 'SortArray'>, 'SOUNDEX': <class 'Soundex'>, 'SPACE': <class 'Space'>, 'SPLIT': <class 'Split'>, 'SPLIT_PART': <class 'SplitPart'>, 'SQRT': <class 'Sqrt'>, 'ST_DISTANCE': <class 'StDistance'>, 'ST_POINT': <class 'StPoint'>, 'ST_MAKEPOINT': <class 'StPoint'>, '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': <class 'String'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRTOK_TO_ARRAY': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUBSTR': <class 'Substring'>, 'SUBSTRING_INDEX': <class 'SubstringIndex'>, '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_BASE32': <class 'ToBase32'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_CODE_POINTS': <class 'ToCodePoints'>, 'TO_DAYS': <class 'ToDays'>, 'TO_DOUBLE': <class 'ToDouble'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRANSLATE': <class 'Translate'>, '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_DATETIME': <class 'TsOrDsToDatetime'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'TYPEOF': <class 'Typeof'>, 'UNHEX': <class 'Unhex'>, 'UNICODE': <class 'Unicode'>, 'UNIX_DATE': <class 'UnixDate'>, 'UNIX_MICROS': <class 'UnixMicros'>, 'UNIX_MILLIS': <class 'UnixMillis'>, 'UNIX_SECONDS': <class 'UnixSeconds'>, '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'>, 'UTC_DATE': <class 'UtcDate'>, 'UTC_TIME': <class 'UtcTime'>, 'UTC_TIMESTAMP': <class 'UtcTimestamp'>, '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'>, 'VECTOR_SEARCH': <class 'VectorSearch'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, 'XMLELEMENT': <class 'XMLElement'>, '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, Type[sqlglot.dialects.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
7753def maybe_parse(
7754    sql_or_expression: ExpOrStr,
7755    *,
7756    into: t.Optional[IntoType] = None,
7757    dialect: DialectType = None,
7758    prefix: t.Optional[str] = None,
7759    copy: bool = False,
7760    **opts,
7761) -> Expression:
7762    """Gracefully handle a possible string or expression.
7763
7764    Example:
7765        >>> maybe_parse("1")
7766        Literal(this=1, is_string=False)
7767        >>> maybe_parse(to_identifier("x"))
7768        Identifier(this=x, quoted=False)
7769
7770    Args:
7771        sql_or_expression: the SQL code string or an expression
7772        into: the SQLGlot Expression to parse into
7773        dialect: the dialect used to parse the input expressions (in the case that an
7774            input expression is a SQL string).
7775        prefix: a string to prefix the sql with before it gets parsed
7776            (automatically includes a space)
7777        copy: whether to copy the expression.
7778        **opts: other options to use to parse the input expressions (again, in the case
7779            that an input expression is a SQL string).
7780
7781    Returns:
7782        Expression: the parsed or given expression.
7783    """
7784    if isinstance(sql_or_expression, Expression):
7785        if copy:
7786            return sql_or_expression.copy()
7787        return sql_or_expression
7788
7789    if sql_or_expression is None:
7790        raise ParseError("SQL cannot be None")
7791
7792    import sqlglot
7793
7794    sql = str(sql_or_expression)
7795    if prefix:
7796        sql = f"{prefix} {sql}"
7797
7798    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):
7809def maybe_copy(instance, copy=True):
7810    return instance.copy() if copy and instance else instance
def union( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
8065def union(
8066    *expressions: ExpOrStr,
8067    distinct: bool = True,
8068    dialect: DialectType = None,
8069    copy: bool = True,
8070    **opts,
8071) -> Union:
8072    """
8073    Initializes a syntax tree for the `UNION` operation.
8074
8075    Example:
8076        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
8077        'SELECT * FROM foo UNION SELECT * FROM bla'
8078
8079    Args:
8080        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
8081            If `Expression` instances are passed, they will be used as-is.
8082        distinct: set the DISTINCT flag if and only if this is true.
8083        dialect: the dialect used to parse the input expression.
8084        copy: whether to copy the expression.
8085        opts: other options to use to parse the input expressions.
8086
8087    Returns:
8088        The new Union instance.
8089    """
8090    assert len(expressions) >= 2, "At least two expressions are required by `union`."
8091    return _apply_set_operation(
8092        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
8093    )

Initializes a syntax tree for the UNION operation.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the UNION's operands. If Expression instances are passed, they 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( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
8096def intersect(
8097    *expressions: ExpOrStr,
8098    distinct: bool = True,
8099    dialect: DialectType = None,
8100    copy: bool = True,
8101    **opts,
8102) -> Intersect:
8103    """
8104    Initializes a syntax tree for the `INTERSECT` operation.
8105
8106    Example:
8107        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
8108        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
8109
8110    Args:
8111        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
8112            If `Expression` instances are passed, they will be used as-is.
8113        distinct: set the DISTINCT flag if and only if this is true.
8114        dialect: the dialect used to parse the input expression.
8115        copy: whether to copy the expression.
8116        opts: other options to use to parse the input expressions.
8117
8118    Returns:
8119        The new Intersect instance.
8120    """
8121    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
8122    return _apply_set_operation(
8123        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
8124    )

Initializes a syntax tree for the INTERSECT operation.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the INTERSECT's operands. If Expression instances are passed, they 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_( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
8127def except_(
8128    *expressions: ExpOrStr,
8129    distinct: bool = True,
8130    dialect: DialectType = None,
8131    copy: bool = True,
8132    **opts,
8133) -> Except:
8134    """
8135    Initializes a syntax tree for the `EXCEPT` operation.
8136
8137    Example:
8138        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
8139        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
8140
8141    Args:
8142        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
8143            If `Expression` instances are passed, they will be used as-is.
8144        distinct: set the DISTINCT flag if and only if this is true.
8145        dialect: the dialect used to parse the input expression.
8146        copy: whether to copy the expression.
8147        opts: other options to use to parse the input expressions.
8148
8149    Returns:
8150        The new Except instance.
8151    """
8152    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
8153    return _apply_set_operation(
8154        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
8155    )

Initializes a syntax tree for the EXCEPT operation.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the EXCEPT's operands. If Expression instances are passed, they 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, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
8158def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
8159    """
8160    Initializes a syntax tree from one or multiple SELECT expressions.
8161
8162    Example:
8163        >>> select("col1", "col2").from_("tbl").sql()
8164        'SELECT col1, col2 FROM tbl'
8165
8166    Args:
8167        *expressions: the SQL code string to parse as the expressions of a
8168            SELECT statement. If an Expression instance is passed, this is used as-is.
8169        dialect: the dialect used to parse the input expressions (in the case that an
8170            input expression is a SQL string).
8171        **opts: other options to use to parse the input expressions (again, in the case
8172            that an input expression is a SQL string).
8173
8174    Returns:
8175        Select: the syntax tree for the SELECT statement.
8176    """
8177    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, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
8180def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
8181    """
8182    Initializes a syntax tree from a FROM expression.
8183
8184    Example:
8185        >>> from_("tbl").select("col1", "col2").sql()
8186        'SELECT col1, col2 FROM tbl'
8187
8188    Args:
8189        *expression: the SQL code string to parse as the FROM expressions of a
8190            SELECT statement. If an Expression instance is passed, this is used as-is.
8191        dialect: the dialect used to parse the input expression (in the case that the
8192            input expression is a SQL string).
8193        **opts: other options to use to parse the input expressions (again, in the case
8194            that the input expression is a SQL string).
8195
8196    Returns:
8197        Select: the syntax tree for the SELECT statement.
8198    """
8199    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: Optional[dict] = None, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, with_: Optional[Dict[str, Union[str, Expression]]] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Update:
8202def update(
8203    table: str | Table,
8204    properties: t.Optional[dict] = None,
8205    where: t.Optional[ExpOrStr] = None,
8206    from_: t.Optional[ExpOrStr] = None,
8207    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
8208    dialect: DialectType = None,
8209    **opts,
8210) -> Update:
8211    """
8212    Creates an update statement.
8213
8214    Example:
8215        >>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
8216        "WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
8217
8218    Args:
8219        properties: dictionary of properties to SET which are
8220            auto converted to sql objects eg None -> NULL
8221        where: sql conditional parsed into a WHERE statement
8222        from_: sql statement parsed into a FROM statement
8223        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
8224        dialect: the dialect used to parse the input expressions.
8225        **opts: other options to use to parse the input expressions.
8226
8227    Returns:
8228        Update: the syntax tree for the UPDATE statement.
8229    """
8230    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
8231    if properties:
8232        update_expr.set(
8233            "expressions",
8234            [
8235                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
8236                for k, v in properties.items()
8237            ],
8238        )
8239    if from_:
8240        update_expr.set(
8241            "from",
8242            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
8243        )
8244    if isinstance(where, Condition):
8245        where = Where(this=where)
8246    if where:
8247        update_expr.set(
8248            "where",
8249            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
8250        )
8251    if with_:
8252        cte_list = [
8253            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
8254            for alias, qry in with_.items()
8255        ]
8256        update_expr.set(
8257            "with",
8258            With(expressions=cte_list),
8259        )
8260    return update_expr

Creates an update statement.

Example:
>>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
"WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
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
  • with_: dictionary of CTE aliases / select statements to include in a WITH clause.
  • 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, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Delete:
8263def delete(
8264    table: ExpOrStr,
8265    where: t.Optional[ExpOrStr] = None,
8266    returning: t.Optional[ExpOrStr] = None,
8267    dialect: DialectType = None,
8268    **opts,
8269) -> Delete:
8270    """
8271    Builds a delete statement.
8272
8273    Example:
8274        >>> delete("my_table", where="id > 1").sql()
8275        'DELETE FROM my_table WHERE id > 1'
8276
8277    Args:
8278        where: sql conditional parsed into a WHERE statement
8279        returning: sql conditional parsed into a RETURNING statement
8280        dialect: the dialect used to parse the input expressions.
8281        **opts: other options to use to parse the input expressions.
8282
8283    Returns:
8284        Delete: the syntax tree for the DELETE statement.
8285    """
8286    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
8287    if where:
8288        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
8289    if returning:
8290        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
8291    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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
8294def insert(
8295    expression: ExpOrStr,
8296    into: ExpOrStr,
8297    columns: t.Optional[t.Sequence[str | Identifier]] = None,
8298    overwrite: t.Optional[bool] = None,
8299    returning: t.Optional[ExpOrStr] = None,
8300    dialect: DialectType = None,
8301    copy: bool = True,
8302    **opts,
8303) -> Insert:
8304    """
8305    Builds an INSERT statement.
8306
8307    Example:
8308        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
8309        'INSERT INTO tbl VALUES (1, 2, 3)'
8310
8311    Args:
8312        expression: the sql string or expression of the INSERT statement
8313        into: the tbl to insert data to.
8314        columns: optionally the table's column names.
8315        overwrite: whether to INSERT OVERWRITE or not.
8316        returning: sql conditional parsed into a RETURNING statement
8317        dialect: the dialect used to parse the input expressions.
8318        copy: whether to copy the expression.
8319        **opts: other options to use to parse the input expressions.
8320
8321    Returns:
8322        Insert: the syntax tree for the INSERT statement.
8323    """
8324    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8325    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
8326
8327    if columns:
8328        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
8329
8330    insert = Insert(this=this, expression=expr, overwrite=overwrite)
8331
8332    if returning:
8333        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
8334
8335    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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
8338def merge(
8339    *when_exprs: ExpOrStr,
8340    into: ExpOrStr,
8341    using: ExpOrStr,
8342    on: ExpOrStr,
8343    returning: t.Optional[ExpOrStr] = None,
8344    dialect: DialectType = None,
8345    copy: bool = True,
8346    **opts,
8347) -> Merge:
8348    """
8349    Builds a MERGE statement.
8350
8351    Example:
8352        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
8353        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
8354        ...       into="my_table",
8355        ...       using="source_table",
8356        ...       on="my_table.id = source_table.id").sql()
8357        '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)'
8358
8359    Args:
8360        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
8361        into: The target table to merge data into.
8362        using: The source table to merge data from.
8363        on: The join condition for the merge.
8364        returning: The columns to return from the merge.
8365        dialect: The dialect used to parse the input expressions.
8366        copy: Whether to copy the expression.
8367        **opts: Other options to use to parse the input expressions.
8368
8369    Returns:
8370        Merge: The syntax tree for the MERGE statement.
8371    """
8372    expressions: t.List[Expression] = []
8373    for when_expr in when_exprs:
8374        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
8375        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
8376
8377    merge = Merge(
8378        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
8379        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
8380        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
8381        whens=Whens(expressions=expressions),
8382    )
8383    if returning:
8384        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
8385
8386    if isinstance(using_clause := merge.args.get("using"), Alias):
8387        using_clause.replace(alias_(using_clause.this, using_clause.args["alias"], table=True))
8388
8389    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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
8392def condition(
8393    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
8394) -> Condition:
8395    """
8396    Initialize a logical condition expression.
8397
8398    Example:
8399        >>> condition("x=1").sql()
8400        'x = 1'
8401
8402        This is helpful for composing larger logical syntax trees:
8403        >>> where = condition("x=1")
8404        >>> where = where.and_("y=1")
8405        >>> Select().from_("tbl").select("*").where(where).sql()
8406        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
8407
8408    Args:
8409        *expression: the SQL code string to parse.
8410            If an Expression instance is passed, this is used as-is.
8411        dialect: the dialect used to parse the input expression (in the case that the
8412            input expression is a SQL string).
8413        copy: Whether to copy `expression` (only applies to expressions).
8414        **opts: other options to use to parse the input expressions (again, in the case
8415            that the input expression is a SQL string).
8416
8417    Returns:
8418        The new Condition instance
8419    """
8420    return maybe_parse(
8421        expression,
8422        into=Condition,
8423        dialect=dialect,
8424        copy=copy,
8425        **opts,
8426    )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
8429def and_(
8430    *expressions: t.Optional[ExpOrStr],
8431    dialect: DialectType = None,
8432    copy: bool = True,
8433    wrap: bool = True,
8434    **opts,
8435) -> Condition:
8436    """
8437    Combine multiple conditions with an AND logical operator.
8438
8439    Example:
8440        >>> and_("x=1", and_("y=1", "z=1")).sql()
8441        'x = 1 AND (y = 1 AND z = 1)'
8442
8443    Args:
8444        *expressions: the SQL code strings to parse.
8445            If an Expression instance is passed, this is used as-is.
8446        dialect: the dialect used to parse the input expression.
8447        copy: whether to copy `expressions` (only applies to Expressions).
8448        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8449            precedence issues, but can be turned off when the produced AST is too deep and
8450            causes recursion-related issues.
8451        **opts: other options to use to parse the input expressions.
8452
8453    Returns:
8454        The new condition
8455    """
8456    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **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).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
8459def or_(
8460    *expressions: t.Optional[ExpOrStr],
8461    dialect: DialectType = None,
8462    copy: bool = True,
8463    wrap: bool = True,
8464    **opts,
8465) -> Condition:
8466    """
8467    Combine multiple conditions with an OR logical operator.
8468
8469    Example:
8470        >>> or_("x=1", or_("y=1", "z=1")).sql()
8471        'x = 1 OR (y = 1 OR z = 1)'
8472
8473    Args:
8474        *expressions: the SQL code strings to parse.
8475            If an Expression instance is passed, this is used as-is.
8476        dialect: the dialect used to parse the input expression.
8477        copy: whether to copy `expressions` (only applies to Expressions).
8478        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8479            precedence issues, but can be turned off when the produced AST is too deep and
8480            causes recursion-related issues.
8481        **opts: other options to use to parse the input expressions.
8482
8483    Returns:
8484        The new condition
8485    """
8486    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **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).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
8489def xor(
8490    *expressions: t.Optional[ExpOrStr],
8491    dialect: DialectType = None,
8492    copy: bool = True,
8493    wrap: bool = True,
8494    **opts,
8495) -> Condition:
8496    """
8497    Combine multiple conditions with an XOR logical operator.
8498
8499    Example:
8500        >>> xor("x=1", xor("y=1", "z=1")).sql()
8501        'x = 1 XOR (y = 1 XOR z = 1)'
8502
8503    Args:
8504        *expressions: the SQL code strings to parse.
8505            If an Expression instance is passed, this is used as-is.
8506        dialect: the dialect used to parse the input expression.
8507        copy: whether to copy `expressions` (only applies to Expressions).
8508        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
8509            precedence issues, but can be turned off when the produced AST is too deep and
8510            causes recursion-related issues.
8511        **opts: other options to use to parse the input expressions.
8512
8513    Returns:
8514        The new condition
8515    """
8516    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **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).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
8519def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
8520    """
8521    Wrap a condition with a NOT operator.
8522
8523    Example:
8524        >>> not_("this_suit='black'").sql()
8525        "NOT this_suit = 'black'"
8526
8527    Args:
8528        expression: the SQL code string to parse.
8529            If an Expression instance is passed, this is used as-is.
8530        dialect: the dialect used to parse the input expression.
8531        copy: whether to copy the expression or not.
8532        **opts: other options to use to parse the input expressions.
8533
8534    Returns:
8535        The new condition.
8536    """
8537    this = condition(
8538        expression,
8539        dialect=dialect,
8540        copy=copy,
8541        **opts,
8542    )
8543    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:
8546def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
8547    """
8548    Wrap an expression in parentheses.
8549
8550    Example:
8551        >>> paren("5 + 3").sql()
8552        '(5 + 3)'
8553
8554    Args:
8555        expression: the SQL code string to parse.
8556            If an Expression instance is passed, this is used as-is.
8557        copy: whether to copy the expression or not.
8558
8559    Returns:
8560        The wrapped expression.
8561    """
8562    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):
8578def to_identifier(name, quoted=None, copy=True):
8579    """Builds an identifier.
8580
8581    Args:
8582        name: The name to turn into an identifier.
8583        quoted: Whether to force quote the identifier.
8584        copy: Whether to copy name if it's an Identifier.
8585
8586    Returns:
8587        The identifier ast node.
8588    """
8589
8590    if name is None:
8591        return None
8592
8593    if isinstance(name, Identifier):
8594        identifier = maybe_copy(name, copy)
8595    elif isinstance(name, str):
8596        identifier = Identifier(
8597            this=name,
8598            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
8599        )
8600    else:
8601        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
8602    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, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Identifier:
8605def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
8606    """
8607    Parses a given string into an identifier.
8608
8609    Args:
8610        name: The name to parse into an identifier.
8611        dialect: The dialect to parse against.
8612
8613    Returns:
8614        The identifier ast node.
8615    """
8616    try:
8617        expression = maybe_parse(name, dialect=dialect, into=Identifier)
8618    except (ParseError, TokenError):
8619        expression = to_identifier(name)
8620
8621    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]+(?:\\.[0-9]+)?)\\s*([a-zA-Z]+)\\s*')
INTERVAL_DAY_TIME_RE = re.compile('\\s*-?\\s*\\d+(?:\\.\\d+)?\\s+(?:-?(?:\\d+:)?\\d+:\\d+(?:\\.\\d+)?|-?(?:\\d+:){1,2}|:)\\s*')
def to_interval( interval: str | Literal) -> Interval:
8640def to_interval(interval: str | Literal) -> Interval:
8641    """Builds an interval expression from a string like '1 day' or '5 months'."""
8642    if isinstance(interval, Literal):
8643        if not interval.is_string:
8644            raise ValueError("Invalid interval string.")
8645
8646        interval = interval.this
8647
8648    interval = maybe_parse(f"INTERVAL {interval}")
8649    assert isinstance(interval, Interval)
8650    return interval

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
8653def to_table(
8654    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
8655) -> Table:
8656    """
8657    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
8658    If a table is passed in then that table is returned.
8659
8660    Args:
8661        sql_path: a `[catalog].[schema].[table]` string.
8662        dialect: the source dialect according to which the table name will be parsed.
8663        copy: Whether to copy a table if it is passed in.
8664        kwargs: the kwargs to instantiate the resulting `Table` expression with.
8665
8666    Returns:
8667        A table expression.
8668    """
8669    if isinstance(sql_path, Table):
8670        return maybe_copy(sql_path, copy=copy)
8671
8672    try:
8673        table = maybe_parse(sql_path, into=Table, dialect=dialect)
8674    except ParseError:
8675        catalog, db, this = split_num_words(sql_path, ".", 3)
8676
8677        if not this:
8678            raise
8679
8680        table = table_(this, db=db, catalog=catalog)
8681
8682    for k, v in kwargs.items():
8683        table.set(k, v)
8684
8685    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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
8688def to_column(
8689    sql_path: str | Column,
8690    quoted: t.Optional[bool] = None,
8691    dialect: DialectType = None,
8692    copy: bool = True,
8693    **kwargs,
8694) -> Column:
8695    """
8696    Create a column from a `[table].[column]` sql path. Table is optional.
8697    If a column is passed in then that column is returned.
8698
8699    Args:
8700        sql_path: a `[table].[column]` string.
8701        quoted: Whether or not to force quote identifiers.
8702        dialect: the source dialect according to which the column name will be parsed.
8703        copy: Whether to copy a column if it is passed in.
8704        kwargs: the kwargs to instantiate the resulting `Column` expression with.
8705
8706    Returns:
8707        A column expression.
8708    """
8709    if isinstance(sql_path, Column):
8710        return maybe_copy(sql_path, copy=copy)
8711
8712    try:
8713        col = maybe_parse(sql_path, into=Column, dialect=dialect)
8714    except ParseError:
8715        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
8716
8717    for k, v in kwargs.items():
8718        col.set(k, v)
8719
8720    if quoted:
8721        for i in col.find_all(Identifier):
8722            i.set("quoted", True)
8723
8724    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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts):
8727def alias_(
8728    expression: ExpOrStr,
8729    alias: t.Optional[str | Identifier],
8730    table: bool | t.Sequence[str | Identifier] = False,
8731    quoted: t.Optional[bool] = None,
8732    dialect: DialectType = None,
8733    copy: bool = True,
8734    **opts,
8735):
8736    """Create an Alias expression.
8737
8738    Example:
8739        >>> alias_('foo', 'bar').sql()
8740        'foo AS bar'
8741
8742        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
8743        '(SELECT 1, 2) AS bar(a, b)'
8744
8745    Args:
8746        expression: the SQL code strings to parse.
8747            If an Expression instance is passed, this is used as-is.
8748        alias: the alias name to use. If the name has
8749            special characters it is quoted.
8750        table: Whether to create a table alias, can also be a list of columns.
8751        quoted: whether to quote the alias
8752        dialect: the dialect used to parse the input expression.
8753        copy: Whether to copy the expression.
8754        **opts: other options to use to parse the input expressions.
8755
8756    Returns:
8757        Alias: the aliased expression
8758    """
8759    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
8760    alias = to_identifier(alias, quoted=quoted)
8761
8762    if table:
8763        table_alias = TableAlias(this=alias)
8764        exp.set("alias", table_alias)
8765
8766        if not isinstance(table, bool):
8767            for column in table:
8768                table_alias.append("columns", to_identifier(column, quoted=quoted))
8769
8770        return exp
8771
8772    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
8773    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
8774    # for the complete Window expression.
8775    #
8776    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
8777
8778    if "alias" in exp.arg_types and not isinstance(exp, Window):
8779        exp.set("alias", alias)
8780        return exp
8781    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, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
8784def subquery(
8785    expression: ExpOrStr,
8786    alias: t.Optional[Identifier | str] = None,
8787    dialect: DialectType = None,
8788    **opts,
8789) -> Select:
8790    """
8791    Build a subquery expression that's selected from.
8792
8793    Example:
8794        >>> subquery('select x from tbl', 'bar').select('x').sql()
8795        'SELECT x FROM (SELECT x FROM tbl) AS bar'
8796
8797    Args:
8798        expression: the SQL code strings to parse.
8799            If an Expression instance is passed, this is used as-is.
8800        alias: the alias name to use.
8801        dialect: the dialect used to parse the input expression.
8802        **opts: other options to use to parse the input expressions.
8803
8804    Returns:
8805        A new Select instance with the subquery expression included.
8806    """
8807
8808    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
8809    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):
8840def column(
8841    col,
8842    table=None,
8843    db=None,
8844    catalog=None,
8845    *,
8846    fields=None,
8847    quoted=None,
8848    copy=True,
8849):
8850    """
8851    Build a Column.
8852
8853    Args:
8854        col: Column name.
8855        table: Table name.
8856        db: Database name.
8857        catalog: Catalog name.
8858        fields: Additional fields using dots.
8859        quoted: Whether to force quotes on the column's identifiers.
8860        copy: Whether to copy identifiers if passed in.
8861
8862    Returns:
8863        The new Column instance.
8864    """
8865    if not isinstance(col, Star):
8866        col = to_identifier(col, quoted=quoted, copy=copy)
8867
8868    this = Column(
8869        this=col,
8870        table=to_identifier(table, quoted=quoted, copy=copy),
8871        db=to_identifier(db, quoted=quoted, copy=copy),
8872        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8873    )
8874
8875    if fields:
8876        this = Dot.build(
8877            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8878        )
8879    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, Identifier, Dot, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Cast:
8882def cast(
8883    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8884) -> Cast:
8885    """Cast an expression to a data type.
8886
8887    Example:
8888        >>> cast('x + 1', 'int').sql()
8889        'CAST(x + 1 AS INT)'
8890
8891    Args:
8892        expression: The expression to cast.
8893        to: The datatype to cast to.
8894        copy: Whether to copy the supplied expressions.
8895        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8896            - The expression to be cast is already a exp.Cast expression
8897            - The existing cast is to a type that is logically equivalent to new type
8898
8899            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8900            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8901            and instead just return the original expression `CAST(x as DATETIME)`.
8902
8903            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8904            mapping is applied in the target dialect generator.
8905
8906    Returns:
8907        The new Cast instance.
8908    """
8909    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8910    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8911
8912    # dont re-cast if the expression is already a cast to the correct type
8913    if isinstance(expr, Cast):
8914        from sqlglot.dialects.dialect import Dialect
8915
8916        target_dialect = Dialect.get_or_raise(dialect)
8917        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8918
8919        existing_cast_type: DataType.Type = expr.to.this
8920        new_cast_type: DataType.Type = data_type.this
8921        types_are_equivalent = type_mapping.get(
8922            existing_cast_type, existing_cast_type.value
8923        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8924
8925        if expr.is_type(data_type) or types_are_equivalent:
8926            return expr
8927
8928    expr = Cast(this=expr, to=data_type)
8929    expr.type = data_type
8930
8931    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:
8934def table_(
8935    table: Identifier | str,
8936    db: t.Optional[Identifier | str] = None,
8937    catalog: t.Optional[Identifier | str] = None,
8938    quoted: t.Optional[bool] = None,
8939    alias: t.Optional[Identifier | str] = None,
8940) -> Table:
8941    """Build a Table.
8942
8943    Args:
8944        table: Table name.
8945        db: Database name.
8946        catalog: Catalog name.
8947        quote: Whether to force quotes on the table's identifiers.
8948        alias: Table's alias.
8949
8950    Returns:
8951        The new Table instance.
8952    """
8953    return Table(
8954        this=to_identifier(table, quoted=quoted) if table else None,
8955        db=to_identifier(db, quoted=quoted) if db else None,
8956        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8957        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8958    )

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:
8961def values(
8962    values: t.Iterable[t.Tuple[t.Any, ...]],
8963    alias: t.Optional[str] = None,
8964    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8965) -> Values:
8966    """Build VALUES statement.
8967
8968    Example:
8969        >>> values([(1, '2')]).sql()
8970        "VALUES (1, '2')"
8971
8972    Args:
8973        values: values statements that will be converted to SQL
8974        alias: optional alias
8975        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8976         If either are provided then an alias is also required.
8977
8978    Returns:
8979        Values: the Values expression object
8980    """
8981    if columns and not alias:
8982        raise ValueError("Alias is required when providing columns")
8983
8984    return Values(
8985        expressions=[convert(tup) for tup in values],
8986        alias=(
8987            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8988            if columns
8989            else (TableAlias(this=to_identifier(alias)) if alias else None)
8990        ),
8991    )

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:
8994def var(name: t.Optional[ExpOrStr]) -> Var:
8995    """Build a SQL variable.
8996
8997    Example:
8998        >>> repr(var('x'))
8999        'Var(this=x)'
9000
9001        >>> repr(var(column('x', table='y')))
9002        'Var(this=x)'
9003
9004    Args:
9005        name: The name of the var or an expression who's name will become the var.
9006
9007    Returns:
9008        The new variable node.
9009    """
9010    if not name:
9011        raise ValueError("Cannot convert empty name into var.")
9012
9013    if isinstance(name, Expression):
9014        name = name.name
9015    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, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
9018def rename_table(
9019    old_name: str | Table,
9020    new_name: str | Table,
9021    dialect: DialectType = None,
9022) -> Alter:
9023    """Build ALTER TABLE... RENAME... expression
9024
9025    Args:
9026        old_name: The old name of the table
9027        new_name: The new name of the table
9028        dialect: The dialect to parse the table.
9029
9030    Returns:
9031        Alter table expression
9032    """
9033    old_table = to_table(old_name, dialect=dialect)
9034    new_table = to_table(new_name, dialect=dialect)
9035    return Alter(
9036        this=old_table,
9037        kind="TABLE",
9038        actions=[
9039            AlterRename(this=new_table),
9040        ],
9041    )

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, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
9044def rename_column(
9045    table_name: str | Table,
9046    old_column_name: str | Column,
9047    new_column_name: str | Column,
9048    exists: t.Optional[bool] = None,
9049    dialect: DialectType = None,
9050) -> Alter:
9051    """Build ALTER TABLE... RENAME COLUMN... expression
9052
9053    Args:
9054        table_name: Name of the table
9055        old_column: The old name of the column
9056        new_column: The new name of the column
9057        exists: Whether to add the `IF EXISTS` clause
9058        dialect: The dialect to parse the table/column.
9059
9060    Returns:
9061        Alter table expression
9062    """
9063    table = to_table(table_name, dialect=dialect)
9064    old_column = to_column(old_column_name, dialect=dialect)
9065    new_column = to_column(new_column_name, dialect=dialect)
9066    return Alter(
9067        this=table,
9068        kind="TABLE",
9069        actions=[
9070            RenameColumn(this=old_column, to=new_column, exists=exists),
9071        ],
9072    )

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:
9075def convert(value: t.Any, copy: bool = False) -> Expression:
9076    """Convert a python value into an expression object.
9077
9078    Raises an error if a conversion is not possible.
9079
9080    Args:
9081        value: A python object.
9082        copy: Whether to copy `value` (only applies to Expressions and collections).
9083
9084    Returns:
9085        The equivalent expression object.
9086    """
9087    if isinstance(value, Expression):
9088        return maybe_copy(value, copy)
9089    if isinstance(value, str):
9090        return Literal.string(value)
9091    if isinstance(value, bool):
9092        return Boolean(this=value)
9093    if value is None or (isinstance(value, float) and math.isnan(value)):
9094        return null()
9095    if isinstance(value, numbers.Number):
9096        return Literal.number(value)
9097    if isinstance(value, bytes):
9098        return HexString(this=value.hex())
9099    if isinstance(value, datetime.datetime):
9100        datetime_literal = Literal.string(value.isoformat(sep=" "))
9101
9102        tz = None
9103        if value.tzinfo:
9104            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
9105            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
9106            tz = Literal.string(str(value.tzinfo))
9107
9108        return TimeStrToTime(this=datetime_literal, zone=tz)
9109    if isinstance(value, datetime.date):
9110        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
9111        return DateStrToDate(this=date_literal)
9112    if isinstance(value, datetime.time):
9113        time_literal = Literal.string(value.isoformat())
9114        return TsOrDsToTime(this=time_literal)
9115    if isinstance(value, tuple):
9116        if hasattr(value, "_fields"):
9117            return Struct(
9118                expressions=[
9119                    PropertyEQ(
9120                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
9121                    )
9122                    for k in value._fields
9123                ]
9124            )
9125        return Tuple(expressions=[convert(v, copy=copy) for v in value])
9126    if isinstance(value, list):
9127        return Array(expressions=[convert(v, copy=copy) for v in value])
9128    if isinstance(value, dict):
9129        return Map(
9130            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
9131            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
9132        )
9133    if hasattr(value, "__dict__"):
9134        return Struct(
9135            expressions=[
9136                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
9137                for k, v in value.__dict__.items()
9138            ]
9139        )
9140    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:
9143def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
9144    """
9145    Replace children of an expression with the result of a lambda fun(child) -> exp.
9146    """
9147    for k, v in tuple(expression.args.items()):
9148        is_list_arg = type(v) is list
9149
9150        child_nodes = v if is_list_arg else [v]
9151        new_child_nodes = []
9152
9153        for cn in child_nodes:
9154            if isinstance(cn, Expression):
9155                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
9156                    new_child_nodes.append(child_node)
9157            else:
9158                new_child_nodes.append(cn)
9159
9160        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:
9163def replace_tree(
9164    expression: Expression,
9165    fun: t.Callable,
9166    prune: t.Optional[t.Callable[[Expression], bool]] = None,
9167) -> Expression:
9168    """
9169    Replace an entire tree with the result of function calls on each node.
9170
9171    This will be traversed in reverse dfs, so leaves first.
9172    If new nodes are created as a result of function calls, they will also be traversed.
9173    """
9174    stack = list(expression.dfs(prune=prune))
9175
9176    while stack:
9177        node = stack.pop()
9178        new_node = fun(node)
9179
9180        if new_node is not node:
9181            node.replace(new_node)
9182
9183            if isinstance(new_node, Expression):
9184                stack.append(new_node)
9185
9186    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]:
9189def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
9190    """
9191    Return all table names referenced through columns in an expression.
9192
9193    Example:
9194        >>> import sqlglot
9195        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
9196        ['a', 'c']
9197
9198    Args:
9199        expression: expression to find table names.
9200        exclude: a table name to exclude
9201
9202    Returns:
9203        A list of unique names.
9204    """
9205    return {
9206        table
9207        for table in (column.table for column in expression.find_all(Column))
9208        if table and table != exclude
9209    }

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, Type[sqlglot.dialects.Dialect], NoneType] = None, identify: bool = False) -> str:
9212def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
9213    """Get the full name of a table as a string.
9214
9215    Args:
9216        table: Table expression node or string.
9217        dialect: The dialect to generate the table name for.
9218        identify: Determines when an identifier should be quoted. Possible values are:
9219            False (default): Never quote, except in cases where it's mandatory by the dialect.
9220            True: Always quote.
9221
9222    Examples:
9223        >>> from sqlglot import exp, parse_one
9224        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
9225        'a.b.c'
9226
9227    Returns:
9228        The table name.
9229    """
9230
9231    table = maybe_parse(table, into=Table, dialect=dialect)
9232
9233    if not table:
9234        raise ValueError(f"Cannot parse {table}")
9235
9236    return ".".join(
9237        (
9238            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
9239            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
9240            else part.name
9241        )
9242        for part in table.parts
9243    )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> str:
9246def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
9247    """Returns a case normalized table name without quotes.
9248
9249    Args:
9250        table: the table to normalize
9251        dialect: the dialect to use for normalization rules
9252        copy: whether to copy the expression.
9253
9254    Examples:
9255        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
9256        'A-B.c'
9257    """
9258    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
9259
9260    return ".".join(
9261        p.name
9262        for p in normalize_identifiers(
9263            to_table(table, dialect=dialect, copy=copy), dialect=dialect
9264        ).parts
9265    )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> ~E:
9268def replace_tables(
9269    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
9270) -> E:
9271    """Replace all tables in expression according to the mapping.
9272
9273    Args:
9274        expression: expression node to be transformed and replaced.
9275        mapping: mapping of table names.
9276        dialect: the dialect of the mapping table
9277        copy: whether to copy the expression.
9278
9279    Examples:
9280        >>> from sqlglot import exp, parse_one
9281        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
9282        'SELECT * FROM c /* a.b */'
9283
9284    Returns:
9285        The mapped expression.
9286    """
9287
9288    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
9289
9290    def _replace_tables(node: Expression) -> Expression:
9291        if isinstance(node, Table) and node.meta.get("replace") is not False:
9292            original = normalize_table_name(node, dialect=dialect)
9293            new_name = mapping.get(original)
9294
9295            if new_name:
9296                table = to_table(
9297                    new_name,
9298                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
9299                    dialect=dialect,
9300                )
9301                table.add_comments([original])
9302                return table
9303        return node
9304
9305    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:
9308def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
9309    """Replace placeholders in an expression.
9310
9311    Args:
9312        expression: expression node to be transformed and replaced.
9313        args: positional names that will substitute unnamed placeholders in the given order.
9314        kwargs: keyword arguments that will substitute named placeholders.
9315
9316    Examples:
9317        >>> from sqlglot import exp, parse_one
9318        >>> replace_placeholders(
9319        ...     parse_one("select * from :tbl where ? = ?"),
9320        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
9321        ... ).sql()
9322        "SELECT * FROM foo WHERE str_col = 'b'"
9323
9324    Returns:
9325        The mapped expression.
9326    """
9327
9328    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
9329        if isinstance(node, Placeholder):
9330            if node.this:
9331                new_name = kwargs.get(node.this)
9332                if new_name is not None:
9333                    return convert(new_name)
9334            else:
9335                try:
9336                    return convert(next(args))
9337                except StopIteration:
9338                    pass
9339        return node
9340
9341    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, Union[Query, Callable[[], Query]]], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Expression:
9344def expand(
9345    expression: Expression,
9346    sources: t.Dict[str, Query | t.Callable[[], Query]],
9347    dialect: DialectType = None,
9348    copy: bool = True,
9349) -> Expression:
9350    """Transforms an expression by expanding all referenced sources into subqueries.
9351
9352    Examples:
9353        >>> from sqlglot import parse_one
9354        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
9355        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
9356
9357        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
9358        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
9359
9360    Args:
9361        expression: The expression to expand.
9362        sources: A dict of name to query or a callable that provides a query on demand.
9363        dialect: The dialect of the sources dict or the callable.
9364        copy: Whether to copy the expression during transformation. Defaults to True.
9365
9366    Returns:
9367        The transformed expression.
9368    """
9369    normalized_sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
9370
9371    def _expand(node: Expression):
9372        if isinstance(node, Table):
9373            name = normalize_table_name(node, dialect=dialect)
9374            source = normalized_sources.get(name)
9375
9376            if source:
9377                # Create a subquery with the same alias (or table name if no alias)
9378                parsed_source = source() if callable(source) else source
9379                subquery = parsed_source.subquery(node.alias or name)
9380                subquery.comments = [f"source: {name}"]
9381
9382                # Continue expanding within the subquery
9383                return subquery.transform(_expand, copy=False)
9384
9385        return node
9386
9387    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 dict of name to query or a callable that provides a query on demand.
  • dialect: The dialect of the sources dict or the callable.
  • 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, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Func:
9390def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
9391    """
9392    Returns a Func expression.
9393
9394    Examples:
9395        >>> func("abs", 5).sql()
9396        'ABS(5)'
9397
9398        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
9399        'CAST(5 AS DOUBLE)'
9400
9401    Args:
9402        name: the name of the function to build.
9403        args: the args used to instantiate the function of interest.
9404        copy: whether to copy the argument expressions.
9405        dialect: the source dialect.
9406        kwargs: the kwargs used to instantiate the function of interest.
9407
9408    Note:
9409        The arguments `args` and `kwargs` are mutually exclusive.
9410
9411    Returns:
9412        An instance of the function of interest, or an anonymous function, if `name` doesn't
9413        correspond to an existing `sqlglot.expressions.Func` class.
9414    """
9415    if args and kwargs:
9416        raise ValueError("Can't use both args and kwargs to instantiate a function.")
9417
9418    from sqlglot.dialects.dialect import Dialect
9419
9420    dialect = Dialect.get_or_raise(dialect)
9421
9422    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
9423    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
9424
9425    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
9426    if constructor:
9427        if converted:
9428            if "dialect" in constructor.__code__.co_varnames:
9429                function = constructor(converted, dialect=dialect)
9430            else:
9431                function = constructor(converted)
9432        elif constructor.__name__ == "from_arg_list":
9433            function = constructor.__self__(**kwargs)  # type: ignore
9434        else:
9435            constructor = FUNCTION_BY_NAME.get(name.upper())
9436            if constructor:
9437                function = constructor(**kwargs)
9438            else:
9439                raise ValueError(
9440                    f"Unable to convert '{name}' into a Func. Either manually construct "
9441                    "the Func expression of interest or parse the function call."
9442                )
9443    else:
9444        kwargs = kwargs or {"expressions": converted}
9445        function = Anonymous(this=name, **kwargs)
9446
9447    for error_message in function.error_messages(converted):
9448        raise ValueError(error_message)
9449
9450    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:
9453def case(
9454    expression: t.Optional[ExpOrStr] = None,
9455    **opts,
9456) -> Case:
9457    """
9458    Initialize a CASE statement.
9459
9460    Example:
9461        case().when("a = 1", "foo").else_("bar")
9462
9463    Args:
9464        expression: Optionally, the input expression (not all dialects support this)
9465        **opts: Extra keyword arguments for parsing `expression`
9466    """
9467    if expression is not None:
9468        this = maybe_parse(expression, **opts)
9469    else:
9470        this = None
9471    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, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Array:
9474def array(
9475    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
9476) -> Array:
9477    """
9478    Returns an array.
9479
9480    Examples:
9481        >>> array(1, 'x').sql()
9482        'ARRAY(1, x)'
9483
9484    Args:
9485        expressions: the expressions to add to the array.
9486        copy: whether to copy the argument expressions.
9487        dialect: the source dialect.
9488        kwargs: the kwargs used to instantiate the function of interest.
9489
9490    Returns:
9491        An array expression.
9492    """
9493    return Array(
9494        expressions=[
9495            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9496            for expression in expressions
9497        ]
9498    )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Tuple:
9501def tuple_(
9502    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
9503) -> Tuple:
9504    """
9505    Returns an tuple.
9506
9507    Examples:
9508        >>> tuple_(1, 'x').sql()
9509        '(1, x)'
9510
9511    Args:
9512        expressions: the expressions to add to the tuple.
9513        copy: whether to copy the argument expressions.
9514        dialect: the source dialect.
9515        kwargs: the kwargs used to instantiate the function of interest.
9516
9517    Returns:
9518        A tuple expression.
9519    """
9520    return Tuple(
9521        expressions=[
9522            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
9523            for expression in expressions
9524        ]
9525    )

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:
9528def true() -> Boolean:
9529    """
9530    Returns a true Boolean expression.
9531    """
9532    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
9535def false() -> Boolean:
9536    """
9537    Returns a false Boolean expression.
9538    """
9539    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
9542def null() -> Null:
9543    """
9544    Returns a Null expression.
9545    """
9546    return Null()

Returns a Null expression.

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