Edit on GitHub

Expressions

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

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


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

Retrieves the argument with key "this".

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

Retrieves the argument with key "expression".

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

Retrieves the argument with key "expressions".

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

Checks whether a Literal expression is a string.

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

Checks whether a Literal expression is a number.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is an integer.

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

Checks whether an expression is a star.

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

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

alias_column_names: List[str]
212    @property
213    def alias_column_names(self) -> t.List[str]:
214        table_alias = self.args.get("alias")
215        if not table_alias:
216            return []
217        return [c.name for c in table_alias.args.get("columns") or []]
name: str
219    @property
220    def name(self) -> str:
221        return self.text("this")
alias_or_name: str
223    @property
224    def alias_or_name(self) -> str:
225        return self.alias or self.name
output_name: str
227    @property
228    def output_name(self) -> str:
229        """
230        Name of the output column if this expression is a selection.
231
232        If the Expression has no output name, an empty string is returned.
233
234        Example:
235            >>> from sqlglot import parse_one
236            >>> parse_one("SELECT a").expressions[0].output_name
237            'a'
238            >>> parse_one("SELECT b AS c").expressions[0].output_name
239            'c'
240            >>> parse_one("SELECT 1 + 2").expressions[0].output_name
241            ''
242        """
243        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]
245    @property
246    def type(self) -> t.Optional[DataType]:
247        return self._type
def is_type(self, *dtypes) -> bool:
255    def is_type(self, *dtypes) -> bool:
256        return self.type is not None and self.type.is_type(*dtypes)
def is_leaf(self) -> bool:
258    def is_leaf(self) -> bool:
259        return not any(isinstance(v, (Expression, list)) for v in self.args.values())
meta: Dict[str, Any]
261    @property
262    def meta(self) -> t.Dict[str, t.Any]:
263        if self._meta is None:
264            self._meta = {}
265        return self._meta
def copy(self) -> typing_extensions.Self:
301    def copy(self) -> Self:
302        """
303        Returns a deep copy of the expression.
304        """
305        return deepcopy(self)

Returns a deep copy of the expression.

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

Returns the depth of this tree.

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

Returns the parent select statement.

same_parent: bool
476    @property
477    def same_parent(self) -> bool:
478        """Returns if the parent is the same class as itself."""
479        return type(self.parent) is self.__class__

Returns if the parent is the same class as itself.

def root(self) -> Expression:
481    def root(self) -> Expression:
482        """
483        Returns the root expression of this tree.
484        """
485        expression = self
486        while expression.parent:
487            expression = expression.parent
488        return expression

Returns the root expression of this tree.

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

Returns the first non parenthesis child or self.

def unalias(self):
565    def unalias(self):
566        """
567        Returns the inner expression if this is an Alias.
568        """
569        if isinstance(self, Alias):
570            return self.this
571        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
573    def unnest_operands(self):
574        """
575        Returns unnested operands as a tuple.
576        """
577        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
579    def flatten(self, unnest=True):
580        """
581        Returns a generator which yields child nodes whose parents are the same class.
582
583        A AND B AND C -> [A, B, C]
584        """
585        for node in self.dfs(prune=lambda n: n.parent and type(n) is not self.__class__):
586            if type(node) is not self.__class__:
587                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:
595    def to_s(self) -> str:
596        """
597        Same as __repr__, but includes additional information which can be useful
598        for debugging, like empty or missing args and the AST nodes' object IDs.
599        """
600        return _to_s(self, verbose=True)

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

def sql( self, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> str:
602    def sql(self, dialect: DialectType = None, **opts) -> str:
603        """
604        Returns SQL string representation of this tree.
605
606        Args:
607            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
608            opts: other `sqlglot.generator.Generator` options.
609
610        Returns:
611            The SQL string.
612        """
613        from sqlglot.dialects import Dialect
614
615        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:
617    def transform(self, fun: t.Callable, *args: t.Any, copy: bool = True, **kwargs) -> Expression:
618        """
619        Visits all tree nodes (excluding already transformed ones)
620        and applies the given transformation function to each node.
621
622        Args:
623            fun: a function which takes a node as an argument and returns a
624                new transformed node or the same node without modifications. If the function
625                returns None, then the corresponding node will be removed from the syntax tree.
626            copy: if set to True a new tree instance is constructed, otherwise the tree is
627                modified in place.
628
629        Returns:
630            The transformed tree.
631        """
632        root = None
633        new_node = None
634
635        for node in (self.copy() if copy else self).dfs(prune=lambda n: n is not new_node):
636            parent, arg_key, index = node.parent, node.arg_key, node.index
637            new_node = fun(node, *args, **kwargs)
638
639            if not root:
640                root = new_node
641            elif new_node is not node:
642                parent.set(arg_key, new_node, index)
643
644        assert root
645        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):
653    def replace(self, expression):
654        """
655        Swap out this expression with a new expression.
656
657        For example::
658
659            >>> tree = Select().select("x").from_("tbl")
660            >>> tree.find(Column).replace(column("y"))
661            Column(
662              this=Identifier(this=y, quoted=False))
663            >>> tree.sql()
664            'SELECT y FROM tbl'
665
666        Args:
667            expression: new node
668
669        Returns:
670            The new expression or expressions.
671        """
672        parent = self.parent
673
674        if not parent or parent is expression:
675            return expression
676
677        key = self.arg_key
678        value = parent.args.get(key)
679
680        if type(expression) is list and isinstance(value, Expression):
681            # We are trying to replace an Expression with a list, so it's assumed that
682            # the intention was to really replace the parent of this expression.
683            value.parent.replace(expression)
684        else:
685            parent.set(key, expression, self.index)
686
687        if expression is not self:
688            self.parent = None
689            self.arg_key = None
690            self.index = None
691
692        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:
694    def pop(self: E) -> E:
695        """
696        Remove this expression from its AST.
697
698        Returns:
699            The popped expression.
700        """
701        self.replace(None)
702        return self

Remove this expression from its AST.

Returns:

The popped expression.

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

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
764    @classmethod
765    def load(cls, obj):
766        """
767        Load a dict (as returned by `Expression.dump`) into an Expression instance.
768        """
769        from sqlglot.serde import load
770
771        return load(obj)

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

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

Wrap this condition with NOT.

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

The new Not instance.

def as_( self, alias: str | Identifier, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Alias:
849    def as_(
850        self,
851        alias: str | Identifier,
852        quoted: t.Optional[bool] = None,
853        dialect: DialectType = None,
854        copy: bool = True,
855        **opts,
856    ) -> Alias:
857        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:
882    def isin(
883        self,
884        *expressions: t.Any,
885        query: t.Optional[ExpOrStr] = None,
886        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
887        copy: bool = True,
888        **opts,
889    ) -> In:
890        subquery = maybe_parse(query, copy=copy, **opts) if query else None
891        if subquery and not isinstance(subquery, Subquery):
892            subquery = subquery.subquery(copy=False)
893
894        return In(
895            this=maybe_copy(self, copy),
896            expressions=[convert(e, copy=copy) for e in expressions],
897            query=subquery,
898            unnest=(
899                Unnest(
900                    expressions=[
901                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
902                        for e in ensure_list(unnest)
903                    ]
904                )
905                if unnest
906                else None
907            ),
908        )
def between( self, low: Any, high: Any, copy: bool = True, **opts) -> Between:
910    def between(self, low: t.Any, high: t.Any, copy: bool = True, **opts) -> Between:
911        return Between(
912            this=maybe_copy(self, copy),
913            low=convert(low, copy=copy, **opts),
914            high=convert(high, copy=copy, **opts),
915        )
def is_( self, other: Union[str, Expression]) -> Is:
917    def is_(self, other: ExpOrStr) -> Is:
918        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
920    def like(self, other: ExpOrStr) -> Like:
921        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
923    def ilike(self, other: ExpOrStr) -> ILike:
924        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
926    def eq(self, other: t.Any) -> EQ:
927        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
929    def neq(self, other: t.Any) -> NEQ:
930        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
932    def rlike(self, other: ExpOrStr) -> RegexpLike:
933        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
935    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
936        div = self._binop(Div, other)
937        div.args["typed"] = typed
938        div.args["safe"] = safe
939        return div
def asc(self, nulls_first: bool = True) -> Ordered:
941    def asc(self, nulls_first: bool = True) -> Ordered:
942        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
944    def desc(self, nulls_first: bool = False) -> Ordered:
945        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):
1028class Condition(Expression):
1029    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

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

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

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

Returns a Subquery that wraps around this query.

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

Adds a LIMIT clause to this query.

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

A limited Select expression.

def offset( self: ~Q, expression: Union[str, Expression, int], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1100    def offset(
1101        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
1102    ) -> Q:
1103        """
1104        Set the OFFSET expression.
1105
1106        Example:
1107            >>> Select().from_("tbl").select("x").offset(10).sql()
1108            'SELECT x FROM tbl OFFSET 10'
1109
1110        Args:
1111            expression: the SQL code string to parse.
1112                This can also be an integer.
1113                If a `Offset` instance is passed, this is used as-is.
1114                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
1115            dialect: the dialect used to parse the input expression.
1116            copy: if `False`, modify this expression instance in-place.
1117            opts: other options to use to parse the input expressions.
1118
1119        Returns:
1120            The modified Select expression.
1121        """
1122        return _apply_builder(
1123            expression=expression,
1124            instance=self,
1125            arg="offset",
1126            into=Offset,
1127            prefix="OFFSET",
1128            dialect=dialect,
1129            copy=copy,
1130            into_arg="expression",
1131            **opts,
1132        )

Set the OFFSET expression.

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

The modified Select expression.

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

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

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

selects: List[Expression]
1180    @property
1181    def selects(self) -> t.List[Expression]:
1182        """Returns the query's projections."""
1183        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

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

Returns the output names of the query's projections.

def select( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
1190    def select(
1191        self: Q,
1192        *expressions: t.Optional[ExpOrStr],
1193        append: bool = True,
1194        dialect: DialectType = None,
1195        copy: bool = True,
1196        **opts,
1197    ) -> Q:
1198        """
1199        Append to or set the SELECT expressions.
1200
1201        Example:
1202            >>> Select().select("x", "y").sql()
1203            'SELECT x, y'
1204
1205        Args:
1206            *expressions: the SQL code strings to parse.
1207                If an `Expression` instance is passed, it will be used as-is.
1208            append: if `True`, add to any existing expressions.
1209                Otherwise, this resets the expressions.
1210            dialect: the dialect used to parse the input expressions.
1211            copy: if `False`, modify this expression instance in-place.
1212            opts: other options to use to parse the input expressions.
1213
1214        Returns:
1215            The modified Query expression.
1216        """
1217        raise NotImplementedError("Query objects must implement `select`")

Append to or set the SELECT expressions.

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

The modified Query expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, scalar: bool = False, **opts) -> ~Q:
1219    def with_(
1220        self: Q,
1221        alias: ExpOrStr,
1222        as_: ExpOrStr,
1223        recursive: t.Optional[bool] = None,
1224        materialized: t.Optional[bool] = None,
1225        append: bool = True,
1226        dialect: DialectType = None,
1227        copy: bool = True,
1228        scalar: bool = False,
1229        **opts,
1230    ) -> Q:
1231        """
1232        Append to or set the common table expressions.
1233
1234        Example:
1235            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
1236            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
1237
1238        Args:
1239            alias: the SQL code string to parse as the table name.
1240                If an `Expression` instance is passed, this is used as-is.
1241            as_: the SQL code string to parse as the table expression.
1242                If an `Expression` instance is passed, it will be used as-is.
1243            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1244            materialized: set the MATERIALIZED part of the expression.
1245            append: if `True`, add to any existing expressions.
1246                Otherwise, this resets the expressions.
1247            dialect: the dialect used to parse the input expression.
1248            copy: if `False`, modify this expression instance in-place.
1249            scalar: if `True`, this is a scalar common table expression.
1250            opts: other options to use to parse the input expressions.
1251
1252        Returns:
1253            The modified expression.
1254        """
1255        return _apply_cte_builder(
1256            self,
1257            alias,
1258            as_,
1259            recursive=recursive,
1260            materialized=materialized,
1261            append=append,
1262            dialect=dialect,
1263            copy=copy,
1264            scalar=scalar,
1265            **opts,
1266        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Union:
1268    def union(
1269        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1270    ) -> Union:
1271        """
1272        Builds a UNION expression.
1273
1274        Example:
1275            >>> import sqlglot
1276            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
1277            'SELECT * FROM foo UNION SELECT * FROM bla'
1278
1279        Args:
1280            expressions: the SQL code strings.
1281                If `Expression` instances are passed, they will be used as-is.
1282            distinct: set the DISTINCT flag if and only if this is true.
1283            dialect: the dialect used to parse the input expression.
1284            opts: other options to use to parse the input expressions.
1285
1286        Returns:
1287            The new Union expression.
1288        """
1289        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Intersect:
1291    def intersect(
1292        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1293    ) -> Intersect:
1294        """
1295        Builds an INTERSECT expression.
1296
1297        Example:
1298            >>> import sqlglot
1299            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
1300            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
1301
1302        Args:
1303            expressions: the SQL code strings.
1304                If `Expression` instances are passed, they will be used as-is.
1305            distinct: set the DISTINCT flag if and only if this is true.
1306            dialect: the dialect used to parse the input expression.
1307            opts: other options to use to parse the input expressions.
1308
1309        Returns:
1310            The new Intersect expression.
1311        """
1312        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Except:
1314    def except_(
1315        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
1316    ) -> Except:
1317        """
1318        Builds an EXCEPT expression.
1319
1320        Example:
1321            >>> import sqlglot
1322            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
1323            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
1324
1325        Args:
1326            expressions: the SQL code strings.
1327                If `Expression` instance are passed, they will be used as-is.
1328            distinct: set the DISTINCT flag if and only if this is true.
1329            dialect: the dialect used to parse the input expression.
1330            opts: other options to use to parse the input expressions.
1331
1332        Returns:
1333            The new Except expression.
1334        """
1335        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):
1338class UDTF(DerivedTable):
1339    @property
1340    def selects(self) -> t.List[Expression]:
1341        alias = self.args.get("alias")
1342        return alias.columns if alias else []
selects: List[Expression]
1339    @property
1340    def selects(self) -> t.List[Expression]:
1341        alias = self.args.get("alias")
1342        return alias.columns if alias else []
key = 'udtf'
class Cache(Expression):
1345class Cache(Expression):
1346    arg_types = {
1347        "this": True,
1348        "lazy": False,
1349        "options": False,
1350        "expression": False,
1351    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
class Uncache(Expression):
1354class Uncache(Expression):
1355    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
class Refresh(Expression):
1358class Refresh(Expression):
1359    pass
key = 'refresh'
class DDL(Expression):
1362class DDL(Expression):
1363    @property
1364    def ctes(self) -> t.List[CTE]:
1365        """Returns a list of all the CTEs attached to this statement."""
1366        with_ = self.args.get("with")
1367        return with_.expressions if with_ else []
1368
1369    @property
1370    def selects(self) -> t.List[Expression]:
1371        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1372        return self.expression.selects if isinstance(self.expression, Query) else []
1373
1374    @property
1375    def named_selects(self) -> t.List[str]:
1376        """
1377        If this statement contains a query (e.g. a CTAS), this returns the output
1378        names of the query's projections.
1379        """
1380        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
1363    @property
1364    def ctes(self) -> t.List[CTE]:
1365        """Returns a list of all the CTEs attached to this statement."""
1366        with_ = self.args.get("with")
1367        return with_.expressions if with_ else []

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

selects: List[Expression]
1369    @property
1370    def selects(self) -> t.List[Expression]:
1371        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
1372        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]
1374    @property
1375    def named_selects(self) -> t.List[str]:
1376        """
1377        If this statement contains a query (e.g. a CTAS), this returns the output
1378        names of the query's projections.
1379        """
1380        return self.expression.named_selects if isinstance(self.expression, Query) else []

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

key = 'ddl'
class DML(Expression):
1383class DML(Expression):
1384    def returning(
1385        self,
1386        expression: ExpOrStr,
1387        dialect: DialectType = None,
1388        copy: bool = True,
1389        **opts,
1390    ) -> "Self":
1391        """
1392        Set the RETURNING expression. Not supported by all dialects.
1393
1394        Example:
1395            >>> delete("tbl").returning("*", dialect="postgres").sql()
1396            'DELETE FROM tbl RETURNING *'
1397
1398        Args:
1399            expression: the SQL code strings to parse.
1400                If an `Expression` instance is passed, it will be used as-is.
1401            dialect: the dialect used to parse the input expressions.
1402            copy: if `False`, modify this expression instance in-place.
1403            opts: other options to use to parse the input expressions.
1404
1405        Returns:
1406            Delete: the modified expression.
1407        """
1408        return _apply_builder(
1409            expression=expression,
1410            instance=self,
1411            arg="returning",
1412            prefix="RETURNING",
1413            dialect=dialect,
1414            copy=copy,
1415            into=Returning,
1416            **opts,
1417        )
def returning( self, expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> typing_extensions.Self:
1384    def returning(
1385        self,
1386        expression: ExpOrStr,
1387        dialect: DialectType = None,
1388        copy: bool = True,
1389        **opts,
1390    ) -> "Self":
1391        """
1392        Set the RETURNING expression. Not supported by all dialects.
1393
1394        Example:
1395            >>> delete("tbl").returning("*", dialect="postgres").sql()
1396            'DELETE FROM tbl RETURNING *'
1397
1398        Args:
1399            expression: the SQL code strings to parse.
1400                If an `Expression` instance is passed, it will be used as-is.
1401            dialect: the dialect used to parse the input expressions.
1402            copy: if `False`, modify this expression instance in-place.
1403            opts: other options to use to parse the input expressions.
1404
1405        Returns:
1406            Delete: the modified expression.
1407        """
1408        return _apply_builder(
1409            expression=expression,
1410            instance=self,
1411            arg="returning",
1412            prefix="RETURNING",
1413            dialect=dialect,
1414            copy=copy,
1415            into=Returning,
1416            **opts,
1417        )

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):
1420class Create(DDL):
1421    arg_types = {
1422        "with": False,
1423        "this": True,
1424        "kind": True,
1425        "expression": False,
1426        "exists": False,
1427        "properties": False,
1428        "replace": False,
1429        "refresh": False,
1430        "unique": False,
1431        "indexes": False,
1432        "no_schema_binding": False,
1433        "begin": False,
1434        "end": False,
1435        "clone": False,
1436        "concurrently": False,
1437        "clustered": False,
1438    }
1439
1440    @property
1441    def kind(self) -> t.Optional[str]:
1442        kind = self.args.get("kind")
1443        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]
1440    @property
1441    def kind(self) -> t.Optional[str]:
1442        kind = self.args.get("kind")
1443        return kind and kind.upper()
key = 'create'
class SequenceProperties(Expression):
1446class SequenceProperties(Expression):
1447    arg_types = {
1448        "increment": False,
1449        "minvalue": False,
1450        "maxvalue": False,
1451        "cache": False,
1452        "start": False,
1453        "owned": False,
1454        "options": False,
1455    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
class TruncateTable(Expression):
1458class TruncateTable(Expression):
1459    arg_types = {
1460        "expressions": True,
1461        "is_database": False,
1462        "exists": False,
1463        "only": False,
1464        "cluster": False,
1465        "identity": False,
1466        "option": False,
1467        "partition": False,
1468    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
class Clone(Expression):
1474class Clone(Expression):
1475    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
class Describe(Expression):
1478class Describe(Expression):
1479    arg_types = {
1480        "this": True,
1481        "style": False,
1482        "kind": False,
1483        "expressions": False,
1484        "partition": False,
1485        "format": False,
1486    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False}
key = 'describe'
class Attach(Expression):
1490class Attach(Expression):
1491    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
class Detach(Expression):
1495class Detach(Expression):
1496    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
class Summarize(Expression):
1500class Summarize(Expression):
1501    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
class Kill(Expression):
1504class Kill(Expression):
1505    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
class Pragma(Expression):
1508class Pragma(Expression):
1509    pass
key = 'pragma'
class Declare(Expression):
1512class Declare(Expression):
1513    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
class DeclareItem(Expression):
1516class DeclareItem(Expression):
1517    arg_types = {"this": True, "kind": True, "default": False}
arg_types = {'this': True, 'kind': True, 'default': False}
key = 'declareitem'
class Set(Expression):
1520class Set(Expression):
1521    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
class Heredoc(Expression):
1524class Heredoc(Expression):
1525    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
class SetItem(Expression):
1528class SetItem(Expression):
1529    arg_types = {
1530        "this": False,
1531        "expressions": False,
1532        "kind": False,
1533        "collate": False,  # MySQL SET NAMES statement
1534        "global": False,
1535    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global': False}
key = 'setitem'
class Show(Expression):
1538class Show(Expression):
1539    arg_types = {
1540        "this": True,
1541        "history": False,
1542        "terse": False,
1543        "target": False,
1544        "offset": False,
1545        "starts_with": False,
1546        "limit": False,
1547        "from": False,
1548        "like": False,
1549        "where": False,
1550        "db": False,
1551        "scope": False,
1552        "scope_kind": False,
1553        "full": False,
1554        "mutex": False,
1555        "query": False,
1556        "channel": False,
1557        "global": False,
1558        "log": False,
1559        "position": False,
1560        "types": False,
1561    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global': False, 'log': False, 'position': False, 'types': False}
key = 'show'
class UserDefinedFunction(Expression):
1564class UserDefinedFunction(Expression):
1565    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
class CharacterSet(Expression):
1568class CharacterSet(Expression):
1569    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
class With(Expression):
1572class With(Expression):
1573    arg_types = {"expressions": True, "recursive": False}
1574
1575    @property
1576    def recursive(self) -> bool:
1577        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False}
recursive: bool
1575    @property
1576    def recursive(self) -> bool:
1577        return bool(self.args.get("recursive"))
key = 'with'
class WithinGroup(Expression):
1580class WithinGroup(Expression):
1581    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
class CTE(DerivedTable):
1586class CTE(DerivedTable):
1587    arg_types = {
1588        "this": True,
1589        "alias": True,
1590        "scalar": False,
1591        "materialized": False,
1592    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False}
key = 'cte'
class ProjectionDef(Expression):
1595class ProjectionDef(Expression):
1596    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
class TableAlias(Expression):
1599class TableAlias(Expression):
1600    arg_types = {"this": False, "columns": False}
1601
1602    @property
1603    def columns(self):
1604        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1602    @property
1603    def columns(self):
1604        return self.args.get("columns") or []
key = 'tablealias'
class BitString(Condition):
1607class BitString(Condition):
1608    pass
key = 'bitstring'
class HexString(Condition):
1611class HexString(Condition):
1612    pass
key = 'hexstring'
class ByteString(Condition):
1615class ByteString(Condition):
1616    pass
key = 'bytestring'
class RawString(Condition):
1619class RawString(Condition):
1620    pass
key = 'rawstring'
class UnicodeString(Condition):
1623class UnicodeString(Condition):
1624    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
class Column(Condition):
1627class Column(Condition):
1628    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1629
1630    @property
1631    def table(self) -> str:
1632        return self.text("table")
1633
1634    @property
1635    def db(self) -> str:
1636        return self.text("db")
1637
1638    @property
1639    def catalog(self) -> str:
1640        return self.text("catalog")
1641
1642    @property
1643    def output_name(self) -> str:
1644        return self.name
1645
1646    @property
1647    def parts(self) -> t.List[Identifier]:
1648        """Return the parts of a column in order catalog, db, table, name."""
1649        return [
1650            t.cast(Identifier, self.args[part])
1651            for part in ("catalog", "db", "table", "this")
1652            if self.args.get(part)
1653        ]
1654
1655    def to_dot(self) -> Dot | Identifier:
1656        """Converts the column into a dot expression."""
1657        parts = self.parts
1658        parent = self.parent
1659
1660        while parent:
1661            if isinstance(parent, Dot):
1662                parts.append(parent.expression)
1663            parent = parent.parent
1664
1665        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
1630    @property
1631    def table(self) -> str:
1632        return self.text("table")
db: str
1634    @property
1635    def db(self) -> str:
1636        return self.text("db")
catalog: str
1638    @property
1639    def catalog(self) -> str:
1640        return self.text("catalog")
output_name: str
1642    @property
1643    def output_name(self) -> str:
1644        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]
1646    @property
1647    def parts(self) -> t.List[Identifier]:
1648        """Return the parts of a column in order catalog, db, table, name."""
1649        return [
1650            t.cast(Identifier, self.args[part])
1651            for part in ("catalog", "db", "table", "this")
1652            if self.args.get(part)
1653        ]

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

def to_dot(self) -> Dot | Identifier:
1655    def to_dot(self) -> Dot | Identifier:
1656        """Converts the column into a dot expression."""
1657        parts = self.parts
1658        parent = self.parent
1659
1660        while parent:
1661            if isinstance(parent, Dot):
1662                parts.append(parent.expression)
1663            parent = parent.parent
1664
1665        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1668class ColumnPosition(Expression):
1669    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1672class ColumnDef(Expression):
1673    arg_types = {
1674        "this": True,
1675        "kind": False,
1676        "constraints": False,
1677        "exists": False,
1678        "position": False,
1679    }
1680
1681    @property
1682    def constraints(self) -> t.List[ColumnConstraint]:
1683        return self.args.get("constraints") or []
1684
1685    @property
1686    def kind(self) -> t.Optional[DataType]:
1687        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False}
constraints: List[ColumnConstraint]
1681    @property
1682    def constraints(self) -> t.List[ColumnConstraint]:
1683        return self.args.get("constraints") or []
kind: Optional[DataType]
1685    @property
1686    def kind(self) -> t.Optional[DataType]:
1687        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1690class AlterColumn(Expression):
1691    arg_types = {
1692        "this": True,
1693        "dtype": False,
1694        "collate": False,
1695        "using": False,
1696        "default": False,
1697        "drop": False,
1698        "comment": False,
1699        "allow_null": False,
1700    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterDistStyle(Expression):
1704class AlterDistStyle(Expression):
1705    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1708class AlterSortKey(Expression):
1709    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1712class AlterSet(Expression):
1713    arg_types = {
1714        "expressions": False,
1715        "option": False,
1716        "tablespace": False,
1717        "access_method": False,
1718        "file_format": False,
1719        "copy_options": False,
1720        "tag": False,
1721        "location": False,
1722        "serde": False,
1723    }
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):
1726class RenameColumn(Expression):
1727    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1730class AlterRename(Expression):
1731    pass
key = 'alterrename'
class SwapTable(Expression):
1734class SwapTable(Expression):
1735    pass
key = 'swaptable'
class Comment(Expression):
1738class Comment(Expression):
1739    arg_types = {
1740        "this": True,
1741        "kind": True,
1742        "expression": True,
1743        "exists": False,
1744        "materialized": False,
1745    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1748class Comprehension(Expression):
1749    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):
1753class MergeTreeTTLAction(Expression):
1754    arg_types = {
1755        "this": True,
1756        "delete": False,
1757        "recompress": False,
1758        "to_disk": False,
1759        "to_volume": False,
1760    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1764class MergeTreeTTL(Expression):
1765    arg_types = {
1766        "expressions": True,
1767        "where": False,
1768        "group": False,
1769        "aggregates": False,
1770    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1774class IndexConstraintOption(Expression):
1775    arg_types = {
1776        "key_block_size": False,
1777        "using": False,
1778        "parser": False,
1779        "comment": False,
1780        "visible": False,
1781        "engine_attr": False,
1782        "secondary_engine_attr": False,
1783    }
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):
1786class ColumnConstraint(Expression):
1787    arg_types = {"this": False, "kind": True}
1788
1789    @property
1790    def kind(self) -> ColumnConstraintKind:
1791        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1789    @property
1790    def kind(self) -> ColumnConstraintKind:
1791        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1794class ColumnConstraintKind(Expression):
1795    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1798class AutoIncrementColumnConstraint(ColumnConstraintKind):
1799    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1802class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1803    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1806class CaseSpecificColumnConstraint(ColumnConstraintKind):
1807    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1810class CharacterSetColumnConstraint(ColumnConstraintKind):
1811    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1814class CheckColumnConstraint(ColumnConstraintKind):
1815    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1818class ClusteredColumnConstraint(ColumnConstraintKind):
1819    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1822class CollateColumnConstraint(ColumnConstraintKind):
1823    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1826class CommentColumnConstraint(ColumnConstraintKind):
1827    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1830class CompressColumnConstraint(ColumnConstraintKind):
1831    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1834class DateFormatColumnConstraint(ColumnConstraintKind):
1835    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1838class DefaultColumnConstraint(ColumnConstraintKind):
1839    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1842class EncodeColumnConstraint(ColumnConstraintKind):
1843    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1847class ExcludeColumnConstraint(ColumnConstraintKind):
1848    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1851class EphemeralColumnConstraint(ColumnConstraintKind):
1852    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1855class WithOperator(Expression):
1856    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1859class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1860    # this: True -> ALWAYS, this: False -> BY DEFAULT
1861    arg_types = {
1862        "this": False,
1863        "expression": False,
1864        "on_null": False,
1865        "start": False,
1866        "increment": False,
1867        "minvalue": False,
1868        "maxvalue": False,
1869        "cycle": False,
1870    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1873class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1874    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1879class IndexColumnConstraint(ColumnConstraintKind):
1880    arg_types = {
1881        "this": False,
1882        "expressions": False,
1883        "kind": False,
1884        "index_type": False,
1885        "options": False,
1886        "expression": False,  # Clickhouse
1887        "granularity": False,
1888    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1891class InlineLengthColumnConstraint(ColumnConstraintKind):
1892    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1895class NonClusteredColumnConstraint(ColumnConstraintKind):
1896    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1899class NotForReplicationColumnConstraint(ColumnConstraintKind):
1900    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1904class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1905    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1908class NotNullColumnConstraint(ColumnConstraintKind):
1909    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1913class OnUpdateColumnConstraint(ColumnConstraintKind):
1914    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1918class TransformColumnConstraint(ColumnConstraintKind):
1919    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1922class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1923    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1926class TitleColumnConstraint(ColumnConstraintKind):
1927    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1930class UniqueColumnConstraint(ColumnConstraintKind):
1931    arg_types = {"this": False, "index_type": False, "on_conflict": False, "nulls": False}
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False}
key = 'uniquecolumnconstraint'
class UppercaseColumnConstraint(ColumnConstraintKind):
1934class UppercaseColumnConstraint(ColumnConstraintKind):
1935    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
1939class WatermarkColumnConstraint(Expression):
1940    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1943class PathColumnConstraint(ColumnConstraintKind):
1944    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1948class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1949    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1954class ComputedColumnConstraint(ColumnConstraintKind):
1955    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1958class Constraint(Expression):
1959    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1962class Delete(DML):
1963    arg_types = {
1964        "with": False,
1965        "this": False,
1966        "using": False,
1967        "where": False,
1968        "returning": False,
1969        "limit": False,
1970        "tables": False,  # Multiple-Table Syntax (MySQL)
1971        "cluster": False,  # Clickhouse
1972    }
1973
1974    def delete(
1975        self,
1976        table: ExpOrStr,
1977        dialect: DialectType = None,
1978        copy: bool = True,
1979        **opts,
1980    ) -> Delete:
1981        """
1982        Create a DELETE expression or replace the table on an existing DELETE expression.
1983
1984        Example:
1985            >>> delete("tbl").sql()
1986            'DELETE FROM tbl'
1987
1988        Args:
1989            table: the table from which to delete.
1990            dialect: the dialect used to parse the input expression.
1991            copy: if `False`, modify this expression instance in-place.
1992            opts: other options to use to parse the input expressions.
1993
1994        Returns:
1995            Delete: the modified expression.
1996        """
1997        return _apply_builder(
1998            expression=table,
1999            instance=self,
2000            arg="this",
2001            dialect=dialect,
2002            into=Table,
2003            copy=copy,
2004            **opts,
2005        )
2006
2007    def where(
2008        self,
2009        *expressions: t.Optional[ExpOrStr],
2010        append: bool = True,
2011        dialect: DialectType = None,
2012        copy: bool = True,
2013        **opts,
2014    ) -> Delete:
2015        """
2016        Append to or set the WHERE expressions.
2017
2018        Example:
2019            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2020            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2021
2022        Args:
2023            *expressions: the SQL code strings to parse.
2024                If an `Expression` instance is passed, it will be used as-is.
2025                Multiple expressions are combined with an AND operator.
2026            append: if `True`, AND the new expressions to any existing expression.
2027                Otherwise, this resets the expression.
2028            dialect: the dialect used to parse the input expressions.
2029            copy: if `False`, modify this expression instance in-place.
2030            opts: other options to use to parse the input expressions.
2031
2032        Returns:
2033            Delete: the modified expression.
2034        """
2035        return _apply_conjunction_builder(
2036            *expressions,
2037            instance=self,
2038            arg="where",
2039            append=append,
2040            into=Where,
2041            dialect=dialect,
2042            copy=copy,
2043            **opts,
2044        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False, 'cluster': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1974    def delete(
1975        self,
1976        table: ExpOrStr,
1977        dialect: DialectType = None,
1978        copy: bool = True,
1979        **opts,
1980    ) -> Delete:
1981        """
1982        Create a DELETE expression or replace the table on an existing DELETE expression.
1983
1984        Example:
1985            >>> delete("tbl").sql()
1986            'DELETE FROM tbl'
1987
1988        Args:
1989            table: the table from which to delete.
1990            dialect: the dialect used to parse the input expression.
1991            copy: if `False`, modify this expression instance in-place.
1992            opts: other options to use to parse the input expressions.
1993
1994        Returns:
1995            Delete: the modified expression.
1996        """
1997        return _apply_builder(
1998            expression=table,
1999            instance=self,
2000            arg="this",
2001            dialect=dialect,
2002            into=Table,
2003            copy=copy,
2004            **opts,
2005        )

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

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

Delete: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
2007    def where(
2008        self,
2009        *expressions: t.Optional[ExpOrStr],
2010        append: bool = True,
2011        dialect: DialectType = None,
2012        copy: bool = True,
2013        **opts,
2014    ) -> Delete:
2015        """
2016        Append to or set the WHERE expressions.
2017
2018        Example:
2019            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2020            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2021
2022        Args:
2023            *expressions: the SQL code strings to parse.
2024                If an `Expression` instance is passed, it will be used as-is.
2025                Multiple expressions are combined with an AND operator.
2026            append: if `True`, AND the new expressions to any existing expression.
2027                Otherwise, this resets the expression.
2028            dialect: the dialect used to parse the input expressions.
2029            copy: if `False`, modify this expression instance in-place.
2030            opts: other options to use to parse the input expressions.
2031
2032        Returns:
2033            Delete: the modified expression.
2034        """
2035        return _apply_conjunction_builder(
2036            *expressions,
2037            instance=self,
2038            arg="where",
2039            append=append,
2040            into=Where,
2041            dialect=dialect,
2042            copy=copy,
2043            **opts,
2044        )

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):
2047class Drop(Expression):
2048    arg_types = {
2049        "this": False,
2050        "kind": False,
2051        "expressions": False,
2052        "exists": False,
2053        "temporary": False,
2054        "materialized": False,
2055        "cascade": False,
2056        "constraints": False,
2057        "purge": False,
2058        "cluster": False,
2059        "concurrently": False,
2060    }
2061
2062    @property
2063    def kind(self) -> t.Optional[str]:
2064        kind = self.args.get("kind")
2065        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]
2062    @property
2063    def kind(self) -> t.Optional[str]:
2064        kind = self.args.get("kind")
2065        return kind and kind.upper()
key = 'drop'
class Filter(Expression):
2068class Filter(Expression):
2069    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2072class Check(Expression):
2073    pass
key = 'check'
class Changes(Expression):
2076class Changes(Expression):
2077    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2081class Connect(Expression):
2082    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2085class CopyParameter(Expression):
2086    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2089class Copy(DML):
2090    arg_types = {
2091        "this": True,
2092        "kind": True,
2093        "files": True,
2094        "credentials": False,
2095        "format": False,
2096        "params": False,
2097    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2100class Credentials(Expression):
2101    arg_types = {
2102        "credentials": False,
2103        "encryption": False,
2104        "storage": False,
2105        "iam_role": False,
2106        "region": False,
2107    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2110class Prior(Expression):
2111    pass
key = 'prior'
class Directory(Expression):
2114class Directory(Expression):
2115    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2116    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2119class ForeignKey(Expression):
2120    arg_types = {
2121        "expressions": False,
2122        "reference": False,
2123        "delete": False,
2124        "update": False,
2125    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2128class ColumnPrefix(Expression):
2129    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2132class PrimaryKey(Expression):
2133    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2138class Into(Expression):
2139    arg_types = {
2140        "this": False,
2141        "temporary": False,
2142        "unlogged": False,
2143        "bulk_collect": False,
2144        "expressions": False,
2145    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2148class From(Expression):
2149    @property
2150    def name(self) -> str:
2151        return self.this.name
2152
2153    @property
2154    def alias_or_name(self) -> str:
2155        return self.this.alias_or_name
name: str
2149    @property
2150    def name(self) -> str:
2151        return self.this.name
alias_or_name: str
2153    @property
2154    def alias_or_name(self) -> str:
2155        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2158class Having(Expression):
2159    pass
key = 'having'
class Hint(Expression):
2162class Hint(Expression):
2163    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2166class JoinHint(Expression):
2167    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2170class Identifier(Expression):
2171    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2172
2173    @property
2174    def quoted(self) -> bool:
2175        return bool(self.args.get("quoted"))
2176
2177    @property
2178    def hashable_args(self) -> t.Any:
2179        return (self.this, self.quoted)
2180
2181    @property
2182    def output_name(self) -> str:
2183        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2173    @property
2174    def quoted(self) -> bool:
2175        return bool(self.args.get("quoted"))
hashable_args: Any
2177    @property
2178    def hashable_args(self) -> t.Any:
2179        return (self.this, self.quoted)
output_name: str
2181    @property
2182    def output_name(self) -> str:
2183        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):
2187class Opclass(Expression):
2188    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2191class Index(Expression):
2192    arg_types = {
2193        "this": False,
2194        "table": False,
2195        "unique": False,
2196        "primary": False,
2197        "amp": False,  # teradata
2198        "params": False,
2199    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2202class IndexParameters(Expression):
2203    arg_types = {
2204        "using": False,
2205        "include": False,
2206        "columns": False,
2207        "with_storage": False,
2208        "partition_by": False,
2209        "tablespace": False,
2210        "where": False,
2211        "on": False,
2212    }
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):
2215class Insert(DDL, DML):
2216    arg_types = {
2217        "hint": False,
2218        "with": False,
2219        "is_function": False,
2220        "this": False,
2221        "expression": False,
2222        "conflict": False,
2223        "returning": False,
2224        "overwrite": False,
2225        "exists": False,
2226        "alternative": False,
2227        "where": False,
2228        "ignore": False,
2229        "by_name": False,
2230        "stored": False,
2231        "partition": False,
2232        "settings": False,
2233        "source": False,
2234    }
2235
2236    def with_(
2237        self,
2238        alias: ExpOrStr,
2239        as_: ExpOrStr,
2240        recursive: t.Optional[bool] = None,
2241        materialized: t.Optional[bool] = None,
2242        append: bool = True,
2243        dialect: DialectType = None,
2244        copy: bool = True,
2245        **opts,
2246    ) -> Insert:
2247        """
2248        Append to or set the common table expressions.
2249
2250        Example:
2251            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2252            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2253
2254        Args:
2255            alias: the SQL code string to parse as the table name.
2256                If an `Expression` instance is passed, this is used as-is.
2257            as_: the SQL code string to parse as the table expression.
2258                If an `Expression` instance is passed, it will be used as-is.
2259            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2260            materialized: set the MATERIALIZED part of the expression.
2261            append: if `True`, add to any existing expressions.
2262                Otherwise, this resets the expressions.
2263            dialect: the dialect used to parse the input expression.
2264            copy: if `False`, modify this expression instance in-place.
2265            opts: other options to use to parse the input expressions.
2266
2267        Returns:
2268            The modified expression.
2269        """
2270        return _apply_cte_builder(
2271            self,
2272            alias,
2273            as_,
2274            recursive=recursive,
2275            materialized=materialized,
2276            append=append,
2277            dialect=dialect,
2278            copy=copy,
2279            **opts,
2280        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False, 'partition': False, 'settings': False, 'source': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2236    def with_(
2237        self,
2238        alias: ExpOrStr,
2239        as_: ExpOrStr,
2240        recursive: t.Optional[bool] = None,
2241        materialized: t.Optional[bool] = None,
2242        append: bool = True,
2243        dialect: DialectType = None,
2244        copy: bool = True,
2245        **opts,
2246    ) -> Insert:
2247        """
2248        Append to or set the common table expressions.
2249
2250        Example:
2251            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2252            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2253
2254        Args:
2255            alias: the SQL code string to parse as the table name.
2256                If an `Expression` instance is passed, this is used as-is.
2257            as_: the SQL code string to parse as the table expression.
2258                If an `Expression` instance is passed, it will be used as-is.
2259            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2260            materialized: set the MATERIALIZED part of the expression.
2261            append: if `True`, add to any existing expressions.
2262                Otherwise, this resets the expressions.
2263            dialect: the dialect used to parse the input expression.
2264            copy: if `False`, modify this expression instance in-place.
2265            opts: other options to use to parse the input expressions.
2266
2267        Returns:
2268            The modified expression.
2269        """
2270        return _apply_cte_builder(
2271            self,
2272            alias,
2273            as_,
2274            recursive=recursive,
2275            materialized=materialized,
2276            append=append,
2277            dialect=dialect,
2278            copy=copy,
2279            **opts,
2280        )

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):
2283class ConditionalInsert(Expression):
2284    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2287class MultitableInserts(Expression):
2288    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2291class OnConflict(Expression):
2292    arg_types = {
2293        "duplicate": False,
2294        "expressions": False,
2295        "action": False,
2296        "conflict_keys": False,
2297        "constraint": False,
2298        "where": False,
2299    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2302class OnCondition(Expression):
2303    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2306class Returning(Expression):
2307    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2311class Introducer(Expression):
2312    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2316class National(Expression):
2317    pass
key = 'national'
class LoadData(Expression):
2320class LoadData(Expression):
2321    arg_types = {
2322        "this": True,
2323        "local": False,
2324        "overwrite": False,
2325        "inpath": True,
2326        "partition": False,
2327        "input_format": False,
2328        "serde": False,
2329    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2332class Partition(Expression):
2333    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2336class PartitionRange(Expression):
2337    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2341class PartitionId(Expression):
2342    pass
key = 'partitionid'
class Fetch(Expression):
2345class Fetch(Expression):
2346    arg_types = {
2347        "direction": False,
2348        "count": False,
2349        "percent": False,
2350        "with_ties": False,
2351    }
arg_types = {'direction': False, 'count': False, 'percent': False, 'with_ties': False}
key = 'fetch'
class Grant(Expression):
2354class Grant(Expression):
2355    arg_types = {
2356        "privileges": True,
2357        "kind": False,
2358        "securable": True,
2359        "principals": True,
2360        "grant_option": False,
2361    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2364class Group(Expression):
2365    arg_types = {
2366        "expressions": False,
2367        "grouping_sets": False,
2368        "cube": False,
2369        "rollup": False,
2370        "totals": False,
2371        "all": False,
2372    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2375class Cube(Expression):
2376    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2379class Rollup(Expression):
2380    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2383class GroupingSets(Expression):
2384    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2387class Lambda(Expression):
2388    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2391class Limit(Expression):
2392    arg_types = {"this": False, "expression": True, "offset": False, "expressions": False}
arg_types = {'this': False, 'expression': True, 'offset': False, 'expressions': False}
key = 'limit'
class Literal(Condition):
2395class Literal(Condition):
2396    arg_types = {"this": True, "is_string": True}
2397
2398    @property
2399    def hashable_args(self) -> t.Any:
2400        return (self.this, self.args.get("is_string"))
2401
2402    @classmethod
2403    def number(cls, number) -> Literal:
2404        return cls(this=str(number), is_string=False)
2405
2406    @classmethod
2407    def string(cls, string) -> Literal:
2408        return cls(this=str(string), is_string=True)
2409
2410    @property
2411    def output_name(self) -> str:
2412        return self.name
2413
2414    def to_py(self) -> int | str | Decimal:
2415        if self.is_number:
2416            try:
2417                return int(self.this)
2418            except ValueError:
2419                return Decimal(self.this)
2420        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2398    @property
2399    def hashable_args(self) -> t.Any:
2400        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2402    @classmethod
2403    def number(cls, number) -> Literal:
2404        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2406    @classmethod
2407    def string(cls, string) -> Literal:
2408        return cls(this=str(string), is_string=True)
output_name: str
2410    @property
2411    def output_name(self) -> str:
2412        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:
2414    def to_py(self) -> int | str | Decimal:
2415        if self.is_number:
2416            try:
2417                return int(self.this)
2418            except ValueError:
2419                return Decimal(self.this)
2420        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2423class Join(Expression):
2424    arg_types = {
2425        "this": True,
2426        "on": False,
2427        "side": False,
2428        "kind": False,
2429        "using": False,
2430        "method": False,
2431        "global": False,
2432        "hint": False,
2433        "match_condition": False,  # Snowflake
2434        "expressions": False,
2435    }
2436
2437    @property
2438    def method(self) -> str:
2439        return self.text("method").upper()
2440
2441    @property
2442    def kind(self) -> str:
2443        return self.text("kind").upper()
2444
2445    @property
2446    def side(self) -> str:
2447        return self.text("side").upper()
2448
2449    @property
2450    def hint(self) -> str:
2451        return self.text("hint").upper()
2452
2453    @property
2454    def alias_or_name(self) -> str:
2455        return self.this.alias_or_name
2456
2457    @property
2458    def is_semi_or_anti_join(self) -> bool:
2459        return self.kind in ("SEMI", "ANTI")
2460
2461    def on(
2462        self,
2463        *expressions: t.Optional[ExpOrStr],
2464        append: bool = True,
2465        dialect: DialectType = None,
2466        copy: bool = True,
2467        **opts,
2468    ) -> Join:
2469        """
2470        Append to or set the ON expressions.
2471
2472        Example:
2473            >>> import sqlglot
2474            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2475            'JOIN x ON y = 1'
2476
2477        Args:
2478            *expressions: the SQL code strings to parse.
2479                If an `Expression` instance is passed, it will be used as-is.
2480                Multiple expressions are combined with an AND operator.
2481            append: if `True`, AND the new expressions to any existing expression.
2482                Otherwise, this resets the expression.
2483            dialect: the dialect used to parse the input expressions.
2484            copy: if `False`, modify this expression instance in-place.
2485            opts: other options to use to parse the input expressions.
2486
2487        Returns:
2488            The modified Join expression.
2489        """
2490        join = _apply_conjunction_builder(
2491            *expressions,
2492            instance=self,
2493            arg="on",
2494            append=append,
2495            dialect=dialect,
2496            copy=copy,
2497            **opts,
2498        )
2499
2500        if join.kind == "CROSS":
2501            join.set("kind", None)
2502
2503        return join
2504
2505    def using(
2506        self,
2507        *expressions: t.Optional[ExpOrStr],
2508        append: bool = True,
2509        dialect: DialectType = None,
2510        copy: bool = True,
2511        **opts,
2512    ) -> Join:
2513        """
2514        Append to or set the USING expressions.
2515
2516        Example:
2517            >>> import sqlglot
2518            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2519            'JOIN x USING (foo, bla)'
2520
2521        Args:
2522            *expressions: the SQL code strings to parse.
2523                If an `Expression` instance is passed, it will be used as-is.
2524            append: if `True`, concatenate the new expressions to the existing "using" list.
2525                Otherwise, this resets the expression.
2526            dialect: the dialect used to parse the input expressions.
2527            copy: if `False`, modify this expression instance in-place.
2528            opts: other options to use to parse the input expressions.
2529
2530        Returns:
2531            The modified Join expression.
2532        """
2533        join = _apply_list_builder(
2534            *expressions,
2535            instance=self,
2536            arg="using",
2537            append=append,
2538            dialect=dialect,
2539            copy=copy,
2540            **opts,
2541        )
2542
2543        if join.kind == "CROSS":
2544            join.set("kind", None)
2545
2546        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}
method: str
2437    @property
2438    def method(self) -> str:
2439        return self.text("method").upper()
kind: str
2441    @property
2442    def kind(self) -> str:
2443        return self.text("kind").upper()
side: str
2445    @property
2446    def side(self) -> str:
2447        return self.text("side").upper()
hint: str
2449    @property
2450    def hint(self) -> str:
2451        return self.text("hint").upper()
alias_or_name: str
2453    @property
2454    def alias_or_name(self) -> str:
2455        return self.this.alias_or_name
is_semi_or_anti_join: bool
2457    @property
2458    def is_semi_or_anti_join(self) -> bool:
2459        return self.kind in ("SEMI", "ANTI")
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2461    def on(
2462        self,
2463        *expressions: t.Optional[ExpOrStr],
2464        append: bool = True,
2465        dialect: DialectType = None,
2466        copy: bool = True,
2467        **opts,
2468    ) -> Join:
2469        """
2470        Append to or set the ON expressions.
2471
2472        Example:
2473            >>> import sqlglot
2474            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2475            'JOIN x ON y = 1'
2476
2477        Args:
2478            *expressions: the SQL code strings to parse.
2479                If an `Expression` instance is passed, it will be used as-is.
2480                Multiple expressions are combined with an AND operator.
2481            append: if `True`, AND the new expressions to any existing expression.
2482                Otherwise, this resets the expression.
2483            dialect: the dialect used to parse the input expressions.
2484            copy: if `False`, modify this expression instance in-place.
2485            opts: other options to use to parse the input expressions.
2486
2487        Returns:
2488            The modified Join expression.
2489        """
2490        join = _apply_conjunction_builder(
2491            *expressions,
2492            instance=self,
2493            arg="on",
2494            append=append,
2495            dialect=dialect,
2496            copy=copy,
2497            **opts,
2498        )
2499
2500        if join.kind == "CROSS":
2501            join.set("kind", None)
2502
2503        return join

Append to or set the ON expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
'JOIN x ON y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

def using( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2505    def using(
2506        self,
2507        *expressions: t.Optional[ExpOrStr],
2508        append: bool = True,
2509        dialect: DialectType = None,
2510        copy: bool = True,
2511        **opts,
2512    ) -> Join:
2513        """
2514        Append to or set the USING expressions.
2515
2516        Example:
2517            >>> import sqlglot
2518            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2519            'JOIN x USING (foo, bla)'
2520
2521        Args:
2522            *expressions: the SQL code strings to parse.
2523                If an `Expression` instance is passed, it will be used as-is.
2524            append: if `True`, concatenate the new expressions to the existing "using" list.
2525                Otherwise, this resets the expression.
2526            dialect: the dialect used to parse the input expressions.
2527            copy: if `False`, modify this expression instance in-place.
2528            opts: other options to use to parse the input expressions.
2529
2530        Returns:
2531            The modified Join expression.
2532        """
2533        join = _apply_list_builder(
2534            *expressions,
2535            instance=self,
2536            arg="using",
2537            append=append,
2538            dialect=dialect,
2539            copy=copy,
2540            **opts,
2541        )
2542
2543        if join.kind == "CROSS":
2544            join.set("kind", None)
2545
2546        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):
2549class Lateral(UDTF):
2550    arg_types = {
2551        "this": True,
2552        "view": False,
2553        "outer": False,
2554        "alias": False,
2555        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2556    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2559class MatchRecognizeMeasure(Expression):
2560    arg_types = {
2561        "this": True,
2562        "window_frame": False,
2563    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2566class MatchRecognize(Expression):
2567    arg_types = {
2568        "partition_by": False,
2569        "order": False,
2570        "measures": False,
2571        "rows": False,
2572        "after": False,
2573        "pattern": False,
2574        "define": False,
2575        "alias": False,
2576    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2581class Final(Expression):
2582    pass
key = 'final'
class Offset(Expression):
2585class Offset(Expression):
2586    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2589class Order(Expression):
2590    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2594class WithFill(Expression):
2595    arg_types = {
2596        "from": False,
2597        "to": False,
2598        "step": False,
2599        "interpolate": False,
2600    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2605class Cluster(Order):
2606    pass
key = 'cluster'
class Distribute(Order):
2609class Distribute(Order):
2610    pass
key = 'distribute'
class Sort(Order):
2613class Sort(Order):
2614    pass
key = 'sort'
class Ordered(Expression):
2617class Ordered(Expression):
2618    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
key = 'ordered'
class Property(Expression):
2621class Property(Expression):
2622    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2625class GrantPrivilege(Expression):
2626    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2629class GrantPrincipal(Expression):
2630    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2633class AllowedValuesProperty(Expression):
2634    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2637class AlgorithmProperty(Property):
2638    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2641class AutoIncrementProperty(Property):
2642    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2646class AutoRefreshProperty(Property):
2647    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2650class BackupProperty(Property):
2651    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2654class BlockCompressionProperty(Property):
2655    arg_types = {
2656        "autotemp": False,
2657        "always": False,
2658        "default": False,
2659        "manual": False,
2660        "never": False,
2661    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2664class CharacterSetProperty(Property):
2665    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2668class ChecksumProperty(Property):
2669    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2672class CollateProperty(Property):
2673    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2676class CopyGrantsProperty(Property):
2677    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2680class DataBlocksizeProperty(Property):
2681    arg_types = {
2682        "size": False,
2683        "units": False,
2684        "minimum": False,
2685        "maximum": False,
2686        "default": False,
2687    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2690class DataDeletionProperty(Property):
2691    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):
2694class DefinerProperty(Property):
2695    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2698class DistKeyProperty(Property):
2699    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2704class DistributedByProperty(Property):
2705    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):
2708class DistStyleProperty(Property):
2709    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2712class DuplicateKeyProperty(Property):
2713    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2716class EngineProperty(Property):
2717    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2720class HeapProperty(Property):
2721    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2724class ToTableProperty(Property):
2725    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2728class ExecuteAsProperty(Property):
2729    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2732class ExternalProperty(Property):
2733    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2736class FallbackProperty(Property):
2737    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2740class FileFormatProperty(Property):
2741    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2744class FreespaceProperty(Property):
2745    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2748class GlobalProperty(Property):
2749    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2752class IcebergProperty(Property):
2753    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2756class InheritsProperty(Property):
2757    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2760class InputModelProperty(Property):
2761    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2764class OutputModelProperty(Property):
2765    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2768class IsolatedLoadingProperty(Property):
2769    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2772class JournalProperty(Property):
2773    arg_types = {
2774        "no": False,
2775        "dual": False,
2776        "before": False,
2777        "local": False,
2778        "after": False,
2779    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2782class LanguageProperty(Property):
2783    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2787class ClusteredByProperty(Property):
2788    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2791class DictProperty(Property):
2792    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2795class DictSubProperty(Property):
2796    pass
key = 'dictsubproperty'
class DictRange(Property):
2799class DictRange(Property):
2800    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2803class DynamicProperty(Property):
2804    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2809class OnCluster(Property):
2810    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2814class EmptyProperty(Property):
2815    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2818class LikeProperty(Property):
2819    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2822class LocationProperty(Property):
2823    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2826class LockProperty(Property):
2827    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2830class LockingProperty(Property):
2831    arg_types = {
2832        "this": False,
2833        "kind": True,
2834        "for_or_in": False,
2835        "lock_type": True,
2836        "override": False,
2837    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2840class LogProperty(Property):
2841    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2844class MaterializedProperty(Property):
2845    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2848class MergeBlockRatioProperty(Property):
2849    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):
2852class NoPrimaryIndexProperty(Property):
2853    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2856class OnProperty(Property):
2857    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2860class OnCommitProperty(Property):
2861    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2864class PartitionedByProperty(Property):
2865    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionByRangeProperty(Property):
2869class PartitionByRangeProperty(Property):
2870    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
2874class PartitionByRangePropertyDynamic(Expression):
2875    arg_types = {"this": False, "start": True, "end": True, "every": True}
arg_types = {'this': False, 'start': True, 'end': True, 'every': True}
key = 'partitionbyrangepropertydynamic'
class UniqueKeyProperty(Property):
2879class UniqueKeyProperty(Property):
2880    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
2884class PartitionBoundSpec(Expression):
2885    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2886    arg_types = {
2887        "this": False,
2888        "expression": False,
2889        "from_expressions": False,
2890        "to_expressions": False,
2891    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2894class PartitionedOfProperty(Property):
2895    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2896    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2899class StreamingTableProperty(Property):
2900    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2903class RemoteWithConnectionModelProperty(Property):
2904    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2907class ReturnsProperty(Property):
2908    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):
2911class StrictProperty(Property):
2912    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2915class RowFormatProperty(Property):
2916    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2919class RowFormatDelimitedProperty(Property):
2920    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2921    arg_types = {
2922        "fields": False,
2923        "escaped": False,
2924        "collection_items": False,
2925        "map_keys": False,
2926        "lines": False,
2927        "null": False,
2928        "serde": False,
2929    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2932class RowFormatSerdeProperty(Property):
2933    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2937class QueryTransform(Expression):
2938    arg_types = {
2939        "expressions": True,
2940        "command_script": True,
2941        "schema": False,
2942        "row_format_before": False,
2943        "record_writer": False,
2944        "row_format_after": False,
2945        "record_reader": False,
2946    }
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):
2949class SampleProperty(Property):
2950    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2954class SecurityProperty(Property):
2955    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2958class SchemaCommentProperty(Property):
2959    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2962class SerdeProperties(Property):
2963    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2966class SetProperty(Property):
2967    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
2970class SharingProperty(Property):
2971    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
2974class SetConfigProperty(Property):
2975    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
2978class SettingsProperty(Property):
2979    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
2982class SortKeyProperty(Property):
2983    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
2986class SqlReadWriteProperty(Property):
2987    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
2990class SqlSecurityProperty(Property):
2991    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
2994class StabilityProperty(Property):
2995    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
2998class TemporaryProperty(Property):
2999    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3002class SecureProperty(Property):
3003    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3007class Tags(ColumnConstraintKind, Property):
3008    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3011class TransformModelProperty(Property):
3012    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3015class TransientProperty(Property):
3016    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3019class UnloggedProperty(Property):
3020    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
3024class ViewAttributeProperty(Property):
3025    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3028class VolatileProperty(Property):
3029    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3032class WithDataProperty(Property):
3033    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3036class WithJournalTableProperty(Property):
3037    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3040class WithSchemaBindingProperty(Property):
3041    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3044class WithSystemVersioningProperty(Property):
3045    arg_types = {
3046        "on": False,
3047        "this": False,
3048        "data_consistency": False,
3049        "retention_period": False,
3050        "with": True,
3051    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3054class WithProcedureOptions(Property):
3055    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3058class EncodeProperty(Property):
3059    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3062class IncludeProperty(Property):
3063    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class Properties(Expression):
3066class Properties(Expression):
3067    arg_types = {"expressions": True}
3068
3069    NAME_TO_PROPERTY = {
3070        "ALGORITHM": AlgorithmProperty,
3071        "AUTO_INCREMENT": AutoIncrementProperty,
3072        "CHARACTER SET": CharacterSetProperty,
3073        "CLUSTERED_BY": ClusteredByProperty,
3074        "COLLATE": CollateProperty,
3075        "COMMENT": SchemaCommentProperty,
3076        "DEFINER": DefinerProperty,
3077        "DISTKEY": DistKeyProperty,
3078        "DISTRIBUTED_BY": DistributedByProperty,
3079        "DISTSTYLE": DistStyleProperty,
3080        "ENGINE": EngineProperty,
3081        "EXECUTE AS": ExecuteAsProperty,
3082        "FORMAT": FileFormatProperty,
3083        "LANGUAGE": LanguageProperty,
3084        "LOCATION": LocationProperty,
3085        "LOCK": LockProperty,
3086        "PARTITIONED_BY": PartitionedByProperty,
3087        "RETURNS": ReturnsProperty,
3088        "ROW_FORMAT": RowFormatProperty,
3089        "SORTKEY": SortKeyProperty,
3090        "ENCODE": EncodeProperty,
3091        "INCLUDE": IncludeProperty,
3092    }
3093
3094    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3095
3096    # CREATE property locations
3097    # Form: schema specified
3098    #   create [POST_CREATE]
3099    #     table a [POST_NAME]
3100    #     (b int) [POST_SCHEMA]
3101    #     with ([POST_WITH])
3102    #     index (b) [POST_INDEX]
3103    #
3104    # Form: alias selection
3105    #   create [POST_CREATE]
3106    #     table a [POST_NAME]
3107    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3108    #     index (c) [POST_INDEX]
3109    class Location(AutoName):
3110        POST_CREATE = auto()
3111        POST_NAME = auto()
3112        POST_SCHEMA = auto()
3113        POST_WITH = auto()
3114        POST_ALIAS = auto()
3115        POST_EXPRESSION = auto()
3116        POST_INDEX = auto()
3117        UNSUPPORTED = auto()
3118
3119    @classmethod
3120    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3121        expressions = []
3122        for key, value in properties_dict.items():
3123            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3124            if property_cls:
3125                expressions.append(property_cls(this=convert(value)))
3126            else:
3127                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3128
3129        return cls(expressions=expressions)
arg_types = {'expressions': True}
NAME_TO_PROPERTY = {'ALGORITHM': <class 'AlgorithmProperty'>, 'AUTO_INCREMENT': <class 'AutoIncrementProperty'>, 'CHARACTER SET': <class 'CharacterSetProperty'>, 'CLUSTERED_BY': <class 'ClusteredByProperty'>, 'COLLATE': <class 'CollateProperty'>, 'COMMENT': <class 'SchemaCommentProperty'>, 'DEFINER': <class 'DefinerProperty'>, 'DISTKEY': <class 'DistKeyProperty'>, 'DISTRIBUTED_BY': <class 'DistributedByProperty'>, 'DISTSTYLE': <class 'DistStyleProperty'>, 'ENGINE': <class 'EngineProperty'>, 'EXECUTE AS': <class 'ExecuteAsProperty'>, 'FORMAT': <class 'FileFormatProperty'>, 'LANGUAGE': <class 'LanguageProperty'>, 'LOCATION': <class 'LocationProperty'>, 'LOCK': <class 'LockProperty'>, 'PARTITIONED_BY': <class 'PartitionedByProperty'>, 'RETURNS': <class 'ReturnsProperty'>, 'ROW_FORMAT': <class 'RowFormatProperty'>, 'SORTKEY': <class 'SortKeyProperty'>, '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 '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:
3119    @classmethod
3120    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3121        expressions = []
3122        for key, value in properties_dict.items():
3123            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3124            if property_cls:
3125                expressions.append(property_cls(this=convert(value)))
3126            else:
3127                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3128
3129        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3109    class Location(AutoName):
3110        POST_CREATE = auto()
3111        POST_NAME = auto()
3112        POST_SCHEMA = auto()
3113        POST_WITH = auto()
3114        POST_ALIAS = auto()
3115        POST_EXPRESSION = auto()
3116        POST_INDEX = auto()
3117        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):
3132class Qualify(Expression):
3133    pass
key = 'qualify'
class InputOutputFormat(Expression):
3136class InputOutputFormat(Expression):
3137    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3141class Return(Expression):
3142    pass
key = 'return'
class Reference(Expression):
3145class Reference(Expression):
3146    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3149class Tuple(Expression):
3150    arg_types = {"expressions": False}
3151
3152    def isin(
3153        self,
3154        *expressions: t.Any,
3155        query: t.Optional[ExpOrStr] = None,
3156        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3157        copy: bool = True,
3158        **opts,
3159    ) -> In:
3160        return In(
3161            this=maybe_copy(self, copy),
3162            expressions=[convert(e, copy=copy) for e in expressions],
3163            query=maybe_parse(query, copy=copy, **opts) if query else None,
3164            unnest=(
3165                Unnest(
3166                    expressions=[
3167                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3168                        for e in ensure_list(unnest)
3169                    ]
3170                )
3171                if unnest
3172                else None
3173            ),
3174        )
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:
3152    def isin(
3153        self,
3154        *expressions: t.Any,
3155        query: t.Optional[ExpOrStr] = None,
3156        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3157        copy: bool = True,
3158        **opts,
3159    ) -> In:
3160        return In(
3161            this=maybe_copy(self, copy),
3162            expressions=[convert(e, copy=copy) for e in expressions],
3163            query=maybe_parse(query, copy=copy, **opts) if query else None,
3164            unnest=(
3165                Unnest(
3166                    expressions=[
3167                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3168                        for e in ensure_list(unnest)
3169                    ]
3170                )
3171                if unnest
3172                else None
3173            ),
3174        )
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):
3205class QueryOption(Expression):
3206    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3210class WithTableHint(Expression):
3211    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3215class IndexTableHint(Expression):
3216    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3220class HistoricalData(Expression):
3221    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3224class Table(Expression):
3225    arg_types = {
3226        "this": False,
3227        "alias": False,
3228        "db": False,
3229        "catalog": False,
3230        "laterals": False,
3231        "joins": False,
3232        "pivots": False,
3233        "hints": False,
3234        "system_time": False,
3235        "version": False,
3236        "format": False,
3237        "pattern": False,
3238        "ordinality": False,
3239        "when": False,
3240        "only": False,
3241        "partition": False,
3242        "changes": False,
3243        "rows_from": False,
3244        "sample": False,
3245    }
3246
3247    @property
3248    def name(self) -> str:
3249        if isinstance(self.this, Func):
3250            return ""
3251        return self.this.name
3252
3253    @property
3254    def db(self) -> str:
3255        return self.text("db")
3256
3257    @property
3258    def catalog(self) -> str:
3259        return self.text("catalog")
3260
3261    @property
3262    def selects(self) -> t.List[Expression]:
3263        return []
3264
3265    @property
3266    def named_selects(self) -> t.List[str]:
3267        return []
3268
3269    @property
3270    def parts(self) -> t.List[Expression]:
3271        """Return the parts of a table in order catalog, db, table."""
3272        parts: t.List[Expression] = []
3273
3274        for arg in ("catalog", "db", "this"):
3275            part = self.args.get(arg)
3276
3277            if isinstance(part, Dot):
3278                parts.extend(part.flatten())
3279            elif isinstance(part, Expression):
3280                parts.append(part)
3281
3282        return parts
3283
3284    def to_column(self, copy: bool = True) -> Expression:
3285        parts = self.parts
3286        last_part = parts[-1]
3287
3288        if isinstance(last_part, Identifier):
3289            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3290        else:
3291            # This branch will be reached if a function or array is wrapped in a `Table`
3292            col = last_part
3293
3294        alias = self.args.get("alias")
3295        if alias:
3296            col = alias_(col, alias.this, copy=copy)
3297
3298        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
3247    @property
3248    def name(self) -> str:
3249        if isinstance(self.this, Func):
3250            return ""
3251        return self.this.name
db: str
3253    @property
3254    def db(self) -> str:
3255        return self.text("db")
catalog: str
3257    @property
3258    def catalog(self) -> str:
3259        return self.text("catalog")
selects: List[Expression]
3261    @property
3262    def selects(self) -> t.List[Expression]:
3263        return []
named_selects: List[str]
3265    @property
3266    def named_selects(self) -> t.List[str]:
3267        return []
parts: List[Expression]
3269    @property
3270    def parts(self) -> t.List[Expression]:
3271        """Return the parts of a table in order catalog, db, table."""
3272        parts: t.List[Expression] = []
3273
3274        for arg in ("catalog", "db", "this"):
3275            part = self.args.get(arg)
3276
3277            if isinstance(part, Dot):
3278                parts.extend(part.flatten())
3279            elif isinstance(part, Expression):
3280                parts.append(part)
3281
3282        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3284    def to_column(self, copy: bool = True) -> Expression:
3285        parts = self.parts
3286        last_part = parts[-1]
3287
3288        if isinstance(last_part, Identifier):
3289            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3290        else:
3291            # This branch will be reached if a function or array is wrapped in a `Table`
3292            col = last_part
3293
3294        alias = self.args.get("alias")
3295        if alias:
3296            col = alias_(col, alias.this, copy=copy)
3297
3298        return col
key = 'table'
class SetOperation(Query):
3301class SetOperation(Query):
3302    arg_types = {
3303        "with": False,
3304        "this": True,
3305        "expression": True,
3306        "distinct": False,
3307        "by_name": False,
3308        **QUERY_MODIFIERS,
3309    }
3310
3311    def select(
3312        self: S,
3313        *expressions: t.Optional[ExpOrStr],
3314        append: bool = True,
3315        dialect: DialectType = None,
3316        copy: bool = True,
3317        **opts,
3318    ) -> S:
3319        this = maybe_copy(self, copy)
3320        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3321        this.expression.unnest().select(
3322            *expressions, append=append, dialect=dialect, copy=False, **opts
3323        )
3324        return this
3325
3326    @property
3327    def named_selects(self) -> t.List[str]:
3328        return self.this.unnest().named_selects
3329
3330    @property
3331    def is_star(self) -> bool:
3332        return self.this.is_star or self.expression.is_star
3333
3334    @property
3335    def selects(self) -> t.List[Expression]:
3336        return self.this.unnest().selects
3337
3338    @property
3339    def left(self) -> Query:
3340        return self.this
3341
3342    @property
3343    def right(self) -> Query:
3344        return self.expression
arg_types = {'with': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False}
def select( self: ~S, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3311    def select(
3312        self: S,
3313        *expressions: t.Optional[ExpOrStr],
3314        append: bool = True,
3315        dialect: DialectType = None,
3316        copy: bool = True,
3317        **opts,
3318    ) -> S:
3319        this = maybe_copy(self, copy)
3320        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3321        this.expression.unnest().select(
3322            *expressions, append=append, dialect=dialect, copy=False, **opts
3323        )
3324        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]
3326    @property
3327    def named_selects(self) -> t.List[str]:
3328        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3330    @property
3331    def is_star(self) -> bool:
3332        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3334    @property
3335    def selects(self) -> t.List[Expression]:
3336        return self.this.unnest().selects

Returns the query's projections.

left: Query
3338    @property
3339    def left(self) -> Query:
3340        return self.this
right: Query
3342    @property
3343    def right(self) -> Query:
3344        return self.expression
key = 'setoperation'
class Union(SetOperation):
3347class Union(SetOperation):
3348    pass
key = 'union'
class Except(SetOperation):
3351class Except(SetOperation):
3352    pass
key = 'except'
class Intersect(SetOperation):
3355class Intersect(SetOperation):
3356    pass
key = 'intersect'
class Update(DML):
3359class Update(DML):
3360    arg_types = {
3361        "with": False,
3362        "this": False,
3363        "expressions": True,
3364        "from": False,
3365        "where": False,
3366        "returning": False,
3367        "order": False,
3368        "limit": False,
3369    }
3370
3371    def table(
3372        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3373    ) -> Update:
3374        """
3375        Set the table to update.
3376
3377        Example:
3378            >>> Update().table("my_table").set_("x = 1").sql()
3379            'UPDATE my_table SET x = 1'
3380
3381        Args:
3382            expression : the SQL code strings to parse.
3383                If a `Table` instance is passed, this is used as-is.
3384                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3385            dialect: the dialect used to parse the input expression.
3386            copy: if `False`, modify this expression instance in-place.
3387            opts: other options to use to parse the input expressions.
3388
3389        Returns:
3390            The modified Update expression.
3391        """
3392        return _apply_builder(
3393            expression=expression,
3394            instance=self,
3395            arg="this",
3396            into=Table,
3397            prefix=None,
3398            dialect=dialect,
3399            copy=copy,
3400            **opts,
3401        )
3402
3403    def set_(
3404        self,
3405        *expressions: ExpOrStr,
3406        append: bool = True,
3407        dialect: DialectType = None,
3408        copy: bool = True,
3409        **opts,
3410    ) -> Update:
3411        """
3412        Append to or set the SET expressions.
3413
3414        Example:
3415            >>> Update().table("my_table").set_("x = 1").sql()
3416            'UPDATE my_table SET x = 1'
3417
3418        Args:
3419            *expressions: the SQL code strings to parse.
3420                If `Expression` instance(s) are passed, they will be used as-is.
3421                Multiple expressions are combined with a comma.
3422            append: if `True`, add the new expressions to any existing SET expressions.
3423                Otherwise, this resets the expressions.
3424            dialect: the dialect used to parse the input expressions.
3425            copy: if `False`, modify this expression instance in-place.
3426            opts: other options to use to parse the input expressions.
3427        """
3428        return _apply_list_builder(
3429            *expressions,
3430            instance=self,
3431            arg="expressions",
3432            append=append,
3433            into=Expression,
3434            prefix=None,
3435            dialect=dialect,
3436            copy=copy,
3437            **opts,
3438        )
3439
3440    def where(
3441        self,
3442        *expressions: t.Optional[ExpOrStr],
3443        append: bool = True,
3444        dialect: DialectType = None,
3445        copy: bool = True,
3446        **opts,
3447    ) -> Select:
3448        """
3449        Append to or set the WHERE expressions.
3450
3451        Example:
3452            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3453            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3454
3455        Args:
3456            *expressions: the SQL code strings to parse.
3457                If an `Expression` instance is passed, it will be used as-is.
3458                Multiple expressions are combined with an AND operator.
3459            append: if `True`, AND the new expressions to any existing expression.
3460                Otherwise, this resets the expression.
3461            dialect: the dialect used to parse the input expressions.
3462            copy: if `False`, modify this expression instance in-place.
3463            opts: other options to use to parse the input expressions.
3464
3465        Returns:
3466            Select: the modified expression.
3467        """
3468        return _apply_conjunction_builder(
3469            *expressions,
3470            instance=self,
3471            arg="where",
3472            append=append,
3473            into=Where,
3474            dialect=dialect,
3475            copy=copy,
3476            **opts,
3477        )
3478
3479    def from_(
3480        self,
3481        expression: t.Optional[ExpOrStr] = None,
3482        dialect: DialectType = None,
3483        copy: bool = True,
3484        **opts,
3485    ) -> Update:
3486        """
3487        Set the FROM expression.
3488
3489        Example:
3490            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3491            'UPDATE my_table SET x = 1 FROM baz'
3492
3493        Args:
3494            expression : the SQL code strings to parse.
3495                If a `From` instance is passed, this is used as-is.
3496                If another `Expression` instance is passed, it will be wrapped in a `From`.
3497                If nothing is passed in then a from is not applied to the expression
3498            dialect: the dialect used to parse the input expression.
3499            copy: if `False`, modify this expression instance in-place.
3500            opts: other options to use to parse the input expressions.
3501
3502        Returns:
3503            The modified Update expression.
3504        """
3505        if not expression:
3506            return maybe_copy(self, copy)
3507
3508        return _apply_builder(
3509            expression=expression,
3510            instance=self,
3511            arg="from",
3512            into=From,
3513            prefix="FROM",
3514            dialect=dialect,
3515            copy=copy,
3516            **opts,
3517        )
3518
3519    def with_(
3520        self,
3521        alias: ExpOrStr,
3522        as_: ExpOrStr,
3523        recursive: t.Optional[bool] = None,
3524        materialized: t.Optional[bool] = None,
3525        append: bool = True,
3526        dialect: DialectType = None,
3527        copy: bool = True,
3528        **opts,
3529    ) -> Update:
3530        """
3531        Append to or set the common table expressions.
3532
3533        Example:
3534            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3535            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3536
3537        Args:
3538            alias: the SQL code string to parse as the table name.
3539                If an `Expression` instance is passed, this is used as-is.
3540            as_: the SQL code string to parse as the table expression.
3541                If an `Expression` instance is passed, it will be used as-is.
3542            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3543            materialized: set the MATERIALIZED part of the expression.
3544            append: if `True`, add to any existing expressions.
3545                Otherwise, this resets the expressions.
3546            dialect: the dialect used to parse the input expression.
3547            copy: if `False`, modify this expression instance in-place.
3548            opts: other options to use to parse the input expressions.
3549
3550        Returns:
3551            The modified expression.
3552        """
3553        return _apply_cte_builder(
3554            self,
3555            alias,
3556            as_,
3557            recursive=recursive,
3558            materialized=materialized,
3559            append=append,
3560            dialect=dialect,
3561            copy=copy,
3562            **opts,
3563        )
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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3371    def table(
3372        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3373    ) -> Update:
3374        """
3375        Set the table to update.
3376
3377        Example:
3378            >>> Update().table("my_table").set_("x = 1").sql()
3379            'UPDATE my_table SET x = 1'
3380
3381        Args:
3382            expression : the SQL code strings to parse.
3383                If a `Table` instance is passed, this is used as-is.
3384                If another `Expression` instance is passed, it will be wrapped in a `Table`.
3385            dialect: the dialect used to parse the input expression.
3386            copy: if `False`, modify this expression instance in-place.
3387            opts: other options to use to parse the input expressions.
3388
3389        Returns:
3390            The modified Update expression.
3391        """
3392        return _apply_builder(
3393            expression=expression,
3394            instance=self,
3395            arg="this",
3396            into=Table,
3397            prefix=None,
3398            dialect=dialect,
3399            copy=copy,
3400            **opts,
3401        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3403    def set_(
3404        self,
3405        *expressions: ExpOrStr,
3406        append: bool = True,
3407        dialect: DialectType = None,
3408        copy: bool = True,
3409        **opts,
3410    ) -> Update:
3411        """
3412        Append to or set the SET expressions.
3413
3414        Example:
3415            >>> Update().table("my_table").set_("x = 1").sql()
3416            'UPDATE my_table SET x = 1'
3417
3418        Args:
3419            *expressions: the SQL code strings to parse.
3420                If `Expression` instance(s) are passed, they will be used as-is.
3421                Multiple expressions are combined with a comma.
3422            append: if `True`, add the new expressions to any existing SET expressions.
3423                Otherwise, this resets the expressions.
3424            dialect: the dialect used to parse the input expressions.
3425            copy: if `False`, modify this expression instance in-place.
3426            opts: other options to use to parse the input expressions.
3427        """
3428        return _apply_list_builder(
3429            *expressions,
3430            instance=self,
3431            arg="expressions",
3432            append=append,
3433            into=Expression,
3434            prefix=None,
3435            dialect=dialect,
3436            copy=copy,
3437            **opts,
3438        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3440    def where(
3441        self,
3442        *expressions: t.Optional[ExpOrStr],
3443        append: bool = True,
3444        dialect: DialectType = None,
3445        copy: bool = True,
3446        **opts,
3447    ) -> Select:
3448        """
3449        Append to or set the WHERE expressions.
3450
3451        Example:
3452            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3453            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3454
3455        Args:
3456            *expressions: the SQL code strings to parse.
3457                If an `Expression` instance is passed, it will be used as-is.
3458                Multiple expressions are combined with an AND operator.
3459            append: if `True`, AND the new expressions to any existing expression.
3460                Otherwise, this resets the expression.
3461            dialect: the dialect used to parse the input expressions.
3462            copy: if `False`, modify this expression instance in-place.
3463            opts: other options to use to parse the input expressions.
3464
3465        Returns:
3466            Select: the modified expression.
3467        """
3468        return _apply_conjunction_builder(
3469            *expressions,
3470            instance=self,
3471            arg="where",
3472            append=append,
3473            into=Where,
3474            dialect=dialect,
3475            copy=copy,
3476            **opts,
3477        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3479    def from_(
3480        self,
3481        expression: t.Optional[ExpOrStr] = None,
3482        dialect: DialectType = None,
3483        copy: bool = True,
3484        **opts,
3485    ) -> Update:
3486        """
3487        Set the FROM expression.
3488
3489        Example:
3490            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3491            'UPDATE my_table SET x = 1 FROM baz'
3492
3493        Args:
3494            expression : the SQL code strings to parse.
3495                If a `From` instance is passed, this is used as-is.
3496                If another `Expression` instance is passed, it will be wrapped in a `From`.
3497                If nothing is passed in then a from is not applied to the expression
3498            dialect: the dialect used to parse the input expression.
3499            copy: if `False`, modify this expression instance in-place.
3500            opts: other options to use to parse the input expressions.
3501
3502        Returns:
3503            The modified Update expression.
3504        """
3505        if not expression:
3506            return maybe_copy(self, copy)
3507
3508        return _apply_builder(
3509            expression=expression,
3510            instance=self,
3511            arg="from",
3512            into=From,
3513            prefix="FROM",
3514            dialect=dialect,
3515            copy=copy,
3516            **opts,
3517        )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3519    def with_(
3520        self,
3521        alias: ExpOrStr,
3522        as_: ExpOrStr,
3523        recursive: t.Optional[bool] = None,
3524        materialized: t.Optional[bool] = None,
3525        append: bool = True,
3526        dialect: DialectType = None,
3527        copy: bool = True,
3528        **opts,
3529    ) -> Update:
3530        """
3531        Append to or set the common table expressions.
3532
3533        Example:
3534            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3535            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3536
3537        Args:
3538            alias: the SQL code string to parse as the table name.
3539                If an `Expression` instance is passed, this is used as-is.
3540            as_: the SQL code string to parse as the table expression.
3541                If an `Expression` instance is passed, it will be used as-is.
3542            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3543            materialized: set the MATERIALIZED part of the expression.
3544            append: if `True`, add to any existing expressions.
3545                Otherwise, this resets the expressions.
3546            dialect: the dialect used to parse the input expression.
3547            copy: if `False`, modify this expression instance in-place.
3548            opts: other options to use to parse the input expressions.
3549
3550        Returns:
3551            The modified expression.
3552        """
3553        return _apply_cte_builder(
3554            self,
3555            alias,
3556            as_,
3557            recursive=recursive,
3558            materialized=materialized,
3559            append=append,
3560            dialect=dialect,
3561            copy=copy,
3562            **opts,
3563        )

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):
3566class Values(UDTF):
3567    arg_types = {"expressions": True, "alias": False}
arg_types = {'expressions': True, 'alias': False}
key = 'values'
class Var(Expression):
3570class Var(Expression):
3571    pass
key = 'var'
class Version(Expression):
3574class Version(Expression):
3575    """
3576    Time travel, iceberg, bigquery etc
3577    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
3578    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
3579    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
3580    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
3581    this is either TIMESTAMP or VERSION
3582    kind is ("AS OF", "BETWEEN")
3583    """
3584
3585    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key = 'version'
class Schema(Expression):
3588class Schema(Expression):
3589    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key = 'schema'
class Lock(Expression):
3594class Lock(Expression):
3595    arg_types = {"update": True, "expressions": False, "wait": False}
arg_types = {'update': True, 'expressions': False, 'wait': False}
key = 'lock'
class Select(Query):
3598class Select(Query):
3599    arg_types = {
3600        "with": False,
3601        "kind": False,
3602        "expressions": False,
3603        "hint": False,
3604        "distinct": False,
3605        "into": False,
3606        "from": False,
3607        "operation_modifiers": False,
3608        **QUERY_MODIFIERS,
3609    }
3610
3611    def from_(
3612        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3613    ) -> Select:
3614        """
3615        Set the FROM expression.
3616
3617        Example:
3618            >>> Select().from_("tbl").select("x").sql()
3619            'SELECT x FROM tbl'
3620
3621        Args:
3622            expression : the SQL code strings to parse.
3623                If a `From` instance is passed, this is used as-is.
3624                If another `Expression` instance is passed, it will be wrapped in a `From`.
3625            dialect: the dialect used to parse the input expression.
3626            copy: if `False`, modify this expression instance in-place.
3627            opts: other options to use to parse the input expressions.
3628
3629        Returns:
3630            The modified Select expression.
3631        """
3632        return _apply_builder(
3633            expression=expression,
3634            instance=self,
3635            arg="from",
3636            into=From,
3637            prefix="FROM",
3638            dialect=dialect,
3639            copy=copy,
3640            **opts,
3641        )
3642
3643    def group_by(
3644        self,
3645        *expressions: t.Optional[ExpOrStr],
3646        append: bool = True,
3647        dialect: DialectType = None,
3648        copy: bool = True,
3649        **opts,
3650    ) -> Select:
3651        """
3652        Set the GROUP BY expression.
3653
3654        Example:
3655            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3656            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3657
3658        Args:
3659            *expressions: the SQL code strings to parse.
3660                If a `Group` instance is passed, this is used as-is.
3661                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3662                If nothing is passed in then a group by is not applied to the expression
3663            append: if `True`, add to any existing expressions.
3664                Otherwise, this flattens all the `Group` expression into a single expression.
3665            dialect: the dialect used to parse the input expression.
3666            copy: if `False`, modify this expression instance in-place.
3667            opts: other options to use to parse the input expressions.
3668
3669        Returns:
3670            The modified Select expression.
3671        """
3672        if not expressions:
3673            return self if not copy else self.copy()
3674
3675        return _apply_child_list_builder(
3676            *expressions,
3677            instance=self,
3678            arg="group",
3679            append=append,
3680            copy=copy,
3681            prefix="GROUP BY",
3682            into=Group,
3683            dialect=dialect,
3684            **opts,
3685        )
3686
3687    def sort_by(
3688        self,
3689        *expressions: t.Optional[ExpOrStr],
3690        append: bool = True,
3691        dialect: DialectType = None,
3692        copy: bool = True,
3693        **opts,
3694    ) -> Select:
3695        """
3696        Set the SORT BY expression.
3697
3698        Example:
3699            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3700            'SELECT x FROM tbl SORT BY x DESC'
3701
3702        Args:
3703            *expressions: the SQL code strings to parse.
3704                If a `Group` instance is passed, this is used as-is.
3705                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3706            append: if `True`, add to any existing expressions.
3707                Otherwise, this flattens all the `Order` expression into a single expression.
3708            dialect: the dialect used to parse the input expression.
3709            copy: if `False`, modify this expression instance in-place.
3710            opts: other options to use to parse the input expressions.
3711
3712        Returns:
3713            The modified Select expression.
3714        """
3715        return _apply_child_list_builder(
3716            *expressions,
3717            instance=self,
3718            arg="sort",
3719            append=append,
3720            copy=copy,
3721            prefix="SORT BY",
3722            into=Sort,
3723            dialect=dialect,
3724            **opts,
3725        )
3726
3727    def cluster_by(
3728        self,
3729        *expressions: t.Optional[ExpOrStr],
3730        append: bool = True,
3731        dialect: DialectType = None,
3732        copy: bool = True,
3733        **opts,
3734    ) -> Select:
3735        """
3736        Set the CLUSTER BY expression.
3737
3738        Example:
3739            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3740            'SELECT x FROM tbl CLUSTER BY x DESC'
3741
3742        Args:
3743            *expressions: the SQL code strings to parse.
3744                If a `Group` instance is passed, this is used as-is.
3745                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3746            append: if `True`, add to any existing expressions.
3747                Otherwise, this flattens all the `Order` expression into a single expression.
3748            dialect: the dialect used to parse the input expression.
3749            copy: if `False`, modify this expression instance in-place.
3750            opts: other options to use to parse the input expressions.
3751
3752        Returns:
3753            The modified Select expression.
3754        """
3755        return _apply_child_list_builder(
3756            *expressions,
3757            instance=self,
3758            arg="cluster",
3759            append=append,
3760            copy=copy,
3761            prefix="CLUSTER BY",
3762            into=Cluster,
3763            dialect=dialect,
3764            **opts,
3765        )
3766
3767    def select(
3768        self,
3769        *expressions: t.Optional[ExpOrStr],
3770        append: bool = True,
3771        dialect: DialectType = None,
3772        copy: bool = True,
3773        **opts,
3774    ) -> Select:
3775        return _apply_list_builder(
3776            *expressions,
3777            instance=self,
3778            arg="expressions",
3779            append=append,
3780            dialect=dialect,
3781            into=Expression,
3782            copy=copy,
3783            **opts,
3784        )
3785
3786    def lateral(
3787        self,
3788        *expressions: t.Optional[ExpOrStr],
3789        append: bool = True,
3790        dialect: DialectType = None,
3791        copy: bool = True,
3792        **opts,
3793    ) -> Select:
3794        """
3795        Append to or set the LATERAL expressions.
3796
3797        Example:
3798            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3799            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3800
3801        Args:
3802            *expressions: the SQL code strings to parse.
3803                If an `Expression` instance is passed, it will be used as-is.
3804            append: if `True`, add to any existing expressions.
3805                Otherwise, this resets the expressions.
3806            dialect: the dialect used to parse the input expressions.
3807            copy: if `False`, modify this expression instance in-place.
3808            opts: other options to use to parse the input expressions.
3809
3810        Returns:
3811            The modified Select expression.
3812        """
3813        return _apply_list_builder(
3814            *expressions,
3815            instance=self,
3816            arg="laterals",
3817            append=append,
3818            into=Lateral,
3819            prefix="LATERAL VIEW",
3820            dialect=dialect,
3821            copy=copy,
3822            **opts,
3823        )
3824
3825    def join(
3826        self,
3827        expression: ExpOrStr,
3828        on: t.Optional[ExpOrStr] = None,
3829        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3830        append: bool = True,
3831        join_type: t.Optional[str] = None,
3832        join_alias: t.Optional[Identifier | str] = None,
3833        dialect: DialectType = None,
3834        copy: bool = True,
3835        **opts,
3836    ) -> Select:
3837        """
3838        Append to or set the JOIN expressions.
3839
3840        Example:
3841            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3842            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3843
3844            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3845            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3846
3847            Use `join_type` to change the type of join:
3848
3849            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3850            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3851
3852        Args:
3853            expression: the SQL code string to parse.
3854                If an `Expression` instance is passed, it will be used as-is.
3855            on: optionally specify the join "on" criteria as a SQL string.
3856                If an `Expression` instance is passed, it will be used as-is.
3857            using: optionally specify the join "using" criteria as a SQL string.
3858                If an `Expression` instance is passed, it will be used as-is.
3859            append: if `True`, add to any existing expressions.
3860                Otherwise, this resets the expressions.
3861            join_type: if set, alter the parsed join type.
3862            join_alias: an optional alias for the joined source.
3863            dialect: the dialect used to parse the input expressions.
3864            copy: if `False`, modify this expression instance in-place.
3865            opts: other options to use to parse the input expressions.
3866
3867        Returns:
3868            Select: the modified expression.
3869        """
3870        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3871
3872        try:
3873            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3874        except ParseError:
3875            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3876
3877        join = expression if isinstance(expression, Join) else Join(this=expression)
3878
3879        if isinstance(join.this, Select):
3880            join.this.replace(join.this.subquery())
3881
3882        if join_type:
3883            method: t.Optional[Token]
3884            side: t.Optional[Token]
3885            kind: t.Optional[Token]
3886
3887            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3888
3889            if method:
3890                join.set("method", method.text)
3891            if side:
3892                join.set("side", side.text)
3893            if kind:
3894                join.set("kind", kind.text)
3895
3896        if on:
3897            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3898            join.set("on", on)
3899
3900        if using:
3901            join = _apply_list_builder(
3902                *ensure_list(using),
3903                instance=join,
3904                arg="using",
3905                append=append,
3906                copy=copy,
3907                into=Identifier,
3908                **opts,
3909            )
3910
3911        if join_alias:
3912            join.set("this", alias_(join.this, join_alias, table=True))
3913
3914        return _apply_list_builder(
3915            join,
3916            instance=self,
3917            arg="joins",
3918            append=append,
3919            copy=copy,
3920            **opts,
3921        )
3922
3923    def where(
3924        self,
3925        *expressions: t.Optional[ExpOrStr],
3926        append: bool = True,
3927        dialect: DialectType = None,
3928        copy: bool = True,
3929        **opts,
3930    ) -> Select:
3931        """
3932        Append to or set the WHERE expressions.
3933
3934        Example:
3935            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3936            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3937
3938        Args:
3939            *expressions: the SQL code strings to parse.
3940                If an `Expression` instance is passed, it will be used as-is.
3941                Multiple expressions are combined with an AND operator.
3942            append: if `True`, AND the new expressions to any existing expression.
3943                Otherwise, this resets the expression.
3944            dialect: the dialect used to parse the input expressions.
3945            copy: if `False`, modify this expression instance in-place.
3946            opts: other options to use to parse the input expressions.
3947
3948        Returns:
3949            Select: the modified expression.
3950        """
3951        return _apply_conjunction_builder(
3952            *expressions,
3953            instance=self,
3954            arg="where",
3955            append=append,
3956            into=Where,
3957            dialect=dialect,
3958            copy=copy,
3959            **opts,
3960        )
3961
3962    def having(
3963        self,
3964        *expressions: t.Optional[ExpOrStr],
3965        append: bool = True,
3966        dialect: DialectType = None,
3967        copy: bool = True,
3968        **opts,
3969    ) -> Select:
3970        """
3971        Append to or set the HAVING expressions.
3972
3973        Example:
3974            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3975            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3976
3977        Args:
3978            *expressions: the SQL code strings to parse.
3979                If an `Expression` instance is passed, it will be used as-is.
3980                Multiple expressions are combined with an AND operator.
3981            append: if `True`, AND the new expressions to any existing expression.
3982                Otherwise, this resets the expression.
3983            dialect: the dialect used to parse the input expressions.
3984            copy: if `False`, modify this expression instance in-place.
3985            opts: other options to use to parse the input expressions.
3986
3987        Returns:
3988            The modified Select expression.
3989        """
3990        return _apply_conjunction_builder(
3991            *expressions,
3992            instance=self,
3993            arg="having",
3994            append=append,
3995            into=Having,
3996            dialect=dialect,
3997            copy=copy,
3998            **opts,
3999        )
4000
4001    def window(
4002        self,
4003        *expressions: t.Optional[ExpOrStr],
4004        append: bool = True,
4005        dialect: DialectType = None,
4006        copy: bool = True,
4007        **opts,
4008    ) -> Select:
4009        return _apply_list_builder(
4010            *expressions,
4011            instance=self,
4012            arg="windows",
4013            append=append,
4014            into=Window,
4015            dialect=dialect,
4016            copy=copy,
4017            **opts,
4018        )
4019
4020    def qualify(
4021        self,
4022        *expressions: t.Optional[ExpOrStr],
4023        append: bool = True,
4024        dialect: DialectType = None,
4025        copy: bool = True,
4026        **opts,
4027    ) -> Select:
4028        return _apply_conjunction_builder(
4029            *expressions,
4030            instance=self,
4031            arg="qualify",
4032            append=append,
4033            into=Qualify,
4034            dialect=dialect,
4035            copy=copy,
4036            **opts,
4037        )
4038
4039    def distinct(
4040        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4041    ) -> Select:
4042        """
4043        Set the OFFSET expression.
4044
4045        Example:
4046            >>> Select().from_("tbl").select("x").distinct().sql()
4047            'SELECT DISTINCT x FROM tbl'
4048
4049        Args:
4050            ons: the expressions to distinct on
4051            distinct: whether the Select should be distinct
4052            copy: if `False`, modify this expression instance in-place.
4053
4054        Returns:
4055            Select: the modified expression.
4056        """
4057        instance = maybe_copy(self, copy)
4058        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4059        instance.set("distinct", Distinct(on=on) if distinct else None)
4060        return instance
4061
4062    def ctas(
4063        self,
4064        table: ExpOrStr,
4065        properties: t.Optional[t.Dict] = None,
4066        dialect: DialectType = None,
4067        copy: bool = True,
4068        **opts,
4069    ) -> Create:
4070        """
4071        Convert this expression to a CREATE TABLE AS statement.
4072
4073        Example:
4074            >>> Select().select("*").from_("tbl").ctas("x").sql()
4075            'CREATE TABLE x AS SELECT * FROM tbl'
4076
4077        Args:
4078            table: the SQL code string to parse as the table name.
4079                If another `Expression` instance is passed, it will be used as-is.
4080            properties: an optional mapping of table properties
4081            dialect: the dialect used to parse the input table.
4082            copy: if `False`, modify this expression instance in-place.
4083            opts: other options to use to parse the input table.
4084
4085        Returns:
4086            The new Create expression.
4087        """
4088        instance = maybe_copy(self, copy)
4089        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4090
4091        properties_expression = None
4092        if properties:
4093            properties_expression = Properties.from_dict(properties)
4094
4095        return Create(
4096            this=table_expression,
4097            kind="TABLE",
4098            expression=instance,
4099            properties=properties_expression,
4100        )
4101
4102    def lock(self, update: bool = True, copy: bool = True) -> Select:
4103        """
4104        Set the locking read mode for this expression.
4105
4106        Examples:
4107            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4108            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4109
4110            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4111            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4112
4113        Args:
4114            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4115            copy: if `False`, modify this expression instance in-place.
4116
4117        Returns:
4118            The modified expression.
4119        """
4120        inst = maybe_copy(self, copy)
4121        inst.set("locks", [Lock(update=update)])
4122
4123        return inst
4124
4125    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4126        """
4127        Set hints for this expression.
4128
4129        Examples:
4130            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4131            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4132
4133        Args:
4134            hints: The SQL code strings to parse as the hints.
4135                If an `Expression` instance is passed, it will be used as-is.
4136            dialect: The dialect used to parse the hints.
4137            copy: If `False`, modify this expression instance in-place.
4138
4139        Returns:
4140            The modified expression.
4141        """
4142        inst = maybe_copy(self, copy)
4143        inst.set(
4144            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4145        )
4146
4147        return inst
4148
4149    @property
4150    def named_selects(self) -> t.List[str]:
4151        return [e.output_name for e in self.expressions if e.alias_or_name]
4152
4153    @property
4154    def is_star(self) -> bool:
4155        return any(expression.is_star for expression in self.expressions)
4156
4157    @property
4158    def selects(self) -> t.List[Expression]:
4159        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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3611    def from_(
3612        self, expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
3613    ) -> Select:
3614        """
3615        Set the FROM expression.
3616
3617        Example:
3618            >>> Select().from_("tbl").select("x").sql()
3619            'SELECT x FROM tbl'
3620
3621        Args:
3622            expression : the SQL code strings to parse.
3623                If a `From` instance is passed, this is used as-is.
3624                If another `Expression` instance is passed, it will be wrapped in a `From`.
3625            dialect: the dialect used to parse the input expression.
3626            copy: if `False`, modify this expression instance in-place.
3627            opts: other options to use to parse the input expressions.
3628
3629        Returns:
3630            The modified Select expression.
3631        """
3632        return _apply_builder(
3633            expression=expression,
3634            instance=self,
3635            arg="from",
3636            into=From,
3637            prefix="FROM",
3638            dialect=dialect,
3639            copy=copy,
3640            **opts,
3641        )

Set the FROM expression.

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

The modified Select expression.

def group_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3643    def group_by(
3644        self,
3645        *expressions: t.Optional[ExpOrStr],
3646        append: bool = True,
3647        dialect: DialectType = None,
3648        copy: bool = True,
3649        **opts,
3650    ) -> Select:
3651        """
3652        Set the GROUP BY expression.
3653
3654        Example:
3655            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3656            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3657
3658        Args:
3659            *expressions: the SQL code strings to parse.
3660                If a `Group` instance is passed, this is used as-is.
3661                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3662                If nothing is passed in then a group by is not applied to the expression
3663            append: if `True`, add to any existing expressions.
3664                Otherwise, this flattens all the `Group` expression into a single expression.
3665            dialect: the dialect used to parse the input expression.
3666            copy: if `False`, modify this expression instance in-place.
3667            opts: other options to use to parse the input expressions.
3668
3669        Returns:
3670            The modified Select expression.
3671        """
3672        if not expressions:
3673            return self if not copy else self.copy()
3674
3675        return _apply_child_list_builder(
3676            *expressions,
3677            instance=self,
3678            arg="group",
3679            append=append,
3680            copy=copy,
3681            prefix="GROUP BY",
3682            into=Group,
3683            dialect=dialect,
3684            **opts,
3685        )

Set the GROUP BY expression.

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

The modified Select expression.

def sort_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3687    def sort_by(
3688        self,
3689        *expressions: t.Optional[ExpOrStr],
3690        append: bool = True,
3691        dialect: DialectType = None,
3692        copy: bool = True,
3693        **opts,
3694    ) -> Select:
3695        """
3696        Set the SORT BY expression.
3697
3698        Example:
3699            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
3700            'SELECT x FROM tbl SORT BY x DESC'
3701
3702        Args:
3703            *expressions: the SQL code strings to parse.
3704                If a `Group` instance is passed, this is used as-is.
3705                If another `Expression` instance is passed, it will be wrapped in a `SORT`.
3706            append: if `True`, add to any existing expressions.
3707                Otherwise, this flattens all the `Order` expression into a single expression.
3708            dialect: the dialect used to parse the input expression.
3709            copy: if `False`, modify this expression instance in-place.
3710            opts: other options to use to parse the input expressions.
3711
3712        Returns:
3713            The modified Select expression.
3714        """
3715        return _apply_child_list_builder(
3716            *expressions,
3717            instance=self,
3718            arg="sort",
3719            append=append,
3720            copy=copy,
3721            prefix="SORT BY",
3722            into=Sort,
3723            dialect=dialect,
3724            **opts,
3725        )

Set the SORT BY expression.

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

The modified Select expression.

def cluster_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3727    def cluster_by(
3728        self,
3729        *expressions: t.Optional[ExpOrStr],
3730        append: bool = True,
3731        dialect: DialectType = None,
3732        copy: bool = True,
3733        **opts,
3734    ) -> Select:
3735        """
3736        Set the CLUSTER BY expression.
3737
3738        Example:
3739            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3740            'SELECT x FROM tbl CLUSTER BY x DESC'
3741
3742        Args:
3743            *expressions: the SQL code strings to parse.
3744                If a `Group` instance is passed, this is used as-is.
3745                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3746            append: if `True`, add to any existing expressions.
3747                Otherwise, this flattens all the `Order` expression into a single expression.
3748            dialect: the dialect used to parse the input expression.
3749            copy: if `False`, modify this expression instance in-place.
3750            opts: other options to use to parse the input expressions.
3751
3752        Returns:
3753            The modified Select expression.
3754        """
3755        return _apply_child_list_builder(
3756            *expressions,
3757            instance=self,
3758            arg="cluster",
3759            append=append,
3760            copy=copy,
3761            prefix="CLUSTER BY",
3762            into=Cluster,
3763            dialect=dialect,
3764            **opts,
3765        )

Set the CLUSTER BY expression.

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

The modified Select expression.

def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3767    def select(
3768        self,
3769        *expressions: t.Optional[ExpOrStr],
3770        append: bool = True,
3771        dialect: DialectType = None,
3772        copy: bool = True,
3773        **opts,
3774    ) -> Select:
3775        return _apply_list_builder(
3776            *expressions,
3777            instance=self,
3778            arg="expressions",
3779            append=append,
3780            dialect=dialect,
3781            into=Expression,
3782            copy=copy,
3783            **opts,
3784        )

Append to or set the SELECT expressions.

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

The modified Query expression.

def lateral( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3786    def lateral(
3787        self,
3788        *expressions: t.Optional[ExpOrStr],
3789        append: bool = True,
3790        dialect: DialectType = None,
3791        copy: bool = True,
3792        **opts,
3793    ) -> Select:
3794        """
3795        Append to or set the LATERAL expressions.
3796
3797        Example:
3798            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3799            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3800
3801        Args:
3802            *expressions: the SQL code strings to parse.
3803                If an `Expression` instance is passed, it will be used as-is.
3804            append: if `True`, add to any existing expressions.
3805                Otherwise, this resets the expressions.
3806            dialect: the dialect used to parse the input expressions.
3807            copy: if `False`, modify this expression instance in-place.
3808            opts: other options to use to parse the input expressions.
3809
3810        Returns:
3811            The modified Select expression.
3812        """
3813        return _apply_list_builder(
3814            *expressions,
3815            instance=self,
3816            arg="laterals",
3817            append=append,
3818            into=Lateral,
3819            prefix="LATERAL VIEW",
3820            dialect=dialect,
3821            copy=copy,
3822            **opts,
3823        )

Append to or set the LATERAL expressions.

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

The modified Select expression.

def join( self, expression: Union[str, Expression], on: Union[str, Expression, NoneType] = None, using: Union[str, Expression, Collection[Union[str, Expression]], NoneType] = None, append: bool = True, join_type: Optional[str] = None, join_alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3825    def join(
3826        self,
3827        expression: ExpOrStr,
3828        on: t.Optional[ExpOrStr] = None,
3829        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3830        append: bool = True,
3831        join_type: t.Optional[str] = None,
3832        join_alias: t.Optional[Identifier | str] = None,
3833        dialect: DialectType = None,
3834        copy: bool = True,
3835        **opts,
3836    ) -> Select:
3837        """
3838        Append to or set the JOIN expressions.
3839
3840        Example:
3841            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3842            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3843
3844            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3845            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3846
3847            Use `join_type` to change the type of join:
3848
3849            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3850            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3851
3852        Args:
3853            expression: the SQL code string to parse.
3854                If an `Expression` instance is passed, it will be used as-is.
3855            on: optionally specify the join "on" criteria as a SQL string.
3856                If an `Expression` instance is passed, it will be used as-is.
3857            using: optionally specify the join "using" criteria as a SQL string.
3858                If an `Expression` instance is passed, it will be used as-is.
3859            append: if `True`, add to any existing expressions.
3860                Otherwise, this resets the expressions.
3861            join_type: if set, alter the parsed join type.
3862            join_alias: an optional alias for the joined source.
3863            dialect: the dialect used to parse the input expressions.
3864            copy: if `False`, modify this expression instance in-place.
3865            opts: other options to use to parse the input expressions.
3866
3867        Returns:
3868            Select: the modified expression.
3869        """
3870        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3871
3872        try:
3873            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3874        except ParseError:
3875            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3876
3877        join = expression if isinstance(expression, Join) else Join(this=expression)
3878
3879        if isinstance(join.this, Select):
3880            join.this.replace(join.this.subquery())
3881
3882        if join_type:
3883            method: t.Optional[Token]
3884            side: t.Optional[Token]
3885            kind: t.Optional[Token]
3886
3887            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3888
3889            if method:
3890                join.set("method", method.text)
3891            if side:
3892                join.set("side", side.text)
3893            if kind:
3894                join.set("kind", kind.text)
3895
3896        if on:
3897            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3898            join.set("on", on)
3899
3900        if using:
3901            join = _apply_list_builder(
3902                *ensure_list(using),
3903                instance=join,
3904                arg="using",
3905                append=append,
3906                copy=copy,
3907                into=Identifier,
3908                **opts,
3909            )
3910
3911        if join_alias:
3912            join.set("this", alias_(join.this, join_alias, table=True))
3913
3914        return _apply_list_builder(
3915            join,
3916            instance=self,
3917            arg="joins",
3918            append=append,
3919            copy=copy,
3920            **opts,
3921        )

Append to or set the JOIN expressions.

Example:
>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
>>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
'SELECT 1 FROM a JOIN b USING (x, y, z)'

Use join_type to change the type of join:

>>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
Arguments:
  • expression: the SQL code string to parse. If an Expression instance is passed, it will be used as-is.
  • on: optionally specify the join "on" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • using: optionally specify the join "using" criteria as a SQL string. If an Expression instance is passed, it will be used as-is.
  • append: if True, add to any existing expressions. Otherwise, this resets the expressions.
  • join_type: if set, alter the parsed join type.
  • join_alias: an optional alias for the joined source.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

Select: the modified expression.

def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3923    def where(
3924        self,
3925        *expressions: t.Optional[ExpOrStr],
3926        append: bool = True,
3927        dialect: DialectType = None,
3928        copy: bool = True,
3929        **opts,
3930    ) -> Select:
3931        """
3932        Append to or set the WHERE expressions.
3933
3934        Example:
3935            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3936            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3937
3938        Args:
3939            *expressions: the SQL code strings to parse.
3940                If an `Expression` instance is passed, it will be used as-is.
3941                Multiple expressions are combined with an AND operator.
3942            append: if `True`, AND the new expressions to any existing expression.
3943                Otherwise, this resets the expression.
3944            dialect: the dialect used to parse the input expressions.
3945            copy: if `False`, modify this expression instance in-place.
3946            opts: other options to use to parse the input expressions.
3947
3948        Returns:
3949            Select: the modified expression.
3950        """
3951        return _apply_conjunction_builder(
3952            *expressions,
3953            instance=self,
3954            arg="where",
3955            append=append,
3956            into=Where,
3957            dialect=dialect,
3958            copy=copy,
3959            **opts,
3960        )

Append to or set the WHERE expressions.

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

Select: the modified expression.

def having( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3962    def having(
3963        self,
3964        *expressions: t.Optional[ExpOrStr],
3965        append: bool = True,
3966        dialect: DialectType = None,
3967        copy: bool = True,
3968        **opts,
3969    ) -> Select:
3970        """
3971        Append to or set the HAVING expressions.
3972
3973        Example:
3974            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
3975            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
3976
3977        Args:
3978            *expressions: the SQL code strings to parse.
3979                If an `Expression` instance is passed, it will be used as-is.
3980                Multiple expressions are combined with an AND operator.
3981            append: if `True`, AND the new expressions to any existing expression.
3982                Otherwise, this resets the expression.
3983            dialect: the dialect used to parse the input expressions.
3984            copy: if `False`, modify this expression instance in-place.
3985            opts: other options to use to parse the input expressions.
3986
3987        Returns:
3988            The modified Select expression.
3989        """
3990        return _apply_conjunction_builder(
3991            *expressions,
3992            instance=self,
3993            arg="having",
3994            append=append,
3995            into=Having,
3996            dialect=dialect,
3997            copy=copy,
3998            **opts,
3999        )

Append to or set the HAVING expressions.

Example:
>>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Select expression.

def window( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4001    def window(
4002        self,
4003        *expressions: t.Optional[ExpOrStr],
4004        append: bool = True,
4005        dialect: DialectType = None,
4006        copy: bool = True,
4007        **opts,
4008    ) -> Select:
4009        return _apply_list_builder(
4010            *expressions,
4011            instance=self,
4012            arg="windows",
4013            append=append,
4014            into=Window,
4015            dialect=dialect,
4016            copy=copy,
4017            **opts,
4018        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4020    def qualify(
4021        self,
4022        *expressions: t.Optional[ExpOrStr],
4023        append: bool = True,
4024        dialect: DialectType = None,
4025        copy: bool = True,
4026        **opts,
4027    ) -> Select:
4028        return _apply_conjunction_builder(
4029            *expressions,
4030            instance=self,
4031            arg="qualify",
4032            append=append,
4033            into=Qualify,
4034            dialect=dialect,
4035            copy=copy,
4036            **opts,
4037        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4039    def distinct(
4040        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4041    ) -> Select:
4042        """
4043        Set the OFFSET expression.
4044
4045        Example:
4046            >>> Select().from_("tbl").select("x").distinct().sql()
4047            'SELECT DISTINCT x FROM tbl'
4048
4049        Args:
4050            ons: the expressions to distinct on
4051            distinct: whether the Select should be distinct
4052            copy: if `False`, modify this expression instance in-place.
4053
4054        Returns:
4055            Select: the modified expression.
4056        """
4057        instance = maybe_copy(self, copy)
4058        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4059        instance.set("distinct", Distinct(on=on) if distinct else None)
4060        return instance

Set the OFFSET expression.

Example:
>>> Select().from_("tbl").select("x").distinct().sql()
'SELECT DISTINCT x FROM tbl'
Arguments:
  • ons: the expressions to distinct on
  • distinct: whether the Select should be distinct
  • copy: if False, modify this expression instance in-place.
Returns:

Select: the modified expression.

def ctas( self, table: Union[str, Expression], properties: Optional[Dict] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
4062    def ctas(
4063        self,
4064        table: ExpOrStr,
4065        properties: t.Optional[t.Dict] = None,
4066        dialect: DialectType = None,
4067        copy: bool = True,
4068        **opts,
4069    ) -> Create:
4070        """
4071        Convert this expression to a CREATE TABLE AS statement.
4072
4073        Example:
4074            >>> Select().select("*").from_("tbl").ctas("x").sql()
4075            'CREATE TABLE x AS SELECT * FROM tbl'
4076
4077        Args:
4078            table: the SQL code string to parse as the table name.
4079                If another `Expression` instance is passed, it will be used as-is.
4080            properties: an optional mapping of table properties
4081            dialect: the dialect used to parse the input table.
4082            copy: if `False`, modify this expression instance in-place.
4083            opts: other options to use to parse the input table.
4084
4085        Returns:
4086            The new Create expression.
4087        """
4088        instance = maybe_copy(self, copy)
4089        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4090
4091        properties_expression = None
4092        if properties:
4093            properties_expression = Properties.from_dict(properties)
4094
4095        return Create(
4096            this=table_expression,
4097            kind="TABLE",
4098            expression=instance,
4099            properties=properties_expression,
4100        )

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:
4102    def lock(self, update: bool = True, copy: bool = True) -> Select:
4103        """
4104        Set the locking read mode for this expression.
4105
4106        Examples:
4107            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4108            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4109
4110            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4111            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4112
4113        Args:
4114            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4115            copy: if `False`, modify this expression instance in-place.
4116
4117        Returns:
4118            The modified expression.
4119        """
4120        inst = maybe_copy(self, copy)
4121        inst.set("locks", [Lock(update=update)])
4122
4123        return inst

Set the locking read mode for this expression.

Examples:
>>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
"SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
>>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
"SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
Arguments:
  • update: if True, the locking type will be FOR UPDATE, else it will be FOR SHARE.
  • copy: if False, modify this expression instance in-place.
Returns:

The modified expression.

def hint( self, *hints: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Select:
4125    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4126        """
4127        Set hints for this expression.
4128
4129        Examples:
4130            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4131            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4132
4133        Args:
4134            hints: The SQL code strings to parse as the hints.
4135                If an `Expression` instance is passed, it will be used as-is.
4136            dialect: The dialect used to parse the hints.
4137            copy: If `False`, modify this expression instance in-place.
4138
4139        Returns:
4140            The modified expression.
4141        """
4142        inst = maybe_copy(self, copy)
4143        inst.set(
4144            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4145        )
4146
4147        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]
4149    @property
4150    def named_selects(self) -> t.List[str]:
4151        return [e.output_name for e in self.expressions if e.alias_or_name]

Returns the output names of the query's projections.

is_star: bool
4153    @property
4154    def is_star(self) -> bool:
4155        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4157    @property
4158    def selects(self) -> t.List[Expression]:
4159        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4165class Subquery(DerivedTable, Query):
4166    arg_types = {
4167        "this": True,
4168        "alias": False,
4169        "with": False,
4170        **QUERY_MODIFIERS,
4171    }
4172
4173    def unnest(self):
4174        """Returns the first non subquery."""
4175        expression = self
4176        while isinstance(expression, Subquery):
4177            expression = expression.this
4178        return expression
4179
4180    def unwrap(self) -> Subquery:
4181        expression = self
4182        while expression.same_parent and expression.is_wrapper:
4183            expression = t.cast(Subquery, expression.parent)
4184        return expression
4185
4186    def select(
4187        self,
4188        *expressions: t.Optional[ExpOrStr],
4189        append: bool = True,
4190        dialect: DialectType = None,
4191        copy: bool = True,
4192        **opts,
4193    ) -> Subquery:
4194        this = maybe_copy(self, copy)
4195        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4196        return this
4197
4198    @property
4199    def is_wrapper(self) -> bool:
4200        """
4201        Whether this Subquery acts as a simple wrapper around another expression.
4202
4203        SELECT * FROM (((SELECT * FROM t)))
4204                      ^
4205                      This corresponds to a "wrapper" Subquery node
4206        """
4207        return all(v is None for k, v in self.args.items() if k != "this")
4208
4209    @property
4210    def is_star(self) -> bool:
4211        return self.this.is_star
4212
4213    @property
4214    def output_name(self) -> str:
4215        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):
4173    def unnest(self):
4174        """Returns the first non subquery."""
4175        expression = self
4176        while isinstance(expression, Subquery):
4177            expression = expression.this
4178        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4180    def unwrap(self) -> Subquery:
4181        expression = self
4182        while expression.same_parent and expression.is_wrapper:
4183            expression = t.cast(Subquery, expression.parent)
4184        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
4186    def select(
4187        self,
4188        *expressions: t.Optional[ExpOrStr],
4189        append: bool = True,
4190        dialect: DialectType = None,
4191        copy: bool = True,
4192        **opts,
4193    ) -> Subquery:
4194        this = maybe_copy(self, copy)
4195        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4196        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
4198    @property
4199    def is_wrapper(self) -> bool:
4200        """
4201        Whether this Subquery acts as a simple wrapper around another expression.
4202
4203        SELECT * FROM (((SELECT * FROM t)))
4204                      ^
4205                      This corresponds to a "wrapper" Subquery node
4206        """
4207        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
4209    @property
4210    def is_star(self) -> bool:
4211        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4213    @property
4214    def output_name(self) -> str:
4215        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):
4218class TableSample(Expression):
4219    arg_types = {
4220        "expressions": False,
4221        "method": False,
4222        "bucket_numerator": False,
4223        "bucket_denominator": False,
4224        "bucket_field": False,
4225        "percent": False,
4226        "rows": False,
4227        "size": False,
4228        "seed": False,
4229    }
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):
4232class Tag(Expression):
4233    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4234
4235    arg_types = {
4236        "this": False,
4237        "prefix": False,
4238        "postfix": False,
4239    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4244class Pivot(Expression):
4245    arg_types = {
4246        "this": False,
4247        "alias": False,
4248        "expressions": False,
4249        "field": False,
4250        "unpivot": False,
4251        "using": False,
4252        "group": False,
4253        "columns": False,
4254        "include_nulls": False,
4255        "default_on_null": False,
4256        "into": False,
4257    }
4258
4259    @property
4260    def unpivot(self) -> bool:
4261        return bool(self.args.get("unpivot"))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'field': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False, 'into': False}
unpivot: bool
4259    @property
4260    def unpivot(self) -> bool:
4261        return bool(self.args.get("unpivot"))
key = 'pivot'
class UnpivotColumns(Expression):
4266class UnpivotColumns(Expression):
4267    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4270class Window(Condition):
4271    arg_types = {
4272        "this": True,
4273        "partition_by": False,
4274        "order": False,
4275        "spec": False,
4276        "alias": False,
4277        "over": False,
4278        "first": False,
4279    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4282class WindowSpec(Expression):
4283    arg_types = {
4284        "kind": False,
4285        "start": False,
4286        "start_side": False,
4287        "end": False,
4288        "end_side": False,
4289    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4292class PreWhere(Expression):
4293    pass
key = 'prewhere'
class Where(Expression):
4296class Where(Expression):
4297    pass
key = 'where'
class Star(Expression):
4300class Star(Expression):
4301    arg_types = {"except": False, "replace": False, "rename": False}
4302
4303    @property
4304    def name(self) -> str:
4305        return "*"
4306
4307    @property
4308    def output_name(self) -> str:
4309        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4303    @property
4304    def name(self) -> str:
4305        return "*"
output_name: str
4307    @property
4308    def output_name(self) -> str:
4309        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):
4312class Parameter(Condition):
4313    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4316class SessionParameter(Condition):
4317    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4320class Placeholder(Condition):
4321    arg_types = {"this": False, "kind": False}
4322
4323    @property
4324    def name(self) -> str:
4325        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4323    @property
4324    def name(self) -> str:
4325        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4328class Null(Condition):
4329    arg_types: t.Dict[str, t.Any] = {}
4330
4331    @property
4332    def name(self) -> str:
4333        return "NULL"
4334
4335    def to_py(self) -> Lit[None]:
4336        return None
arg_types: Dict[str, Any] = {}
name: str
4331    @property
4332    def name(self) -> str:
4333        return "NULL"
def to_py(self) -> Literal[None]:
4335    def to_py(self) -> Lit[None]:
4336        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4339class Boolean(Condition):
4340    def to_py(self) -> bool:
4341        return self.this
def to_py(self) -> bool:
4340    def to_py(self) -> bool:
4341        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4344class DataTypeParam(Expression):
4345    arg_types = {"this": True, "expression": False}
4346
4347    @property
4348    def name(self) -> str:
4349        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4347    @property
4348    def name(self) -> str:
4349        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4354class DataType(Expression):
4355    arg_types = {
4356        "this": True,
4357        "expressions": False,
4358        "nested": False,
4359        "values": False,
4360        "prefix": False,
4361        "kind": False,
4362        "nullable": False,
4363    }
4364
4365    class Type(AutoName):
4366        ARRAY = auto()
4367        AGGREGATEFUNCTION = auto()
4368        SIMPLEAGGREGATEFUNCTION = auto()
4369        BIGDECIMAL = auto()
4370        BIGINT = auto()
4371        BIGSERIAL = auto()
4372        BINARY = auto()
4373        BIT = auto()
4374        BOOLEAN = auto()
4375        BPCHAR = auto()
4376        CHAR = auto()
4377        DATE = auto()
4378        DATE32 = auto()
4379        DATEMULTIRANGE = auto()
4380        DATERANGE = auto()
4381        DATETIME = auto()
4382        DATETIME2 = auto()
4383        DATETIME64 = auto()
4384        DECIMAL = auto()
4385        DECIMAL32 = auto()
4386        DECIMAL64 = auto()
4387        DECIMAL128 = auto()
4388        DECIMAL256 = auto()
4389        DOUBLE = auto()
4390        DYNAMIC = auto()
4391        ENUM = auto()
4392        ENUM8 = auto()
4393        ENUM16 = auto()
4394        FIXEDSTRING = auto()
4395        FLOAT = auto()
4396        GEOGRAPHY = auto()
4397        GEOMETRY = auto()
4398        POINT = auto()
4399        RING = auto()
4400        LINESTRING = auto()
4401        MULTILINESTRING = auto()
4402        POLYGON = auto()
4403        MULTIPOLYGON = auto()
4404        HLLSKETCH = auto()
4405        HSTORE = auto()
4406        IMAGE = auto()
4407        INET = auto()
4408        INT = auto()
4409        INT128 = auto()
4410        INT256 = auto()
4411        INT4MULTIRANGE = auto()
4412        INT4RANGE = auto()
4413        INT8MULTIRANGE = auto()
4414        INT8RANGE = auto()
4415        INTERVAL = auto()
4416        IPADDRESS = auto()
4417        IPPREFIX = auto()
4418        IPV4 = auto()
4419        IPV6 = auto()
4420        JSON = auto()
4421        JSONB = auto()
4422        LIST = auto()
4423        LONGBLOB = auto()
4424        LONGTEXT = auto()
4425        LOWCARDINALITY = auto()
4426        MAP = auto()
4427        MEDIUMBLOB = auto()
4428        MEDIUMINT = auto()
4429        MEDIUMTEXT = auto()
4430        MONEY = auto()
4431        NAME = auto()
4432        NCHAR = auto()
4433        NESTED = auto()
4434        NULL = auto()
4435        NUMMULTIRANGE = auto()
4436        NUMRANGE = auto()
4437        NVARCHAR = auto()
4438        OBJECT = auto()
4439        RANGE = auto()
4440        ROWVERSION = auto()
4441        SERIAL = auto()
4442        SET = auto()
4443        SMALLDATETIME = auto()
4444        SMALLINT = auto()
4445        SMALLMONEY = auto()
4446        SMALLSERIAL = auto()
4447        STRUCT = auto()
4448        SUPER = auto()
4449        TEXT = auto()
4450        TINYBLOB = auto()
4451        TINYTEXT = auto()
4452        TIME = auto()
4453        TIMETZ = auto()
4454        TIMESTAMP = auto()
4455        TIMESTAMPNTZ = auto()
4456        TIMESTAMPLTZ = auto()
4457        TIMESTAMPTZ = auto()
4458        TIMESTAMP_S = auto()
4459        TIMESTAMP_MS = auto()
4460        TIMESTAMP_NS = auto()
4461        TINYINT = auto()
4462        TSMULTIRANGE = auto()
4463        TSRANGE = auto()
4464        TSTZMULTIRANGE = auto()
4465        TSTZRANGE = auto()
4466        UBIGINT = auto()
4467        UINT = auto()
4468        UINT128 = auto()
4469        UINT256 = auto()
4470        UMEDIUMINT = auto()
4471        UDECIMAL = auto()
4472        UNION = auto()
4473        UNIQUEIDENTIFIER = auto()
4474        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4475        USERDEFINED = "USER-DEFINED"
4476        USMALLINT = auto()
4477        UTINYINT = auto()
4478        UUID = auto()
4479        VARBINARY = auto()
4480        VARCHAR = auto()
4481        VARIANT = auto()
4482        VECTOR = auto()
4483        XML = auto()
4484        YEAR = auto()
4485        TDIGEST = auto()
4486
4487    STRUCT_TYPES = {
4488        Type.NESTED,
4489        Type.OBJECT,
4490        Type.STRUCT,
4491        Type.UNION,
4492    }
4493
4494    ARRAY_TYPES = {
4495        Type.ARRAY,
4496        Type.LIST,
4497    }
4498
4499    NESTED_TYPES = {
4500        *STRUCT_TYPES,
4501        *ARRAY_TYPES,
4502        Type.MAP,
4503    }
4504
4505    TEXT_TYPES = {
4506        Type.CHAR,
4507        Type.NCHAR,
4508        Type.NVARCHAR,
4509        Type.TEXT,
4510        Type.VARCHAR,
4511        Type.NAME,
4512    }
4513
4514    SIGNED_INTEGER_TYPES = {
4515        Type.BIGINT,
4516        Type.INT,
4517        Type.INT128,
4518        Type.INT256,
4519        Type.MEDIUMINT,
4520        Type.SMALLINT,
4521        Type.TINYINT,
4522    }
4523
4524    UNSIGNED_INTEGER_TYPES = {
4525        Type.UBIGINT,
4526        Type.UINT,
4527        Type.UINT128,
4528        Type.UINT256,
4529        Type.UMEDIUMINT,
4530        Type.USMALLINT,
4531        Type.UTINYINT,
4532    }
4533
4534    INTEGER_TYPES = {
4535        *SIGNED_INTEGER_TYPES,
4536        *UNSIGNED_INTEGER_TYPES,
4537        Type.BIT,
4538    }
4539
4540    FLOAT_TYPES = {
4541        Type.DOUBLE,
4542        Type.FLOAT,
4543    }
4544
4545    REAL_TYPES = {
4546        *FLOAT_TYPES,
4547        Type.BIGDECIMAL,
4548        Type.DECIMAL,
4549        Type.DECIMAL32,
4550        Type.DECIMAL64,
4551        Type.DECIMAL128,
4552        Type.DECIMAL256,
4553        Type.MONEY,
4554        Type.SMALLMONEY,
4555        Type.UDECIMAL,
4556    }
4557
4558    NUMERIC_TYPES = {
4559        *INTEGER_TYPES,
4560        *REAL_TYPES,
4561    }
4562
4563    TEMPORAL_TYPES = {
4564        Type.DATE,
4565        Type.DATE32,
4566        Type.DATETIME,
4567        Type.DATETIME2,
4568        Type.DATETIME64,
4569        Type.SMALLDATETIME,
4570        Type.TIME,
4571        Type.TIMESTAMP,
4572        Type.TIMESTAMPNTZ,
4573        Type.TIMESTAMPLTZ,
4574        Type.TIMESTAMPTZ,
4575        Type.TIMESTAMP_MS,
4576        Type.TIMESTAMP_NS,
4577        Type.TIMESTAMP_S,
4578        Type.TIMETZ,
4579    }
4580
4581    @classmethod
4582    def build(
4583        cls,
4584        dtype: DATA_TYPE,
4585        dialect: DialectType = None,
4586        udt: bool = False,
4587        copy: bool = True,
4588        **kwargs,
4589    ) -> DataType:
4590        """
4591        Constructs a DataType object.
4592
4593        Args:
4594            dtype: the data type of interest.
4595            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4596            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4597                DataType, thus creating a user-defined type.
4598            copy: whether to copy the data type.
4599            kwargs: additional arguments to pass in the constructor of DataType.
4600
4601        Returns:
4602            The constructed DataType object.
4603        """
4604        from sqlglot import parse_one
4605
4606        if isinstance(dtype, str):
4607            if dtype.upper() == "UNKNOWN":
4608                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4609
4610            try:
4611                data_type_exp = parse_one(
4612                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4613                )
4614            except ParseError:
4615                if udt:
4616                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4617                raise
4618        elif isinstance(dtype, DataType.Type):
4619            data_type_exp = DataType(this=dtype)
4620        elif isinstance(dtype, DataType):
4621            return maybe_copy(dtype, copy)
4622        else:
4623            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4624
4625        return DataType(**{**data_type_exp.args, **kwargs})
4626
4627    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4628        """
4629        Checks whether this DataType matches one of the provided data types. Nested types or precision
4630        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4631
4632        Args:
4633            dtypes: the data types to compare this DataType to.
4634            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4635                If false, it means that NULLABLE<INT> is equivalent to INT.
4636
4637        Returns:
4638            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4639        """
4640        self_is_nullable = self.args.get("nullable")
4641        for dtype in dtypes:
4642            other_type = DataType.build(dtype, copy=False, udt=True)
4643            other_is_nullable = other_type.args.get("nullable")
4644            if (
4645                other_type.expressions
4646                or (check_nullable and (self_is_nullable or other_is_nullable))
4647                or self.this == DataType.Type.USERDEFINED
4648                or other_type.this == DataType.Type.USERDEFINED
4649            ):
4650                matches = self == other_type
4651            else:
4652                matches = self.this == other_type.this
4653
4654            if matches:
4655                return True
4656        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.OBJECT: 'OBJECT'>, <Type.UNION: 'UNION'>, <Type.NESTED: 'NESTED'>, <Type.STRUCT: 'STRUCT'>}
ARRAY_TYPES = {<Type.ARRAY: 'ARRAY'>, <Type.LIST: 'LIST'>}
NESTED_TYPES = {<Type.LIST: 'LIST'>, <Type.UNION: 'UNION'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>, <Type.ARRAY: 'ARRAY'>, <Type.MAP: 'MAP'>, <Type.STRUCT: 'STRUCT'>}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.TEXT: 'TEXT'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NAME: 'NAME'>, <Type.NCHAR: 'NCHAR'>}
SIGNED_INTEGER_TYPES = {<Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.INT256: 'INT256'>}
UNSIGNED_INTEGER_TYPES = {<Type.UTINYINT: 'UTINYINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT: 'UINT'>, <Type.UINT256: 'UINT256'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UINT128: 'UINT128'>}
INTEGER_TYPES = {<Type.TINYINT: 'TINYINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.BIT: 'BIT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.UINT: 'UINT'>, <Type.UINT256: 'UINT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT128: 'INT128'>, <Type.UINT128: 'UINT128'>, <Type.INT256: 'INT256'>}
FLOAT_TYPES = {<Type.FLOAT: 'FLOAT'>, <Type.DOUBLE: 'DOUBLE'>}
REAL_TYPES = {<Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.MONEY: 'MONEY'>, <Type.DECIMAL64: 'DECIMAL64'>}
NUMERIC_TYPES = {<Type.TINYINT: 'TINYINT'>, <Type.INT: 'INT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT: 'UINT'>, <Type.MONEY: 'MONEY'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.INT256: 'INT256'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.UTINYINT: 'UTINYINT'>, <Type.BIGINT: 'BIGINT'>, <Type.DECIMAL: 'DECIMAL'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.BIT: 'BIT'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.UBIGINT: 'UBIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.DOUBLE: 'DOUBLE'>, <Type.UINT256: 'UINT256'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.FLOAT: 'FLOAT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.INT128: 'INT128'>, <Type.UINT128: 'UINT128'>}
TEMPORAL_TYPES = {<Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.DATETIME64: 'DATETIME64'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.DATETIME2: 'DATETIME2'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATETIME: 'DATETIME'>, <Type.DATE: 'DATE'>, <Type.DATE32: 'DATE32'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>, <Type.TIME: 'TIME'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4581    @classmethod
4582    def build(
4583        cls,
4584        dtype: DATA_TYPE,
4585        dialect: DialectType = None,
4586        udt: bool = False,
4587        copy: bool = True,
4588        **kwargs,
4589    ) -> DataType:
4590        """
4591        Constructs a DataType object.
4592
4593        Args:
4594            dtype: the data type of interest.
4595            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4596            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4597                DataType, thus creating a user-defined type.
4598            copy: whether to copy the data type.
4599            kwargs: additional arguments to pass in the constructor of DataType.
4600
4601        Returns:
4602            The constructed DataType object.
4603        """
4604        from sqlglot import parse_one
4605
4606        if isinstance(dtype, str):
4607            if dtype.upper() == "UNKNOWN":
4608                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4609
4610            try:
4611                data_type_exp = parse_one(
4612                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4613                )
4614            except ParseError:
4615                if udt:
4616                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4617                raise
4618        elif isinstance(dtype, DataType.Type):
4619            data_type_exp = DataType(this=dtype)
4620        elif isinstance(dtype, DataType):
4621            return maybe_copy(dtype, copy)
4622        else:
4623            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4624
4625        return DataType(**{**data_type_exp.args, **kwargs})

Constructs a DataType object.

Arguments:
  • dtype: the data type of interest.
  • dialect: the dialect to use for parsing dtype, in case it's a string.
  • udt: when set to True, dtype will be used as-is if it can't be parsed into a DataType, thus creating a user-defined type.
  • copy: whether to copy the data type.
  • kwargs: additional arguments to pass in the constructor of DataType.
Returns:

The constructed DataType object.

def is_type( self, *dtypes: Union[str, DataType, DataType.Type], check_nullable: bool = False) -> bool:
4627    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4628        """
4629        Checks whether this DataType matches one of the provided data types. Nested types or precision
4630        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4631
4632        Args:
4633            dtypes: the data types to compare this DataType to.
4634            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4635                If false, it means that NULLABLE<INT> is equivalent to INT.
4636
4637        Returns:
4638            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4639        """
4640        self_is_nullable = self.args.get("nullable")
4641        for dtype in dtypes:
4642            other_type = DataType.build(dtype, copy=False, udt=True)
4643            other_is_nullable = other_type.args.get("nullable")
4644            if (
4645                other_type.expressions
4646                or (check_nullable and (self_is_nullable or other_is_nullable))
4647                or self.this == DataType.Type.USERDEFINED
4648                or other_type.this == DataType.Type.USERDEFINED
4649            ):
4650                matches = self == other_type
4651            else:
4652                matches = self.this == other_type.this
4653
4654            if matches:
4655                return True
4656        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):
4365    class Type(AutoName):
4366        ARRAY = auto()
4367        AGGREGATEFUNCTION = auto()
4368        SIMPLEAGGREGATEFUNCTION = auto()
4369        BIGDECIMAL = auto()
4370        BIGINT = auto()
4371        BIGSERIAL = auto()
4372        BINARY = auto()
4373        BIT = auto()
4374        BOOLEAN = auto()
4375        BPCHAR = auto()
4376        CHAR = auto()
4377        DATE = auto()
4378        DATE32 = auto()
4379        DATEMULTIRANGE = auto()
4380        DATERANGE = auto()
4381        DATETIME = auto()
4382        DATETIME2 = auto()
4383        DATETIME64 = auto()
4384        DECIMAL = auto()
4385        DECIMAL32 = auto()
4386        DECIMAL64 = auto()
4387        DECIMAL128 = auto()
4388        DECIMAL256 = auto()
4389        DOUBLE = auto()
4390        DYNAMIC = auto()
4391        ENUM = auto()
4392        ENUM8 = auto()
4393        ENUM16 = auto()
4394        FIXEDSTRING = auto()
4395        FLOAT = auto()
4396        GEOGRAPHY = auto()
4397        GEOMETRY = auto()
4398        POINT = auto()
4399        RING = auto()
4400        LINESTRING = auto()
4401        MULTILINESTRING = auto()
4402        POLYGON = auto()
4403        MULTIPOLYGON = auto()
4404        HLLSKETCH = auto()
4405        HSTORE = auto()
4406        IMAGE = auto()
4407        INET = auto()
4408        INT = auto()
4409        INT128 = auto()
4410        INT256 = auto()
4411        INT4MULTIRANGE = auto()
4412        INT4RANGE = auto()
4413        INT8MULTIRANGE = auto()
4414        INT8RANGE = auto()
4415        INTERVAL = auto()
4416        IPADDRESS = auto()
4417        IPPREFIX = auto()
4418        IPV4 = auto()
4419        IPV6 = auto()
4420        JSON = auto()
4421        JSONB = auto()
4422        LIST = auto()
4423        LONGBLOB = auto()
4424        LONGTEXT = auto()
4425        LOWCARDINALITY = auto()
4426        MAP = auto()
4427        MEDIUMBLOB = auto()
4428        MEDIUMINT = auto()
4429        MEDIUMTEXT = auto()
4430        MONEY = auto()
4431        NAME = auto()
4432        NCHAR = auto()
4433        NESTED = auto()
4434        NULL = auto()
4435        NUMMULTIRANGE = auto()
4436        NUMRANGE = auto()
4437        NVARCHAR = auto()
4438        OBJECT = auto()
4439        RANGE = auto()
4440        ROWVERSION = auto()
4441        SERIAL = auto()
4442        SET = auto()
4443        SMALLDATETIME = auto()
4444        SMALLINT = auto()
4445        SMALLMONEY = auto()
4446        SMALLSERIAL = auto()
4447        STRUCT = auto()
4448        SUPER = auto()
4449        TEXT = auto()
4450        TINYBLOB = auto()
4451        TINYTEXT = auto()
4452        TIME = auto()
4453        TIMETZ = auto()
4454        TIMESTAMP = auto()
4455        TIMESTAMPNTZ = auto()
4456        TIMESTAMPLTZ = auto()
4457        TIMESTAMPTZ = auto()
4458        TIMESTAMP_S = auto()
4459        TIMESTAMP_MS = auto()
4460        TIMESTAMP_NS = auto()
4461        TINYINT = auto()
4462        TSMULTIRANGE = auto()
4463        TSRANGE = auto()
4464        TSTZMULTIRANGE = auto()
4465        TSTZRANGE = auto()
4466        UBIGINT = auto()
4467        UINT = auto()
4468        UINT128 = auto()
4469        UINT256 = auto()
4470        UMEDIUMINT = auto()
4471        UDECIMAL = auto()
4472        UNION = auto()
4473        UNIQUEIDENTIFIER = auto()
4474        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4475        USERDEFINED = "USER-DEFINED"
4476        USMALLINT = auto()
4477        UTINYINT = auto()
4478        UUID = auto()
4479        VARBINARY = auto()
4480        VARCHAR = auto()
4481        VARIANT = auto()
4482        VECTOR = auto()
4483        XML = auto()
4484        YEAR = auto()
4485        TDIGEST = auto()

An enumeration.

ARRAY = <Type.ARRAY: 'ARRAY'>
AGGREGATEFUNCTION = <Type.AGGREGATEFUNCTION: 'AGGREGATEFUNCTION'>
SIMPLEAGGREGATEFUNCTION = <Type.SIMPLEAGGREGATEFUNCTION: 'SIMPLEAGGREGATEFUNCTION'>
BIGDECIMAL = <Type.BIGDECIMAL: 'BIGDECIMAL'>
BIGINT = <Type.BIGINT: 'BIGINT'>
BIGSERIAL = <Type.BIGSERIAL: 'BIGSERIAL'>
BINARY = <Type.BINARY: 'BINARY'>
BIT = <Type.BIT: 'BIT'>
BOOLEAN = <Type.BOOLEAN: 'BOOLEAN'>
BPCHAR = <Type.BPCHAR: 'BPCHAR'>
CHAR = <Type.CHAR: 'CHAR'>
DATE = <Type.DATE: 'DATE'>
DATE32 = <Type.DATE32: 'DATE32'>
DATEMULTIRANGE = <Type.DATEMULTIRANGE: 'DATEMULTIRANGE'>
DATERANGE = <Type.DATERANGE: 'DATERANGE'>
DATETIME = <Type.DATETIME: 'DATETIME'>
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'>
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'>
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'>
UNION = <Type.UNION: 'UNION'>
UNIQUEIDENTIFIER = <Type.UNIQUEIDENTIFIER: 'UNIQUEIDENTIFIER'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
VECTOR = <Type.VECTOR: 'VECTOR'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4663class PseudoType(DataType):
4664    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4668class ObjectIdentifier(DataType):
4669    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4673class SubqueryPredicate(Predicate):
4674    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4677class All(SubqueryPredicate):
4678    pass
key = 'all'
class Any(SubqueryPredicate):
4681class Any(SubqueryPredicate):
4682    pass
key = 'any'
class Command(Expression):
4687class Command(Expression):
4688    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4691class Transaction(Expression):
4692    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4695class Commit(Expression):
4696    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4699class Rollback(Expression):
4700    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4703class Alter(Expression):
4704    arg_types = {
4705        "this": True,
4706        "kind": True,
4707        "actions": True,
4708        "exists": False,
4709        "only": False,
4710        "options": False,
4711        "cluster": False,
4712        "not_valid": False,
4713    }
4714
4715    @property
4716    def kind(self) -> t.Optional[str]:
4717        kind = self.args.get("kind")
4718        return kind and kind.upper()
4719
4720    @property
4721    def actions(self) -> t.List[Expression]:
4722        return self.args.get("actions") or []
arg_types = {'this': True, 'kind': True, 'actions': True, 'exists': False, 'only': False, 'options': False, 'cluster': False, 'not_valid': False}
kind: Optional[str]
4715    @property
4716    def kind(self) -> t.Optional[str]:
4717        kind = self.args.get("kind")
4718        return kind and kind.upper()
actions: List[Expression]
4720    @property
4721    def actions(self) -> t.List[Expression]:
4722        return self.args.get("actions") or []
key = 'alter'
class Analyze(Expression):
4725class Analyze(Expression):
4726    arg_types = {
4727        "kind": False,
4728        "this": False,
4729        "options": False,
4730        "mode": False,
4731        "partition": False,
4732        "expression": False,
4733        "properties": False,
4734    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4737class AnalyzeStatistics(Expression):
4738    arg_types = {
4739        "kind": True,
4740        "option": False,
4741        "this": False,
4742        "expressions": False,
4743    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4746class AnalyzeHistogram(Expression):
4747    arg_types = {
4748        "this": True,
4749        "expressions": True,
4750        "expression": False,
4751        "update_options": False,
4752    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4755class AnalyzeSample(Expression):
4756    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4759class AnalyzeListChainedRows(Expression):
4760    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4763class AnalyzeDelete(Expression):
4764    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4767class AnalyzeWith(Expression):
4768    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4771class AnalyzeValidate(Expression):
4772    arg_types = {
4773        "kind": True,
4774        "this": False,
4775        "expression": False,
4776    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4779class AnalyzeColumns(Expression):
4780    pass
key = 'analyzecolumns'
class UsingData(Expression):
4783class UsingData(Expression):
4784    pass
key = 'usingdata'
class AddConstraint(Expression):
4787class AddConstraint(Expression):
4788    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AttachOption(Expression):
4791class AttachOption(Expression):
4792    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
4795class DropPartition(Expression):
4796    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4800class ReplacePartition(Expression):
4801    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4805class Binary(Condition):
4806    arg_types = {"this": True, "expression": True}
4807
4808    @property
4809    def left(self) -> Expression:
4810        return self.this
4811
4812    @property
4813    def right(self) -> Expression:
4814        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4808    @property
4809    def left(self) -> Expression:
4810        return self.this
right: Expression
4812    @property
4813    def right(self) -> Expression:
4814        return self.expression
key = 'binary'
class Add(Binary):
4817class Add(Binary):
4818    pass
key = 'add'
class Connector(Binary):
4821class Connector(Binary):
4822    pass
key = 'connector'
class And(Connector):
4825class And(Connector):
4826    pass
key = 'and'
class Or(Connector):
4829class Or(Connector):
4830    pass
key = 'or'
class BitwiseAnd(Binary):
4833class BitwiseAnd(Binary):
4834    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4837class BitwiseLeftShift(Binary):
4838    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4841class BitwiseOr(Binary):
4842    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4845class BitwiseRightShift(Binary):
4846    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4849class BitwiseXor(Binary):
4850    pass
key = 'bitwisexor'
class Div(Binary):
4853class Div(Binary):
4854    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):
4857class Overlaps(Binary):
4858    pass
key = 'overlaps'
class Dot(Binary):
4861class Dot(Binary):
4862    @property
4863    def is_star(self) -> bool:
4864        return self.expression.is_star
4865
4866    @property
4867    def name(self) -> str:
4868        return self.expression.name
4869
4870    @property
4871    def output_name(self) -> str:
4872        return self.name
4873
4874    @classmethod
4875    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4876        """Build a Dot object with a sequence of expressions."""
4877        if len(expressions) < 2:
4878            raise ValueError("Dot requires >= 2 expressions.")
4879
4880        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4881
4882    @property
4883    def parts(self) -> t.List[Expression]:
4884        """Return the parts of a table / column in order catalog, db, table."""
4885        this, *parts = self.flatten()
4886
4887        parts.reverse()
4888
4889        for arg in COLUMN_PARTS:
4890            part = this.args.get(arg)
4891
4892            if isinstance(part, Expression):
4893                parts.append(part)
4894
4895        parts.reverse()
4896        return parts
is_star: bool
4862    @property
4863    def is_star(self) -> bool:
4864        return self.expression.is_star

Checks whether an expression is a star.

name: str
4866    @property
4867    def name(self) -> str:
4868        return self.expression.name
output_name: str
4870    @property
4871    def output_name(self) -> str:
4872        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:
4874    @classmethod
4875    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4876        """Build a Dot object with a sequence of expressions."""
4877        if len(expressions) < 2:
4878            raise ValueError("Dot requires >= 2 expressions.")
4879
4880        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]
4882    @property
4883    def parts(self) -> t.List[Expression]:
4884        """Return the parts of a table / column in order catalog, db, table."""
4885        this, *parts = self.flatten()
4886
4887        parts.reverse()
4888
4889        for arg in COLUMN_PARTS:
4890            part = this.args.get(arg)
4891
4892            if isinstance(part, Expression):
4893                parts.append(part)
4894
4895        parts.reverse()
4896        return parts

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

key = 'dot'
class DPipe(Binary):
4899class DPipe(Binary):
4900    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4903class EQ(Binary, Predicate):
4904    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4907class NullSafeEQ(Binary, Predicate):
4908    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4911class NullSafeNEQ(Binary, Predicate):
4912    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4916class PropertyEQ(Binary):
4917    pass
key = 'propertyeq'
class Distance(Binary):
4920class Distance(Binary):
4921    pass
key = 'distance'
class Escape(Binary):
4924class Escape(Binary):
4925    pass
key = 'escape'
class Glob(Binary, Predicate):
4928class Glob(Binary, Predicate):
4929    pass
key = 'glob'
class GT(Binary, Predicate):
4932class GT(Binary, Predicate):
4933    pass
key = 'gt'
class GTE(Binary, Predicate):
4936class GTE(Binary, Predicate):
4937    pass
key = 'gte'
class ILike(Binary, Predicate):
4940class ILike(Binary, Predicate):
4941    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4944class ILikeAny(Binary, Predicate):
4945    pass
key = 'ilikeany'
class IntDiv(Binary):
4948class IntDiv(Binary):
4949    pass
key = 'intdiv'
class Is(Binary, Predicate):
4952class Is(Binary, Predicate):
4953    pass
key = 'is'
class Kwarg(Binary):
4956class Kwarg(Binary):
4957    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4960class Like(Binary, Predicate):
4961    pass
key = 'like'
class LikeAny(Binary, Predicate):
4964class LikeAny(Binary, Predicate):
4965    pass
key = 'likeany'
class LT(Binary, Predicate):
4968class LT(Binary, Predicate):
4969    pass
key = 'lt'
class LTE(Binary, Predicate):
4972class LTE(Binary, Predicate):
4973    pass
key = 'lte'
class Mod(Binary):
4976class Mod(Binary):
4977    pass
key = 'mod'
class Mul(Binary):
4980class Mul(Binary):
4981    pass
key = 'mul'
class NEQ(Binary, Predicate):
4984class NEQ(Binary, Predicate):
4985    pass
key = 'neq'
class Operator(Binary):
4989class Operator(Binary):
4990    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
4993class SimilarTo(Binary, Predicate):
4994    pass
key = 'similarto'
class Slice(Binary):
4997class Slice(Binary):
4998    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5001class Sub(Binary):
5002    pass
key = 'sub'
class Unary(Condition):
5007class Unary(Condition):
5008    pass
key = 'unary'
class BitwiseNot(Unary):
5011class BitwiseNot(Unary):
5012    pass
key = 'bitwisenot'
class Not(Unary):
5015class Not(Unary):
5016    pass
key = 'not'
class Paren(Unary):
5019class Paren(Unary):
5020    @property
5021    def output_name(self) -> str:
5022        return self.this.name
output_name: str
5020    @property
5021    def output_name(self) -> str:
5022        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):
5025class Neg(Unary):
5026    def to_py(self) -> int | Decimal:
5027        if self.is_number:
5028            return self.this.to_py() * -1
5029        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5026    def to_py(self) -> int | Decimal:
5027        if self.is_number:
5028            return self.this.to_py() * -1
5029        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5032class Alias(Expression):
5033    arg_types = {"this": True, "alias": False}
5034
5035    @property
5036    def output_name(self) -> str:
5037        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5035    @property
5036    def output_name(self) -> str:
5037        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):
5042class PivotAlias(Alias):
5043    pass
key = 'pivotalias'
class PivotAny(Expression):
5048class PivotAny(Expression):
5049    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5052class Aliases(Expression):
5053    arg_types = {"this": True, "expressions": True}
5054
5055    @property
5056    def aliases(self):
5057        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5055    @property
5056    def aliases(self):
5057        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5061class AtIndex(Expression):
5062    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5065class AtTimeZone(Expression):
5066    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5069class FromTimeZone(Expression):
5070    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
5073class Between(Predicate):
5074    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5077class Bracket(Condition):
5078    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5079    arg_types = {
5080        "this": True,
5081        "expressions": True,
5082        "offset": False,
5083        "safe": False,
5084        "returns_list_for_maps": False,
5085    }
5086
5087    @property
5088    def output_name(self) -> str:
5089        if len(self.expressions) == 1:
5090            return self.expressions[0].output_name
5091
5092        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5087    @property
5088    def output_name(self) -> str:
5089        if len(self.expressions) == 1:
5090            return self.expressions[0].output_name
5091
5092        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):
5095class Distinct(Expression):
5096    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5099class In(Predicate):
5100    arg_types = {
5101        "this": True,
5102        "expressions": False,
5103        "query": False,
5104        "unnest": False,
5105        "field": False,
5106        "is_global": False,
5107    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5111class ForIn(Expression):
5112    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5115class TimeUnit(Expression):
5116    """Automatically converts unit arg into a var."""
5117
5118    arg_types = {"unit": False}
5119
5120    UNABBREVIATED_UNIT_NAME = {
5121        "D": "DAY",
5122        "H": "HOUR",
5123        "M": "MINUTE",
5124        "MS": "MILLISECOND",
5125        "NS": "NANOSECOND",
5126        "Q": "QUARTER",
5127        "S": "SECOND",
5128        "US": "MICROSECOND",
5129        "W": "WEEK",
5130        "Y": "YEAR",
5131    }
5132
5133    VAR_LIKE = (Column, Literal, Var)
5134
5135    def __init__(self, **args):
5136        unit = args.get("unit")
5137        if isinstance(unit, self.VAR_LIKE):
5138            args["unit"] = Var(
5139                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5140            )
5141        elif isinstance(unit, Week):
5142            unit.set("this", Var(this=unit.this.name.upper()))
5143
5144        super().__init__(**args)
5145
5146    @property
5147    def unit(self) -> t.Optional[Var | IntervalSpan]:
5148        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5135    def __init__(self, **args):
5136        unit = args.get("unit")
5137        if isinstance(unit, self.VAR_LIKE):
5138            args["unit"] = Var(
5139                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5140            )
5141        elif isinstance(unit, Week):
5142            unit.set("this", Var(this=unit.this.name.upper()))
5143
5144        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]
5146    @property
5147    def unit(self) -> t.Optional[Var | IntervalSpan]:
5148        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5151class IntervalOp(TimeUnit):
5152    arg_types = {"unit": False, "expression": True}
5153
5154    def interval(self):
5155        return Interval(
5156            this=self.expression.copy(),
5157            unit=self.unit.copy() if self.unit else None,
5158        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5154    def interval(self):
5155        return Interval(
5156            this=self.expression.copy(),
5157            unit=self.unit.copy() if self.unit else None,
5158        )
key = 'intervalop'
class IntervalSpan(DataType):
5164class IntervalSpan(DataType):
5165    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5168class Interval(TimeUnit):
5169    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5172class IgnoreNulls(Expression):
5173    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5176class RespectNulls(Expression):
5177    pass
key = 'respectnulls'
class HavingMax(Expression):
5181class HavingMax(Expression):
5182    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5186class Func(Condition):
5187    """
5188    The base class for all function expressions.
5189
5190    Attributes:
5191        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5192            treated as a variable length argument and the argument's value will be stored as a list.
5193        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5194            function expression. These values are used to map this node to a name during parsing as
5195            well as to provide the function's name during SQL string generation. By default the SQL
5196            name is set to the expression's class name transformed to snake case.
5197    """
5198
5199    is_var_len_args = False
5200
5201    @classmethod
5202    def from_arg_list(cls, args):
5203        if cls.is_var_len_args:
5204            all_arg_keys = list(cls.arg_types)
5205            # If this function supports variable length argument treat the last argument as such.
5206            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5207            num_non_var = len(non_var_len_arg_keys)
5208
5209            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5210            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5211        else:
5212            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5213
5214        return cls(**args_dict)
5215
5216    @classmethod
5217    def sql_names(cls):
5218        if cls is Func:
5219            raise NotImplementedError(
5220                "SQL name is only supported by concrete function implementations"
5221            )
5222        if "_sql_names" not in cls.__dict__:
5223            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5224        return cls._sql_names
5225
5226    @classmethod
5227    def sql_name(cls):
5228        return cls.sql_names()[0]
5229
5230    @classmethod
5231    def default_parser_mappings(cls):
5232        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):
5201    @classmethod
5202    def from_arg_list(cls, args):
5203        if cls.is_var_len_args:
5204            all_arg_keys = list(cls.arg_types)
5205            # If this function supports variable length argument treat the last argument as such.
5206            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5207            num_non_var = len(non_var_len_arg_keys)
5208
5209            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5210            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5211        else:
5212            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5213
5214        return cls(**args_dict)
@classmethod
def sql_names(cls):
5216    @classmethod
5217    def sql_names(cls):
5218        if cls is Func:
5219            raise NotImplementedError(
5220                "SQL name is only supported by concrete function implementations"
5221            )
5222        if "_sql_names" not in cls.__dict__:
5223            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5224        return cls._sql_names
@classmethod
def sql_name(cls):
5226    @classmethod
5227    def sql_name(cls):
5228        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5230    @classmethod
5231    def default_parser_mappings(cls):
5232        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5235class AggFunc(Func):
5236    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5239class ParameterizedAgg(AggFunc):
5240    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5243class Abs(Func):
5244    pass
key = 'abs'
class ArgMax(AggFunc):
5247class ArgMax(AggFunc):
5248    arg_types = {"this": True, "expression": True, "count": False}
5249    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5252class ArgMin(AggFunc):
5253    arg_types = {"this": True, "expression": True, "count": False}
5254    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5257class ApproxTopK(AggFunc):
5258    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5261class Flatten(Func):
5262    pass
key = 'flatten'
class Transform(Func):
5266class Transform(Func):
5267    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5270class Anonymous(Func):
5271    arg_types = {"this": True, "expressions": False}
5272    is_var_len_args = True
5273
5274    @property
5275    def name(self) -> str:
5276        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
5274    @property
5275    def name(self) -> str:
5276        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5279class AnonymousAggFunc(AggFunc):
5280    arg_types = {"this": True, "expressions": False}
5281    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5285class CombinedAggFunc(AnonymousAggFunc):
5286    arg_types = {"this": True, "expressions": False, "parts": True}
arg_types = {'this': True, 'expressions': False, 'parts': True}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5289class CombinedParameterizedAgg(ParameterizedAgg):
5290    arg_types = {"this": True, "expressions": True, "params": True, "parts": True}
arg_types = {'this': True, 'expressions': True, 'params': True, 'parts': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5295class Hll(AggFunc):
5296    arg_types = {"this": True, "expressions": False}
5297    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5300class ApproxDistinct(AggFunc):
5301    arg_types = {"this": True, "accuracy": False}
5302    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5305class Apply(Func):
5306    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5309class Array(Func):
5310    arg_types = {"expressions": False, "bracket_notation": False}
5311    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5315class ToArray(Func):
5316    pass
key = 'toarray'
class List(Func):
5320class List(Func):
5321    arg_types = {"expressions": False}
5322    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5326class Pad(Func):
5327    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):
5332class ToChar(Func):
5333    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5338class ToNumber(Func):
5339    arg_types = {
5340        "this": True,
5341        "format": False,
5342        "nlsparam": False,
5343        "precision": False,
5344        "scale": False,
5345    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5349class ToDouble(Func):
5350    arg_types = {
5351        "this": True,
5352        "format": False,
5353    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5356class Columns(Func):
5357    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5361class Convert(Func):
5362    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5365class ConvertTimezone(Func):
5366    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
arg_types = {'source_tz': False, 'target_tz': True, 'timestamp': True}
key = 'converttimezone'
class GenerateSeries(Func):
5369class GenerateSeries(Func):
5370    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):
5376class ExplodingGenerateSeries(GenerateSeries):
5377    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5380class ArrayAgg(AggFunc):
5381    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5384class ArrayUniqueAgg(AggFunc):
5385    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5388class ArrayAll(Func):
5389    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5393class ArrayAny(Func):
5394    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5397class ArrayConcat(Func):
5398    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5399    arg_types = {"this": True, "expressions": False}
5400    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5403class ArrayConstructCompact(Func):
5404    arg_types = {"expressions": True}
5405    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5408class ArrayContains(Binary, Func):
5409    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5412class ArrayContainsAll(Binary, Func):
5413    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5416class ArrayFilter(Func):
5417    arg_types = {"this": True, "expression": True}
5418    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5421class ArrayToString(Func):
5422    arg_types = {"this": True, "expression": True, "null": False}
5423    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5427class String(Func):
5428    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5431class StringToArray(Func):
5432    arg_types = {"this": True, "expression": True, "null": False}
5433    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5436class ArrayOverlaps(Binary, Func):
5437    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5440class ArraySize(Func):
5441    arg_types = {"this": True, "expression": False}
5442    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5445class ArraySort(Func):
5446    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5449class ArraySum(Func):
5450    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5453class ArrayUnionAgg(AggFunc):
5454    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5457class Avg(AggFunc):
5458    pass
key = 'avg'
class AnyValue(AggFunc):
5461class AnyValue(AggFunc):
5462    pass
key = 'anyvalue'
class Lag(AggFunc):
5465class Lag(AggFunc):
5466    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5469class Lead(AggFunc):
5470    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5475class First(AggFunc):
5476    pass
key = 'first'
class Last(AggFunc):
5479class Last(AggFunc):
5480    pass
key = 'last'
class FirstValue(AggFunc):
5483class FirstValue(AggFunc):
5484    pass
key = 'firstvalue'
class LastValue(AggFunc):
5487class LastValue(AggFunc):
5488    pass
key = 'lastvalue'
class NthValue(AggFunc):
5491class NthValue(AggFunc):
5492    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5495class Case(Func):
5496    arg_types = {"this": False, "ifs": True, "default": False}
5497
5498    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5499        instance = maybe_copy(self, copy)
5500        instance.append(
5501            "ifs",
5502            If(
5503                this=maybe_parse(condition, copy=copy, **opts),
5504                true=maybe_parse(then, copy=copy, **opts),
5505            ),
5506        )
5507        return instance
5508
5509    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5510        instance = maybe_copy(self, copy)
5511        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5512        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:
5498    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5499        instance = maybe_copy(self, copy)
5500        instance.append(
5501            "ifs",
5502            If(
5503                this=maybe_parse(condition, copy=copy, **opts),
5504                true=maybe_parse(then, copy=copy, **opts),
5505            ),
5506        )
5507        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5509    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5510        instance = maybe_copy(self, copy)
5511        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5512        return instance
key = 'case'
class Cast(Func):
5515class Cast(Func):
5516    arg_types = {
5517        "this": True,
5518        "to": True,
5519        "format": False,
5520        "safe": False,
5521        "action": False,
5522    }
5523
5524    @property
5525    def name(self) -> str:
5526        return self.this.name
5527
5528    @property
5529    def to(self) -> DataType:
5530        return self.args["to"]
5531
5532    @property
5533    def output_name(self) -> str:
5534        return self.name
5535
5536    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5537        """
5538        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5539        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5540        array<int> != array<float>.
5541
5542        Args:
5543            dtypes: the data types to compare this Cast's DataType to.
5544
5545        Returns:
5546            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5547        """
5548        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False}
name: str
5524    @property
5525    def name(self) -> str:
5526        return self.this.name
to: DataType
5528    @property
5529    def to(self) -> DataType:
5530        return self.args["to"]
output_name: str
5532    @property
5533    def output_name(self) -> str:
5534        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a")sqlglot.expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c")sqlglot.expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2")sqlglot.expressions[0].output_name
''
def is_type( self, *dtypes: Union[str, DataType, DataType.Type]) -> bool:
5536    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5537        """
5538        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5539        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5540        array<int> != array<float>.
5541
5542        Args:
5543            dtypes: the data types to compare this Cast's DataType to.
5544
5545        Returns:
5546            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5547        """
5548        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):
5551class TryCast(Cast):
5552    pass
key = 'trycast'
class Try(Func):
5555class Try(Func):
5556    pass
key = 'try'
class CastToStrType(Func):
5559class CastToStrType(Func):
5560    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5563class Collate(Binary, Func):
5564    pass
key = 'collate'
class Ceil(Func):
5567class Ceil(Func):
5568    arg_types = {"this": True, "decimals": False, "to": False}
5569    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5572class Coalesce(Func):
5573    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5574    is_var_len_args = True
5575    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5578class Chr(Func):
5579    arg_types = {"expressions": True, "charset": False}
5580    is_var_len_args = True
5581    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5584class Concat(Func):
5585    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5586    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5589class ConcatWs(Concat):
5590    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5593class Contains(Func):
5594    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5598class ConnectByRoot(Func):
5599    pass
key = 'connectbyroot'
class Count(AggFunc):
5602class Count(AggFunc):
5603    arg_types = {"this": False, "expressions": False, "big_int": False}
5604    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5607class CountIf(AggFunc):
5608    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5612class Cbrt(Func):
5613    pass
key = 'cbrt'
class CurrentDate(Func):
5616class CurrentDate(Func):
5617    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5620class CurrentDatetime(Func):
5621    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5624class CurrentTime(Func):
5625    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5628class CurrentTimestamp(Func):
5629    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentUser(Func):
5632class CurrentUser(Func):
5633    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5636class DateAdd(Func, IntervalOp):
5637    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateSub(Func, IntervalOp):
5640class DateSub(Func, IntervalOp):
5641    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5644class DateDiff(Func, TimeUnit):
5645    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5646    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5649class DateTrunc(Func):
5650    arg_types = {"unit": True, "this": True, "zone": False}
5651
5652    def __init__(self, **args):
5653        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5654        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5655        unabbreviate = args.pop("unabbreviate", True)
5656
5657        unit = args.get("unit")
5658        if isinstance(unit, TimeUnit.VAR_LIKE):
5659            unit_name = unit.name.upper()
5660            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5661                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5662
5663            args["unit"] = Literal.string(unit_name)
5664        elif isinstance(unit, Week):
5665            unit.set("this", Literal.string(unit.this.name.upper()))
5666
5667        super().__init__(**args)
5668
5669    @property
5670    def unit(self) -> Expression:
5671        return self.args["unit"]
DateTrunc(**args)
5652    def __init__(self, **args):
5653        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5654        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5655        unabbreviate = args.pop("unabbreviate", True)
5656
5657        unit = args.get("unit")
5658        if isinstance(unit, TimeUnit.VAR_LIKE):
5659            unit_name = unit.name.upper()
5660            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5661                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5662
5663            args["unit"] = Literal.string(unit_name)
5664        elif isinstance(unit, Week):
5665            unit.set("this", Literal.string(unit.this.name.upper()))
5666
5667        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5669    @property
5670    def unit(self) -> Expression:
5671        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5676class Datetime(Func):
5677    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5680class DatetimeAdd(Func, IntervalOp):
5681    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5684class DatetimeSub(Func, IntervalOp):
5685    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5688class DatetimeDiff(Func, TimeUnit):
5689    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5692class DatetimeTrunc(Func, TimeUnit):
5693    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5696class DayOfWeek(Func):
5697    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5702class DayOfWeekIso(Func):
5703    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5706class DayOfMonth(Func):
5707    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5710class DayOfYear(Func):
5711    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5714class ToDays(Func):
5715    pass
key = 'todays'
class WeekOfYear(Func):
5718class WeekOfYear(Func):
5719    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5722class MonthsBetween(Func):
5723    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5726class MakeInterval(Func):
5727    arg_types = {
5728        "year": False,
5729        "month": False,
5730        "day": False,
5731        "hour": False,
5732        "minute": False,
5733        "second": False,
5734    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5737class LastDay(Func, TimeUnit):
5738    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5739    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5742class Extract(Func):
5743    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5746class Exists(Func, SubqueryPredicate):
5747    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5750class Timestamp(Func):
5751    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5754class TimestampAdd(Func, TimeUnit):
5755    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5758class TimestampSub(Func, TimeUnit):
5759    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5762class TimestampDiff(Func, TimeUnit):
5763    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5764    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5767class TimestampTrunc(Func, TimeUnit):
5768    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5771class TimeAdd(Func, TimeUnit):
5772    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5775class TimeSub(Func, TimeUnit):
5776    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5779class TimeDiff(Func, TimeUnit):
5780    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5783class TimeTrunc(Func, TimeUnit):
5784    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5787class DateFromParts(Func):
5788    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5789    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5792class TimeFromParts(Func):
5793    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5794    arg_types = {
5795        "hour": True,
5796        "min": True,
5797        "sec": True,
5798        "nano": False,
5799        "fractions": False,
5800        "precision": False,
5801    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5804class DateStrToDate(Func):
5805    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5808class DateToDateStr(Func):
5809    pass
key = 'datetodatestr'
class DateToDi(Func):
5812class DateToDi(Func):
5813    pass
key = 'datetodi'
class Date(Func):
5817class Date(Func):
5818    arg_types = {"this": False, "zone": False, "expressions": False}
5819    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5822class Day(Func):
5823    pass
key = 'day'
class Decode(Func):
5826class Decode(Func):
5827    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5830class DiToDate(Func):
5831    pass
key = 'ditodate'
class Encode(Func):
5834class Encode(Func):
5835    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5838class Exp(Func):
5839    pass
key = 'exp'
class Explode(Func, UDTF):
5843class Explode(Func, UDTF):
5844    arg_types = {"this": True, "expressions": False}
5845    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5849class Inline(Func):
5850    pass
key = 'inline'
class ExplodeOuter(Explode):
5853class ExplodeOuter(Explode):
5854    pass
key = 'explodeouter'
class Posexplode(Explode):
5857class Posexplode(Explode):
5858    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5861class PosexplodeOuter(Posexplode, ExplodeOuter):
5862    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5865class Unnest(Func, UDTF):
5866    arg_types = {
5867        "expressions": True,
5868        "alias": False,
5869        "offset": False,
5870        "explode_array": False,
5871    }
5872
5873    @property
5874    def selects(self) -> t.List[Expression]:
5875        columns = super().selects
5876        offset = self.args.get("offset")
5877        if offset:
5878            columns = columns + [to_identifier("offset") if offset is True else offset]
5879        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5873    @property
5874    def selects(self) -> t.List[Expression]:
5875        columns = super().selects
5876        offset = self.args.get("offset")
5877        if offset:
5878            columns = columns + [to_identifier("offset") if offset is True else offset]
5879        return columns
key = 'unnest'
class Floor(Func):
5882class Floor(Func):
5883    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
5886class FromBase64(Func):
5887    pass
key = 'frombase64'
class FeaturesAtTime(Func):
5890class FeaturesAtTime(Func):
5891    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 ToBase64(Func):
5894class ToBase64(Func):
5895    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5899class FromISO8601Timestamp(Func):
5900    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5903class GapFill(Func):
5904    arg_types = {
5905        "this": True,
5906        "ts_column": True,
5907        "bucket_width": True,
5908        "partitioning_columns": False,
5909        "value_columns": False,
5910        "origin": False,
5911        "ignore_nulls": False,
5912    }
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):
5916class GenerateDateArray(Func):
5917    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5921class GenerateTimestampArray(Func):
5922    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5925class Greatest(Func):
5926    arg_types = {"this": True, "expressions": False}
5927    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
5932class OverflowTruncateBehavior(Expression):
5933    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
5936class GroupConcat(AggFunc):
5937    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
5940class Hex(Func):
5941    pass
key = 'hex'
class LowerHex(Hex):
5944class LowerHex(Hex):
5945    pass
key = 'lowerhex'
class Xor(Connector, Func):
5948class Xor(Connector, Func):
5949    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5952class If(Func):
5953    arg_types = {"this": True, "true": True, "false": False}
5954    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
5957class Nullif(Func):
5958    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
5961class Initcap(Func):
5962    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
5965class IsAscii(Func):
5966    pass
key = 'isascii'
class IsNan(Func):
5969class IsNan(Func):
5970    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
5974class Int64(Func):
5975    pass
key = 'int64'
class IsInf(Func):
5978class IsInf(Func):
5979    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
5983class JSON(Expression):
5984    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
5987class JSONPath(Expression):
5988    arg_types = {"expressions": True, "escape": False}
5989
5990    @property
5991    def output_name(self) -> str:
5992        last_segment = self.expressions[-1].this
5993        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
5990    @property
5991    def output_name(self) -> str:
5992        last_segment = self.expressions[-1].this
5993        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):
5996class JSONPathPart(Expression):
5997    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6000class JSONPathFilter(JSONPathPart):
6001    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6004class JSONPathKey(JSONPathPart):
6005    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6008class JSONPathRecursive(JSONPathPart):
6009    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6012class JSONPathRoot(JSONPathPart):
6013    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6016class JSONPathScript(JSONPathPart):
6017    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6020class JSONPathSlice(JSONPathPart):
6021    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6024class JSONPathSelector(JSONPathPart):
6025    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6028class JSONPathSubscript(JSONPathPart):
6029    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6032class JSONPathUnion(JSONPathPart):
6033    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6036class JSONPathWildcard(JSONPathPart):
6037    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6040class FormatJson(Expression):
6041    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6044class JSONKeyValue(Expression):
6045    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6048class JSONObject(Func):
6049    arg_types = {
6050        "expressions": False,
6051        "null_handling": False,
6052        "unique_keys": False,
6053        "return_type": False,
6054        "encoding": False,
6055    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6058class JSONObjectAgg(AggFunc):
6059    arg_types = {
6060        "expressions": False,
6061        "null_handling": False,
6062        "unique_keys": False,
6063        "return_type": False,
6064        "encoding": False,
6065    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONArray(Func):
6069class JSONArray(Func):
6070    arg_types = {
6071        "expressions": True,
6072        "null_handling": False,
6073        "return_type": False,
6074        "strict": False,
6075    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6079class JSONArrayAgg(Func):
6080    arg_types = {
6081        "this": True,
6082        "order": False,
6083        "null_handling": False,
6084        "return_type": False,
6085        "strict": False,
6086    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6089class JSONExists(Func):
6090    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):
6095class JSONColumnDef(Expression):
6096    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):
6099class JSONSchema(Expression):
6100    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6104class JSONValue(Expression):
6105    arg_types = {
6106        "this": True,
6107        "path": True,
6108        "returning": False,
6109        "on_condition": False,
6110    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6113class JSONValueArray(Func):
6114    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6118class JSONTable(Func):
6119    arg_types = {
6120        "this": True,
6121        "schema": True,
6122        "path": False,
6123        "error_handling": False,
6124        "empty_handling": False,
6125    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6129class ObjectInsert(Func):
6130    arg_types = {
6131        "this": True,
6132        "key": True,
6133        "value": True,
6134        "update_flag": False,
6135    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6138class OpenJSONColumnDef(Expression):
6139    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):
6142class OpenJSON(Func):
6143    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6146class JSONBContains(Binary, Func):
6147    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6150class JSONBExists(Func):
6151    arg_types = {"this": True, "path": True}
6152    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6155class JSONExtract(Binary, Func):
6156    arg_types = {
6157        "this": True,
6158        "expression": True,
6159        "only_json_types": False,
6160        "expressions": False,
6161        "variant_extract": False,
6162        "json_query": False,
6163        "option": False,
6164        "quote": False,
6165    }
6166    _sql_names = ["JSON_EXTRACT"]
6167    is_var_len_args = True
6168
6169    @property
6170    def output_name(self) -> str:
6171        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}
is_var_len_args = True
output_name: str
6169    @property
6170    def output_name(self) -> str:
6171        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):
6175class JSONExtractQuote(Expression):
6176    arg_types = {
6177        "option": True,
6178        "scalar": False,
6179    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6182class JSONExtractArray(Func):
6183    arg_types = {"this": True, "expression": False}
6184    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6187class JSONExtractScalar(Binary, Func):
6188    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6189    _sql_names = ["JSON_EXTRACT_SCALAR"]
6190    is_var_len_args = True
6191
6192    @property
6193    def output_name(self) -> str:
6194        return self.expression.output_name
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False}
is_var_len_args = True
output_name: str
6192    @property
6193    def output_name(self) -> str:
6194        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):
6197class JSONBExtract(Binary, Func):
6198    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6201class JSONBExtractScalar(Binary, Func):
6202    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6205class JSONFormat(Func):
6206    arg_types = {"this": False, "options": False}
6207    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6211class JSONArrayContains(Binary, Predicate, Func):
6212    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6215class ParseJSON(Func):
6216    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6217    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6218    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6219    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6222class Least(Func):
6223    arg_types = {"this": True, "expressions": False}
6224    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6227class Left(Func):
6228    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6235class Length(Func):
6236    arg_types = {"this": True, "binary": False, "encoding": False}
6237    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6240class Levenshtein(Func):
6241    arg_types = {
6242        "this": True,
6243        "expression": False,
6244        "ins_cost": False,
6245        "del_cost": False,
6246        "sub_cost": False,
6247        "max_dist": False,
6248    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6251class Ln(Func):
6252    pass
key = 'ln'
class Log(Func):
6255class Log(Func):
6256    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6259class LogicalOr(AggFunc):
6260    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6263class LogicalAnd(AggFunc):
6264    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6267class Lower(Func):
6268    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6271class Map(Func):
6272    arg_types = {"keys": False, "values": False}
6273
6274    @property
6275    def keys(self) -> t.List[Expression]:
6276        keys = self.args.get("keys")
6277        return keys.expressions if keys else []
6278
6279    @property
6280    def values(self) -> t.List[Expression]:
6281        values = self.args.get("values")
6282        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6274    @property
6275    def keys(self) -> t.List[Expression]:
6276        keys = self.args.get("keys")
6277        return keys.expressions if keys else []
values: List[Expression]
6279    @property
6280    def values(self) -> t.List[Expression]:
6281        values = self.args.get("values")
6282        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6286class ToMap(Func):
6287    pass
key = 'tomap'
class MapFromEntries(Func):
6290class MapFromEntries(Func):
6291    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6295class ScopeResolution(Expression):
6296    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6299class Stream(Expression):
6300    pass
key = 'stream'
class StarMap(Func):
6303class StarMap(Func):
6304    pass
key = 'starmap'
class VarMap(Func):
6307class VarMap(Func):
6308    arg_types = {"keys": True, "values": True}
6309    is_var_len_args = True
6310
6311    @property
6312    def keys(self) -> t.List[Expression]:
6313        return self.args["keys"].expressions
6314
6315    @property
6316    def values(self) -> t.List[Expression]:
6317        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6311    @property
6312    def keys(self) -> t.List[Expression]:
6313        return self.args["keys"].expressions
values: List[Expression]
6315    @property
6316    def values(self) -> t.List[Expression]:
6317        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6321class MatchAgainst(Func):
6322    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6325class Max(AggFunc):
6326    arg_types = {"this": True, "expressions": False}
6327    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6330class MD5(Func):
6331    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6335class MD5Digest(Func):
6336    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6339class Median(AggFunc):
6340    pass
key = 'median'
class Min(AggFunc):
6343class Min(AggFunc):
6344    arg_types = {"this": True, "expressions": False}
6345    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6348class Month(Func):
6349    pass
key = 'month'
class AddMonths(Func):
6352class AddMonths(Func):
6353    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6356class Nvl2(Func):
6357    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6360class Normalize(Func):
6361    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6364class Overlay(Func):
6365    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):
6369class Predict(Func):
6370    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6373class Pow(Binary, Func):
6374    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6377class PercentileCont(AggFunc):
6378    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6381class PercentileDisc(AggFunc):
6382    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6385class Quantile(AggFunc):
6386    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6389class ApproxQuantile(Quantile):
6390    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
arg_types = {'this': True, 'quantile': True, 'accuracy': False, 'weight': False}
key = 'approxquantile'
class Quarter(Func):
6393class Quarter(Func):
6394    pass
key = 'quarter'
class Rand(Func):
6399class Rand(Func):
6400    _sql_names = ["RAND", "RANDOM"]
6401    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6404class Randn(Func):
6405    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6408class RangeN(Func):
6409    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6412class ReadCSV(Func):
6413    _sql_names = ["READ_CSV"]
6414    is_var_len_args = True
6415    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6418class Reduce(Func):
6419    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):
6422class RegexpExtract(Func):
6423    arg_types = {
6424        "this": True,
6425        "expression": True,
6426        "position": False,
6427        "occurrence": False,
6428        "parameters": False,
6429        "group": False,
6430    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6433class RegexpExtractAll(Func):
6434    arg_types = {
6435        "this": True,
6436        "expression": True,
6437        "position": False,
6438        "occurrence": False,
6439        "parameters": False,
6440        "group": False,
6441    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6444class RegexpReplace(Func):
6445    arg_types = {
6446        "this": True,
6447        "expression": True,
6448        "replacement": False,
6449        "position": False,
6450        "occurrence": False,
6451        "modifiers": False,
6452    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6455class RegexpLike(Binary, Func):
6456    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6459class RegexpILike(Binary, Func):
6460    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6465class RegexpSplit(Func):
6466    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6469class Repeat(Func):
6470    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6475class Round(Func):
6476    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6479class RowNumber(Func):
6480    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6483class SafeDivide(Func):
6484    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6487class SHA(Func):
6488    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6491class SHA2(Func):
6492    _sql_names = ["SHA2"]
6493    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6496class Sign(Func):
6497    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6500class SortArray(Func):
6501    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6504class Split(Func):
6505    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6509class SplitPart(Func):
6510    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6515class Substring(Func):
6516    _sql_names = ["SUBSTRING", "SUBSTR"]
6517    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6520class StandardHash(Func):
6521    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6524class StartsWith(Func):
6525    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6526    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6529class StrPosition(Func):
6530    arg_types = {
6531        "this": True,
6532        "substr": True,
6533        "position": False,
6534        "occurrence": False,
6535    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6538class StrToDate(Func):
6539    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6542class StrToTime(Func):
6543    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):
6548class StrToUnix(Func):
6549    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6554class StrToMap(Func):
6555    arg_types = {
6556        "this": True,
6557        "pair_delim": False,
6558        "key_value_delim": False,
6559        "duplicate_resolution_callback": False,
6560    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6563class NumberToStr(Func):
6564    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6567class FromBase(Func):
6568    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6571class Struct(Func):
6572    arg_types = {"expressions": False}
6573    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6576class StructExtract(Func):
6577    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6582class Stuff(Func):
6583    _sql_names = ["STUFF", "INSERT"]
6584    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):
6587class Sum(AggFunc):
6588    pass
key = 'sum'
class Sqrt(Func):
6591class Sqrt(Func):
6592    pass
key = 'sqrt'
class Stddev(AggFunc):
6595class Stddev(AggFunc):
6596    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6599class StddevPop(AggFunc):
6600    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6603class StddevSamp(AggFunc):
6604    pass
key = 'stddevsamp'
class Time(Func):
6608class Time(Func):
6609    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6612class TimeToStr(Func):
6613    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):
6616class TimeToTimeStr(Func):
6617    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6620class TimeToUnix(Func):
6621    pass
key = 'timetounix'
class TimeStrToDate(Func):
6624class TimeStrToDate(Func):
6625    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6628class TimeStrToTime(Func):
6629    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6632class TimeStrToUnix(Func):
6633    pass
key = 'timestrtounix'
class Trim(Func):
6636class Trim(Func):
6637    arg_types = {
6638        "this": True,
6639        "expression": False,
6640        "position": False,
6641        "collation": False,
6642    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6645class TsOrDsAdd(Func, TimeUnit):
6646    # return_type is used to correctly cast the arguments of this expression when transpiling it
6647    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6648
6649    @property
6650    def return_type(self) -> DataType:
6651        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
6649    @property
6650    def return_type(self) -> DataType:
6651        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6654class TsOrDsDiff(Func, TimeUnit):
6655    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6658class TsOrDsToDateStr(Func):
6659    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6662class TsOrDsToDate(Func):
6663    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6666class TsOrDsToDatetime(Func):
6667    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6670class TsOrDsToTime(Func):
6671    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6674class TsOrDsToTimestamp(Func):
6675    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6678class TsOrDiToDi(Func):
6679    pass
key = 'tsorditodi'
class Unhex(Func):
6682class Unhex(Func):
6683    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6686class Unicode(Func):
6687    pass
key = 'unicode'
class UnixDate(Func):
6691class UnixDate(Func):
6692    pass
key = 'unixdate'
class UnixToStr(Func):
6695class UnixToStr(Func):
6696    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6701class UnixToTime(Func):
6702    arg_types = {
6703        "this": True,
6704        "scale": False,
6705        "zone": False,
6706        "hours": False,
6707        "minutes": False,
6708        "format": False,
6709    }
6710
6711    SECONDS = Literal.number(0)
6712    DECIS = Literal.number(1)
6713    CENTIS = Literal.number(2)
6714    MILLIS = Literal.number(3)
6715    DECIMILLIS = Literal.number(4)
6716    CENTIMILLIS = Literal.number(5)
6717    MICROS = Literal.number(6)
6718    DECIMICROS = Literal.number(7)
6719    CENTIMICROS = Literal.number(8)
6720    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):
6723class UnixToTimeStr(Func):
6724    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6727class UnixSeconds(Func):
6728    pass
key = 'unixseconds'
class Uuid(Func):
6731class Uuid(Func):
6732    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6733
6734    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6737class TimestampFromParts(Func):
6738    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6739    arg_types = {
6740        "year": True,
6741        "month": True,
6742        "day": True,
6743        "hour": True,
6744        "min": True,
6745        "sec": True,
6746        "nano": False,
6747        "zone": False,
6748        "milli": False,
6749    }
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):
6752class Upper(Func):
6753    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6756class Corr(Binary, AggFunc):
6757    pass
key = 'corr'
class Variance(AggFunc):
6760class Variance(AggFunc):
6761    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6764class VariancePop(AggFunc):
6765    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6768class CovarSamp(Binary, AggFunc):
6769    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6772class CovarPop(Binary, AggFunc):
6773    pass
key = 'covarpop'
class Week(Func):
6776class Week(Func):
6777    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6780class XMLElement(Func):
6781    _sql_names = ["XMLELEMENT"]
6782    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6785class XMLTable(Func):
6786    arg_types = {
6787        "this": True,
6788        "namespaces": False,
6789        "passing": False,
6790        "columns": False,
6791        "by_ref": False,
6792    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6795class XMLNamespace(Expression):
6796    pass
key = 'xmlnamespace'
class Year(Func):
6799class Year(Func):
6800    pass
key = 'year'
class Use(Expression):
6803class Use(Expression):
6804    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'use'
class Merge(DML):
6807class Merge(DML):
6808    arg_types = {
6809        "this": True,
6810        "using": True,
6811        "on": True,
6812        "whens": True,
6813        "with": False,
6814        "returning": False,
6815    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6818class When(Expression):
6819    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):
6822class Whens(Expression):
6823    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6824
6825    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
6830class NextValueFor(Func):
6831    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6836class Semicolon(Expression):
6837    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'AnonymousAggFunc'>, <class 'AnyValue'>, <class 'Apply'>, <class 'ApproxDistinct'>, <class 'ApproxQuantile'>, <class 'ApproxTopK'>, <class 'ArgMax'>, <class 'ArgMin'>, <class 'Array'>, <class 'ArrayAgg'>, <class 'ArrayAll'>, <class 'ArrayAny'>, <class 'ArrayConcat'>, <class 'ArrayConstructCompact'>, <class 'ArrayContains'>, <class 'ArrayContainsAll'>, <class 'ArrayFilter'>, <class 'ArrayOverlaps'>, <class 'ArraySize'>, <class 'ArraySort'>, <class 'ArraySum'>, <class 'ArrayToString'>, <class 'ArrayUnionAgg'>, <class 'ArrayUniqueAgg'>, <class 'Avg'>, <class 'Case'>, <class 'Cast'>, <class 'CastToStrType'>, <class 'Cbrt'>, <class 'Ceil'>, <class 'Chr'>, <class 'Coalesce'>, <class 'Collate'>, <class 'Columns'>, <class 'CombinedAggFunc'>, <class 'CombinedParameterizedAgg'>, <class 'Concat'>, <class 'ConcatWs'>, <class 'ConnectByRoot'>, <class 'Contains'>, <class 'Convert'>, <class 'ConvertTimezone'>, <class 'Corr'>, <class 'Count'>, <class 'CountIf'>, <class 'CovarPop'>, <class 'CovarSamp'>, <class 'CurrentDate'>, <class 'CurrentDatetime'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateDiff'>, <class 'DateFromParts'>, <class 'DateStrToDate'>, <class 'DateSub'>, <class 'DateToDateStr'>, <class 'DateToDi'>, <class 'DateTrunc'>, <class 'Datetime'>, <class 'DatetimeAdd'>, <class 'DatetimeDiff'>, <class 'DatetimeSub'>, <class 'DatetimeTrunc'>, <class 'Day'>, <class 'DayOfMonth'>, <class 'DayOfWeek'>, <class 'DayOfWeekIso'>, <class 'DayOfYear'>, <class 'Decode'>, <class 'DiToDate'>, <class 'Encode'>, <class 'Exists'>, <class 'Exp'>, <class 'Explode'>, <class 'ExplodeOuter'>, <class 'ExplodingGenerateSeries'>, <class 'Extract'>, <class 'FeaturesAtTime'>, <class 'First'>, <class 'FirstValue'>, <class 'Flatten'>, <class 'Floor'>, <class 'FromBase'>, <class 'FromBase64'>, <class 'FromISO8601Timestamp'>, <class 'GapFill'>, <class 'GenerateDateArray'>, <class 'GenerateSeries'>, <class 'GenerateTimestampArray'>, <class 'Greatest'>, <class 'GroupConcat'>, <class 'Hex'>, <class 'Hll'>, <class 'If'>, <class 'Initcap'>, <class 'Inline'>, <class 'Int64'>, <class 'IsAscii'>, <class 'IsInf'>, <class 'IsNan'>, <class 'JSONArray'>, <class 'JSONArrayAgg'>, <class 'JSONArrayContains'>, <class 'JSONBContains'>, <class 'JSONBExists'>, <class 'JSONBExtract'>, <class 'JSONBExtractScalar'>, <class 'JSONExists'>, <class 'JSONExtract'>, <class 'JSONExtractArray'>, <class 'JSONExtractScalar'>, <class 'JSONFormat'>, <class 'JSONObject'>, <class 'JSONObjectAgg'>, <class 'JSONTable'>, <class 'JSONValueArray'>, <class 'Lag'>, <class 'Last'>, <class 'LastDay'>, <class 'LastValue'>, <class 'Lead'>, <class 'Least'>, <class 'Left'>, <class 'Length'>, <class 'Levenshtein'>, <class 'List'>, <class 'Ln'>, <class 'Log'>, <class 'LogicalAnd'>, <class 'LogicalOr'>, <class 'Lower'>, <class 'LowerHex'>, <class 'MD5'>, <class 'MD5Digest'>, <class 'MakeInterval'>, <class 'Map'>, <class 'MapFromEntries'>, <class 'MatchAgainst'>, <class 'Max'>, <class 'Median'>, <class 'Min'>, <class 'Month'>, <class 'MonthsBetween'>, <class 'NextValueFor'>, <class 'Normalize'>, <class 'NthValue'>, <class 'Nullif'>, <class 'NumberToStr'>, <class 'Nvl2'>, <class 'ObjectInsert'>, <class 'OpenJSON'>, <class 'Overlay'>, <class 'Pad'>, <class 'ParameterizedAgg'>, <class 'ParseJSON'>, <class 'PercentileCont'>, <class 'PercentileDisc'>, <class 'Posexplode'>, <class 'PosexplodeOuter'>, <class 'Pow'>, <class 'Predict'>, <class 'Quantile'>, <class 'Quarter'>, <class 'Rand'>, <class 'Randn'>, <class 'RangeN'>, <class 'ReadCSV'>, <class 'Reduce'>, <class 'RegexpExtract'>, <class 'RegexpExtractAll'>, <class 'RegexpILike'>, <class 'RegexpLike'>, <class 'RegexpReplace'>, <class 'RegexpSplit'>, <class 'Repeat'>, <class 'Right'>, <class 'Round'>, <class 'RowNumber'>, <class 'SHA'>, <class 'SHA2'>, <class 'SafeDivide'>, <class 'Sign'>, <class 'SortArray'>, <class 'Split'>, <class 'SplitPart'>, <class 'Sqrt'>, <class 'StandardHash'>, <class 'StarMap'>, <class 'StartsWith'>, <class 'Stddev'>, <class 'StddevPop'>, <class 'StddevSamp'>, <class 'StrPosition'>, <class 'StrToDate'>, <class 'StrToMap'>, <class 'StrToTime'>, <class 'StrToUnix'>, <class 'String'>, <class 'StringToArray'>, <class 'Struct'>, <class 'StructExtract'>, <class 'Stuff'>, <class 'Substring'>, <class 'Sum'>, <class 'Time'>, <class 'TimeAdd'>, <class 'TimeDiff'>, <class 'TimeFromParts'>, <class 'TimeStrToDate'>, <class 'TimeStrToTime'>, <class 'TimeStrToUnix'>, <class 'TimeSub'>, <class 'TimeToStr'>, <class 'TimeToTimeStr'>, <class 'TimeToUnix'>, <class 'TimeTrunc'>, <class 'Timestamp'>, <class 'TimestampAdd'>, <class 'TimestampDiff'>, <class 'TimestampFromParts'>, <class 'TimestampSub'>, <class 'TimestampTrunc'>, <class 'ToArray'>, <class 'ToBase64'>, <class 'ToChar'>, <class 'ToDays'>, <class 'ToDouble'>, <class 'ToMap'>, <class 'ToNumber'>, <class 'Transform'>, <class 'Trim'>, <class 'Try'>, <class 'TryCast'>, <class 'TsOrDiToDi'>, <class 'TsOrDsAdd'>, <class 'TsOrDsDiff'>, <class 'TsOrDsToDate'>, <class 'TsOrDsToDateStr'>, <class 'TsOrDsToDatetime'>, <class 'TsOrDsToTime'>, <class 'TsOrDsToTimestamp'>, <class 'Unhex'>, <class 'Unicode'>, <class 'UnixDate'>, <class 'UnixSeconds'>, <class 'UnixToStr'>, <class 'UnixToTime'>, <class 'UnixToTimeStr'>, <class 'Unnest'>, <class 'Upper'>, <class 'Uuid'>, <class 'VarMap'>, <class 'Variance'>, <class 'VariancePop'>, <class 'Week'>, <class 'WeekOfYear'>, <class 'XMLElement'>, <class 'XMLTable'>, <class 'Xor'>, <class 'Year'>]
FUNCTION_BY_NAME = {'ABS': <class 'Abs'>, 'ADD_MONTHS': <class 'AddMonths'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPLY': <class 'Apply'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_TOP_K': <class 'ApproxTopK'>, 'ARG_MAX': <class 'ArgMax'>, 'ARGMAX': <class 'ArgMax'>, 'MAX_BY': <class 'ArgMax'>, 'ARG_MIN': <class 'ArgMin'>, 'ARGMIN': <class 'ArgMin'>, 'MIN_BY': <class 'ArgMin'>, 'ARRAY': <class 'Array'>, 'ARRAY_AGG': <class 'ArrayAgg'>, 'ARRAY_ALL': <class 'ArrayAll'>, 'ARRAY_ANY': <class 'ArrayAny'>, 'ARRAY_CONCAT': <class 'ArrayConcat'>, 'ARRAY_CAT': <class 'ArrayConcat'>, 'ARRAY_CONSTRUCT_COMPACT': <class 'ArrayConstructCompact'>, 'ARRAY_CONTAINS': <class 'ArrayContains'>, 'ARRAY_HAS': <class 'ArrayContains'>, 'ARRAY_CONTAINS_ALL': <class 'ArrayContainsAll'>, 'ARRAY_HAS_ALL': <class 'ArrayContainsAll'>, 'FILTER': <class 'ArrayFilter'>, 'ARRAY_FILTER': <class 'ArrayFilter'>, 'ARRAY_OVERLAPS': <class 'ArrayOverlaps'>, 'ARRAY_SIZE': <class 'ArraySize'>, 'ARRAY_LENGTH': <class 'ArraySize'>, 'ARRAY_SORT': <class 'ArraySort'>, 'ARRAY_SUM': <class 'ArraySum'>, 'ARRAY_TO_STRING': <class 'ArrayToString'>, 'ARRAY_JOIN': <class 'ArrayToString'>, 'ARRAY_UNION_AGG': <class 'ArrayUnionAgg'>, 'ARRAY_UNIQUE_AGG': <class 'ArrayUniqueAgg'>, 'AVG': <class 'Avg'>, 'CASE': <class 'Case'>, 'CAST': <class 'Cast'>, 'CAST_TO_STR_TYPE': <class 'CastToStrType'>, 'CBRT': <class 'Cbrt'>, 'CEIL': <class 'Ceil'>, 'CEILING': <class 'Ceil'>, 'CHR': <class 'Chr'>, 'CHAR': <class 'Chr'>, 'COALESCE': <class 'Coalesce'>, 'IFNULL': <class 'Coalesce'>, 'NVL': <class 'Coalesce'>, 'COLLATE': <class 'Collate'>, 'COLUMNS': <class 'Columns'>, 'COMBINED_AGG_FUNC': <class 'CombinedAggFunc'>, 'COMBINED_PARAMETERIZED_AGG': <class 'CombinedParameterizedAgg'>, 'CONCAT': <class 'Concat'>, 'CONCAT_WS': <class 'ConcatWs'>, 'CONNECT_BY_ROOT': <class 'ConnectByRoot'>, 'CONTAINS': <class 'Contains'>, 'CONVERT': <class 'Convert'>, 'CONVERT_TIMEZONE': <class 'ConvertTimezone'>, 'CORR': <class 'Corr'>, 'COUNT': <class 'Count'>, 'COUNT_IF': <class 'CountIf'>, 'COUNTIF': <class 'CountIf'>, 'COVAR_POP': <class 'CovarPop'>, 'COVAR_SAMP': <class 'CovarSamp'>, 'CURRENT_DATE': <class 'CurrentDate'>, 'CURRENT_DATETIME': <class 'CurrentDatetime'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_STR_TO_DATE': <class 'DateStrToDate'>, 'DATE_SUB': <class 'DateSub'>, 'DATE_TO_DATE_STR': <class 'DateToDateStr'>, 'DATE_TO_DI': <class 'DateToDi'>, 'DATE_TRUNC': <class 'DateTrunc'>, 'DATETIME': <class 'Datetime'>, 'DATETIME_ADD': <class 'DatetimeAdd'>, 'DATETIME_DIFF': <class 'DatetimeDiff'>, 'DATETIME_SUB': <class 'DatetimeSub'>, 'DATETIME_TRUNC': <class 'DatetimeTrunc'>, 'DAY': <class 'Day'>, 'DAY_OF_MONTH': <class 'DayOfMonth'>, 'DAYOFMONTH': <class 'DayOfMonth'>, 'DAY_OF_WEEK': <class 'DayOfWeek'>, 'DAYOFWEEK': <class 'DayOfWeek'>, 'DAYOFWEEK_ISO': <class 'DayOfWeekIso'>, 'ISODOW': <class 'DayOfWeekIso'>, 'DAY_OF_YEAR': <class 'DayOfYear'>, 'DAYOFYEAR': <class 'DayOfYear'>, 'DECODE': <class 'Decode'>, 'DI_TO_DATE': <class 'DiToDate'>, 'ENCODE': <class 'Encode'>, 'EXISTS': <class 'Exists'>, 'EXP': <class 'Exp'>, 'EXPLODE': <class 'Explode'>, 'EXPLODE_OUTER': <class 'ExplodeOuter'>, 'EXPLODING_GENERATE_SERIES': <class 'ExplodingGenerateSeries'>, 'EXTRACT': <class 'Extract'>, 'FEATURES_AT_TIME': <class 'FeaturesAtTime'>, 'FIRST': <class 'First'>, 'FIRST_VALUE': <class 'FirstValue'>, 'FLATTEN': <class 'Flatten'>, 'FLOOR': <class 'Floor'>, 'FROM_BASE': <class 'FromBase'>, 'FROM_BASE64': <class 'FromBase64'>, 'FROM_ISO8601_TIMESTAMP': <class 'FromISO8601Timestamp'>, 'GAP_FILL': <class 'GapFill'>, 'GENERATE_DATE_ARRAY': <class 'GenerateDateArray'>, 'GENERATE_SERIES': <class 'GenerateSeries'>, 'GENERATE_TIMESTAMP_ARRAY': <class 'GenerateTimestampArray'>, 'GREATEST': <class 'Greatest'>, 'GROUP_CONCAT': <class 'GroupConcat'>, 'HEX': <class 'Hex'>, 'HLL': <class 'Hll'>, 'IF': <class 'If'>, 'IIF': <class 'If'>, 'INITCAP': <class 'Initcap'>, 'INLINE': <class 'Inline'>, '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_CONTAINS': <class 'JSONArrayContains'>, 'JSONB_CONTAINS': <class 'JSONBContains'>, 'JSONB_EXISTS': <class 'JSONBExists'>, 'JSONB_EXTRACT': <class 'JSONBExtract'>, 'JSONB_EXTRACT_SCALAR': <class 'JSONBExtractScalar'>, '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_OBJECT': <class 'JSONObject'>, 'J_S_O_N_OBJECT_AGG': <class 'JSONObjectAgg'>, 'J_S_O_N_TABLE': <class 'JSONTable'>, 'J_S_O_N_VALUE_ARRAY': <class 'JSONValueArray'>, 'LAG': <class 'Lag'>, 'LAST': <class 'Last'>, 'LAST_DAY': <class 'LastDay'>, 'LAST_DAY_OF_MONTH': <class 'LastDay'>, 'LAST_VALUE': <class 'LastValue'>, 'LEAD': <class 'Lead'>, 'LEAST': <class 'Least'>, 'LEFT': <class 'Left'>, 'LENGTH': <class 'Length'>, 'LEN': <class 'Length'>, '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'>, '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'>, 'NULLIF': <class 'Nullif'>, 'NUMBER_TO_STR': <class 'NumberToStr'>, 'NVL2': <class 'Nvl2'>, 'OBJECT_INSERT': <class 'ObjectInsert'>, 'OPEN_J_S_O_N': <class 'OpenJSON'>, 'OVERLAY': <class 'Overlay'>, 'PAD': <class 'Pad'>, 'PARAMETERIZED_AGG': <class 'ParameterizedAgg'>, 'PARSE_JSON': <class 'ParseJSON'>, 'JSON_PARSE': <class 'ParseJSON'>, 'PERCENTILE_CONT': <class 'PercentileCont'>, 'PERCENTILE_DISC': <class 'PercentileDisc'>, 'POSEXPLODE': <class 'Posexplode'>, 'POSEXPLODE_OUTER': <class 'PosexplodeOuter'>, 'POWER': <class 'Pow'>, 'POW': <class 'Pow'>, 'PREDICT': <class 'Predict'>, 'QUANTILE': <class 'Quantile'>, 'QUARTER': <class 'Quarter'>, 'RAND': <class 'Rand'>, 'RANDOM': <class 'Rand'>, 'RANDN': <class 'Randn'>, 'RANGE_N': <class 'RangeN'>, 'READ_CSV': <class 'ReadCSV'>, 'REDUCE': <class 'Reduce'>, 'REGEXP_EXTRACT': <class 'RegexpExtract'>, 'REGEXP_EXTRACT_ALL': <class 'RegexpExtractAll'>, 'REGEXP_I_LIKE': <class 'RegexpILike'>, 'REGEXP_LIKE': <class 'RegexpLike'>, 'REGEXP_REPLACE': <class 'RegexpReplace'>, 'REGEXP_SPLIT': <class 'RegexpSplit'>, 'REPEAT': <class 'Repeat'>, 'RIGHT': <class 'Right'>, 'ROUND': <class 'Round'>, 'ROW_NUMBER': <class 'RowNumber'>, 'SHA': <class 'SHA'>, 'SHA1': <class 'SHA'>, 'SHA2': <class 'SHA2'>, 'SAFE_DIVIDE': <class 'SafeDivide'>, 'SIGN': <class 'Sign'>, 'SIGNUM': <class 'Sign'>, 'SORT_ARRAY': <class 'SortArray'>, 'SPLIT': <class 'Split'>, 'SPLIT_PART': <class 'SplitPart'>, 'SQRT': <class 'Sqrt'>, 'STANDARD_HASH': <class 'StandardHash'>, 'STAR_MAP': <class 'StarMap'>, 'STARTS_WITH': <class 'StartsWith'>, 'STARTSWITH': <class 'StartsWith'>, 'STDDEV': <class 'Stddev'>, 'STDEV': <class 'Stddev'>, 'STDDEV_POP': <class 'StddevPop'>, 'STDDEV_SAMP': <class 'StddevSamp'>, 'STR_POSITION': <class 'StrPosition'>, 'STR_TO_DATE': <class 'StrToDate'>, 'STR_TO_MAP': <class 'StrToMap'>, 'STR_TO_TIME': <class 'StrToTime'>, 'STR_TO_UNIX': <class 'StrToUnix'>, 'STRING': <class 'String'>, 'STRING_TO_ARRAY': <class 'StringToArray'>, 'SPLIT_BY_STRING': <class 'StringToArray'>, 'STRUCT': <class 'Struct'>, 'STRUCT_EXTRACT': <class 'StructExtract'>, 'STUFF': <class 'Stuff'>, 'INSERT': <class 'Stuff'>, 'SUBSTRING': <class 'Substring'>, 'SUBSTR': <class 'Substring'>, 'SUM': <class 'Sum'>, 'TIME': <class 'Time'>, 'TIME_ADD': <class 'TimeAdd'>, 'TIME_DIFF': <class 'TimeDiff'>, 'TIME_FROM_PARTS': <class 'TimeFromParts'>, 'TIMEFROMPARTS': <class 'TimeFromParts'>, 'TIME_STR_TO_DATE': <class 'TimeStrToDate'>, 'TIME_STR_TO_TIME': <class 'TimeStrToTime'>, 'TIME_STR_TO_UNIX': <class 'TimeStrToUnix'>, 'TIME_SUB': <class 'TimeSub'>, 'TIME_TO_STR': <class 'TimeToStr'>, 'TIME_TO_TIME_STR': <class 'TimeToTimeStr'>, 'TIME_TO_UNIX': <class 'TimeToUnix'>, 'TIME_TRUNC': <class 'TimeTrunc'>, 'TIMESTAMP': <class 'Timestamp'>, 'TIMESTAMP_ADD': <class 'TimestampAdd'>, 'TIMESTAMPDIFF': <class 'TimestampDiff'>, 'TIMESTAMP_DIFF': <class 'TimestampDiff'>, 'TIMESTAMP_FROM_PARTS': <class 'TimestampFromParts'>, 'TIMESTAMPFROMPARTS': <class 'TimestampFromParts'>, 'TIMESTAMP_SUB': <class 'TimestampSub'>, 'TIMESTAMP_TRUNC': <class 'TimestampTrunc'>, 'TO_ARRAY': <class 'ToArray'>, 'TO_BASE64': <class 'ToBase64'>, 'TO_CHAR': <class 'ToChar'>, 'TO_DAYS': <class 'ToDays'>, 'TO_DOUBLE': <class 'ToDouble'>, 'TO_MAP': <class 'ToMap'>, 'TO_NUMBER': <class 'ToNumber'>, 'TRANSFORM': <class 'Transform'>, 'TRIM': <class 'Trim'>, 'TRY': <class 'Try'>, 'TRY_CAST': <class 'TryCast'>, 'TS_OR_DI_TO_DI': <class 'TsOrDiToDi'>, 'TS_OR_DS_ADD': <class 'TsOrDsAdd'>, 'TS_OR_DS_DIFF': <class 'TsOrDsDiff'>, 'TS_OR_DS_TO_DATE': <class 'TsOrDsToDate'>, 'TS_OR_DS_TO_DATE_STR': <class 'TsOrDsToDateStr'>, 'TS_OR_DS_TO_DATETIME': <class 'TsOrDsToDatetime'>, 'TS_OR_DS_TO_TIME': <class 'TsOrDsToTime'>, 'TS_OR_DS_TO_TIMESTAMP': <class 'TsOrDsToTimestamp'>, 'UNHEX': <class 'Unhex'>, 'UNICODE': <class 'Unicode'>, 'UNIX_DATE': <class 'UnixDate'>, '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'>, 'UUID': <class 'Uuid'>, 'GEN_RANDOM_UUID': <class 'Uuid'>, 'GENERATE_UUID': <class 'Uuid'>, 'UUID_STRING': <class 'Uuid'>, 'VAR_MAP': <class 'VarMap'>, 'VARIANCE': <class 'Variance'>, 'VARIANCE_SAMP': <class 'Variance'>, 'VAR_SAMP': <class 'Variance'>, 'VARIANCE_POP': <class 'VariancePop'>, 'VAR_POP': <class 'VariancePop'>, 'WEEK': <class 'Week'>, 'WEEK_OF_YEAR': <class 'WeekOfYear'>, 'WEEKOFYEAR': <class 'WeekOfYear'>, '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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
6877def maybe_parse(
6878    sql_or_expression: ExpOrStr,
6879    *,
6880    into: t.Optional[IntoType] = None,
6881    dialect: DialectType = None,
6882    prefix: t.Optional[str] = None,
6883    copy: bool = False,
6884    **opts,
6885) -> Expression:
6886    """Gracefully handle a possible string or expression.
6887
6888    Example:
6889        >>> maybe_parse("1")
6890        Literal(this=1, is_string=False)
6891        >>> maybe_parse(to_identifier("x"))
6892        Identifier(this=x, quoted=False)
6893
6894    Args:
6895        sql_or_expression: the SQL code string or an expression
6896        into: the SQLGlot Expression to parse into
6897        dialect: the dialect used to parse the input expressions (in the case that an
6898            input expression is a SQL string).
6899        prefix: a string to prefix the sql with before it gets parsed
6900            (automatically includes a space)
6901        copy: whether to copy the expression.
6902        **opts: other options to use to parse the input expressions (again, in the case
6903            that an input expression is a SQL string).
6904
6905    Returns:
6906        Expression: the parsed or given expression.
6907    """
6908    if isinstance(sql_or_expression, Expression):
6909        if copy:
6910            return sql_or_expression.copy()
6911        return sql_or_expression
6912
6913    if sql_or_expression is None:
6914        raise ParseError("SQL cannot be None")
6915
6916    import sqlglot
6917
6918    sql = str(sql_or_expression)
6919    if prefix:
6920        sql = f"{prefix} {sql}"
6921
6922    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):
6933def maybe_copy(instance, copy=True):
6934    return instance.copy() if copy and instance else instance
def union( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
7182def union(
7183    *expressions: ExpOrStr,
7184    distinct: bool = True,
7185    dialect: DialectType = None,
7186    copy: bool = True,
7187    **opts,
7188) -> Union:
7189    """
7190    Initializes a syntax tree for the `UNION` operation.
7191
7192    Example:
7193        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7194        'SELECT * FROM foo UNION SELECT * FROM bla'
7195
7196    Args:
7197        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7198            If `Expression` instances are passed, they will be used as-is.
7199        distinct: set the DISTINCT flag if and only if this is true.
7200        dialect: the dialect used to parse the input expression.
7201        copy: whether to copy the expression.
7202        opts: other options to use to parse the input expressions.
7203
7204    Returns:
7205        The new Union instance.
7206    """
7207    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7208    return _apply_set_operation(
7209        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7210    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
7213def intersect(
7214    *expressions: ExpOrStr,
7215    distinct: bool = True,
7216    dialect: DialectType = None,
7217    copy: bool = True,
7218    **opts,
7219) -> Intersect:
7220    """
7221    Initializes a syntax tree for the `INTERSECT` operation.
7222
7223    Example:
7224        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7225        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7226
7227    Args:
7228        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7229            If `Expression` instances are passed, they will be used as-is.
7230        distinct: set the DISTINCT flag if and only if this is true.
7231        dialect: the dialect used to parse the input expression.
7232        copy: whether to copy the expression.
7233        opts: other options to use to parse the input expressions.
7234
7235    Returns:
7236        The new Intersect instance.
7237    """
7238    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7239    return _apply_set_operation(
7240        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7241    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
7244def except_(
7245    *expressions: ExpOrStr,
7246    distinct: bool = True,
7247    dialect: DialectType = None,
7248    copy: bool = True,
7249    **opts,
7250) -> Except:
7251    """
7252    Initializes a syntax tree for the `EXCEPT` operation.
7253
7254    Example:
7255        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7256        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7257
7258    Args:
7259        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7260            If `Expression` instances are passed, they will be used as-is.
7261        distinct: set the DISTINCT flag if and only if this is true.
7262        dialect: the dialect used to parse the input expression.
7263        copy: whether to copy the expression.
7264        opts: other options to use to parse the input expressions.
7265
7266    Returns:
7267        The new Except instance.
7268    """
7269    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7270    return _apply_set_operation(
7271        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7272    )

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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
7275def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7276    """
7277    Initializes a syntax tree from one or multiple SELECT expressions.
7278
7279    Example:
7280        >>> select("col1", "col2").from_("tbl").sql()
7281        'SELECT col1, col2 FROM tbl'
7282
7283    Args:
7284        *expressions: the SQL code string to parse as the expressions of a
7285            SELECT statement. If an Expression instance is passed, this is used as-is.
7286        dialect: the dialect used to parse the input expressions (in the case that an
7287            input expression is a SQL string).
7288        **opts: other options to use to parse the input expressions (again, in the case
7289            that an input expression is a SQL string).
7290
7291    Returns:
7292        Select: the syntax tree for the SELECT statement.
7293    """
7294    return Select().select(*expressions, dialect=dialect, **opts)

Initializes a syntax tree from one or multiple SELECT expressions.

Example:
>>> select("col1", "col2").from_("tbl").sql()
'SELECT col1, col2 FROM tbl'
Arguments:
  • *expressions: the SQL code string to parse as the expressions of a SELECT statement. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expressions (in the case that an input expression is a SQL string).
  • **opts: other options to use to parse the input expressions (again, in the case that an input expression is a SQL string).
Returns:

Select: the syntax tree for the SELECT statement.

def from_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
7297def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7298    """
7299    Initializes a syntax tree from a FROM expression.
7300
7301    Example:
7302        >>> from_("tbl").select("col1", "col2").sql()
7303        'SELECT col1, col2 FROM tbl'
7304
7305    Args:
7306        *expression: the SQL code string to parse as the FROM expressions of a
7307            SELECT statement. If an Expression instance is passed, this is used as-is.
7308        dialect: the dialect used to parse the input expression (in the case that the
7309            input expression is a SQL string).
7310        **opts: other options to use to parse the input expressions (again, in the case
7311            that the input expression is a SQL string).
7312
7313    Returns:
7314        Select: the syntax tree for the SELECT statement.
7315    """
7316    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Update:
7319def update(
7320    table: str | Table,
7321    properties: t.Optional[dict] = None,
7322    where: t.Optional[ExpOrStr] = None,
7323    from_: t.Optional[ExpOrStr] = None,
7324    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7325    dialect: DialectType = None,
7326    **opts,
7327) -> Update:
7328    """
7329    Creates an update statement.
7330
7331    Example:
7332        >>> 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()
7333        "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"
7334
7335    Args:
7336        properties: dictionary of properties to SET which are
7337            auto converted to sql objects eg None -> NULL
7338        where: sql conditional parsed into a WHERE statement
7339        from_: sql statement parsed into a FROM statement
7340        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7341        dialect: the dialect used to parse the input expressions.
7342        **opts: other options to use to parse the input expressions.
7343
7344    Returns:
7345        Update: the syntax tree for the UPDATE statement.
7346    """
7347    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7348    if properties:
7349        update_expr.set(
7350            "expressions",
7351            [
7352                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7353                for k, v in properties.items()
7354            ],
7355        )
7356    if from_:
7357        update_expr.set(
7358            "from",
7359            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7360        )
7361    if isinstance(where, Condition):
7362        where = Where(this=where)
7363    if where:
7364        update_expr.set(
7365            "where",
7366            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7367        )
7368    if with_:
7369        cte_list = [
7370            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7371            for alias, qry in with_.items()
7372        ]
7373        update_expr.set(
7374            "with",
7375            With(expressions=cte_list),
7376        )
7377    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Delete:
7380def delete(
7381    table: ExpOrStr,
7382    where: t.Optional[ExpOrStr] = None,
7383    returning: t.Optional[ExpOrStr] = None,
7384    dialect: DialectType = None,
7385    **opts,
7386) -> Delete:
7387    """
7388    Builds a delete statement.
7389
7390    Example:
7391        >>> delete("my_table", where="id > 1").sql()
7392        'DELETE FROM my_table WHERE id > 1'
7393
7394    Args:
7395        where: sql conditional parsed into a WHERE statement
7396        returning: sql conditional parsed into a RETURNING statement
7397        dialect: the dialect used to parse the input expressions.
7398        **opts: other options to use to parse the input expressions.
7399
7400    Returns:
7401        Delete: the syntax tree for the DELETE statement.
7402    """
7403    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7404    if where:
7405        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7406    if returning:
7407        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7408    return delete_expr

Builds a delete statement.

Example:
>>> delete("my_table", where="id > 1").sql()
'DELETE FROM my_table WHERE id > 1'
Arguments:
  • where: sql conditional parsed into a WHERE statement
  • returning: sql conditional parsed into a RETURNING statement
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Delete: the syntax tree for the DELETE statement.

def insert( expression: Union[str, Expression], into: Union[str, Expression], columns: Optional[Sequence[str | Identifier]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
7411def insert(
7412    expression: ExpOrStr,
7413    into: ExpOrStr,
7414    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7415    overwrite: t.Optional[bool] = None,
7416    returning: t.Optional[ExpOrStr] = None,
7417    dialect: DialectType = None,
7418    copy: bool = True,
7419    **opts,
7420) -> Insert:
7421    """
7422    Builds an INSERT statement.
7423
7424    Example:
7425        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7426        'INSERT INTO tbl VALUES (1, 2, 3)'
7427
7428    Args:
7429        expression: the sql string or expression of the INSERT statement
7430        into: the tbl to insert data to.
7431        columns: optionally the table's column names.
7432        overwrite: whether to INSERT OVERWRITE or not.
7433        returning: sql conditional parsed into a RETURNING statement
7434        dialect: the dialect used to parse the input expressions.
7435        copy: whether to copy the expression.
7436        **opts: other options to use to parse the input expressions.
7437
7438    Returns:
7439        Insert: the syntax tree for the INSERT statement.
7440    """
7441    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7442    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7443
7444    if columns:
7445        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7446
7447    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7448
7449    if returning:
7450        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7451
7452    return insert

Builds an INSERT statement.

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

Insert: the syntax tree for the INSERT statement.

def merge( *when_exprs: Union[str, Expression], into: Union[str, Expression], using: Union[str, Expression], on: Union[str, Expression], returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
7455def merge(
7456    *when_exprs: ExpOrStr,
7457    into: ExpOrStr,
7458    using: ExpOrStr,
7459    on: ExpOrStr,
7460    returning: t.Optional[ExpOrStr] = None,
7461    dialect: DialectType = None,
7462    copy: bool = True,
7463    **opts,
7464) -> Merge:
7465    """
7466    Builds a MERGE statement.
7467
7468    Example:
7469        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7470        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7471        ...       into="my_table",
7472        ...       using="source_table",
7473        ...       on="my_table.id = source_table.id").sql()
7474        '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)'
7475
7476    Args:
7477        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7478        into: The target table to merge data into.
7479        using: The source table to merge data from.
7480        on: The join condition for the merge.
7481        returning: The columns to return from the merge.
7482        dialect: The dialect used to parse the input expressions.
7483        copy: Whether to copy the expression.
7484        **opts: Other options to use to parse the input expressions.
7485
7486    Returns:
7487        Merge: The syntax tree for the MERGE statement.
7488    """
7489    expressions: t.List[Expression] = []
7490    for when_expr in when_exprs:
7491        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7492        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7493
7494    merge = Merge(
7495        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7496        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7497        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7498        whens=Whens(expressions=expressions),
7499    )
7500    if returning:
7501        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7502
7503    return merge

Builds a MERGE statement.

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

Merge: The syntax tree for the MERGE statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
7506def condition(
7507    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7508) -> Condition:
7509    """
7510    Initialize a logical condition expression.
7511
7512    Example:
7513        >>> condition("x=1").sql()
7514        'x = 1'
7515
7516        This is helpful for composing larger logical syntax trees:
7517        >>> where = condition("x=1")
7518        >>> where = where.and_("y=1")
7519        >>> Select().from_("tbl").select("*").where(where).sql()
7520        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7521
7522    Args:
7523        *expression: the SQL code string to parse.
7524            If an Expression instance is passed, this is used as-is.
7525        dialect: the dialect used to parse the input expression (in the case that the
7526            input expression is a SQL string).
7527        copy: Whether to copy `expression` (only applies to expressions).
7528        **opts: other options to use to parse the input expressions (again, in the case
7529            that the input expression is a SQL string).
7530
7531    Returns:
7532        The new Condition instance
7533    """
7534    return maybe_parse(
7535        expression,
7536        into=Condition,
7537        dialect=dialect,
7538        copy=copy,
7539        **opts,
7540    )

Initialize a logical condition expression.

Example:
>>> condition("x=1").sql()
'x = 1'

This is helpful for composing larger logical syntax trees:

>>> where = condition("x=1")
>>> where = where.and_("y=1")
>>> Select().from_("tbl").select("*").where(where).sql()
'SELECT * FROM tbl WHERE x = 1 AND y = 1'
Arguments:
  • *expression: the SQL code string to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression (in the case that the input expression is a SQL string).
  • copy: Whether to copy expression (only applies to expressions).
  • **opts: other options to use to parse the input expressions (again, in the case that the input expression is a SQL string).
Returns:

The new Condition instance

def and_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7543def and_(
7544    *expressions: t.Optional[ExpOrStr],
7545    dialect: DialectType = None,
7546    copy: bool = True,
7547    wrap: bool = True,
7548    **opts,
7549) -> Condition:
7550    """
7551    Combine multiple conditions with an AND logical operator.
7552
7553    Example:
7554        >>> and_("x=1", and_("y=1", "z=1")).sql()
7555        'x = 1 AND (y = 1 AND z = 1)'
7556
7557    Args:
7558        *expressions: the SQL code strings to parse.
7559            If an Expression instance is passed, this is used as-is.
7560        dialect: the dialect used to parse the input expression.
7561        copy: whether to copy `expressions` (only applies to Expressions).
7562        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7563            precedence issues, but can be turned off when the produced AST is too deep and
7564            causes recursion-related issues.
7565        **opts: other options to use to parse the input expressions.
7566
7567    Returns:
7568        The new condition
7569    """
7570    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7573def or_(
7574    *expressions: t.Optional[ExpOrStr],
7575    dialect: DialectType = None,
7576    copy: bool = True,
7577    wrap: bool = True,
7578    **opts,
7579) -> Condition:
7580    """
7581    Combine multiple conditions with an OR logical operator.
7582
7583    Example:
7584        >>> or_("x=1", or_("y=1", "z=1")).sql()
7585        'x = 1 OR (y = 1 OR z = 1)'
7586
7587    Args:
7588        *expressions: the SQL code strings to parse.
7589            If an Expression instance is passed, this is used as-is.
7590        dialect: the dialect used to parse the input expression.
7591        copy: whether to copy `expressions` (only applies to Expressions).
7592        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7593            precedence issues, but can be turned off when the produced AST is too deep and
7594            causes recursion-related issues.
7595        **opts: other options to use to parse the input expressions.
7596
7597    Returns:
7598        The new condition
7599    """
7600    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7603def xor(
7604    *expressions: t.Optional[ExpOrStr],
7605    dialect: DialectType = None,
7606    copy: bool = True,
7607    wrap: bool = True,
7608    **opts,
7609) -> Condition:
7610    """
7611    Combine multiple conditions with an XOR logical operator.
7612
7613    Example:
7614        >>> xor("x=1", xor("y=1", "z=1")).sql()
7615        'x = 1 XOR (y = 1 XOR z = 1)'
7616
7617    Args:
7618        *expressions: the SQL code strings to parse.
7619            If an Expression instance is passed, this is used as-is.
7620        dialect: the dialect used to parse the input expression.
7621        copy: whether to copy `expressions` (only applies to Expressions).
7622        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7623            precedence issues, but can be turned off when the produced AST is too deep and
7624            causes recursion-related issues.
7625        **opts: other options to use to parse the input expressions.
7626
7627    Returns:
7628        The new condition
7629    """
7630    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
7633def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7634    """
7635    Wrap a condition with a NOT operator.
7636
7637    Example:
7638        >>> not_("this_suit='black'").sql()
7639        "NOT this_suit = 'black'"
7640
7641    Args:
7642        expression: the SQL code string to parse.
7643            If an Expression instance is passed, this is used as-is.
7644        dialect: the dialect used to parse the input expression.
7645        copy: whether to copy the expression or not.
7646        **opts: other options to use to parse the input expressions.
7647
7648    Returns:
7649        The new condition.
7650    """
7651    this = condition(
7652        expression,
7653        dialect=dialect,
7654        copy=copy,
7655        **opts,
7656    )
7657    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:
7660def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7661    """
7662    Wrap an expression in parentheses.
7663
7664    Example:
7665        >>> paren("5 + 3").sql()
7666        '(5 + 3)'
7667
7668    Args:
7669        expression: the SQL code string to parse.
7670            If an Expression instance is passed, this is used as-is.
7671        copy: whether to copy the expression or not.
7672
7673    Returns:
7674        The wrapped expression.
7675    """
7676    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):
7692def to_identifier(name, quoted=None, copy=True):
7693    """Builds an identifier.
7694
7695    Args:
7696        name: The name to turn into an identifier.
7697        quoted: Whether to force quote the identifier.
7698        copy: Whether to copy name if it's an Identifier.
7699
7700    Returns:
7701        The identifier ast node.
7702    """
7703
7704    if name is None:
7705        return None
7706
7707    if isinstance(name, Identifier):
7708        identifier = maybe_copy(name, copy)
7709    elif isinstance(name, str):
7710        identifier = Identifier(
7711            this=name,
7712            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7713        )
7714    else:
7715        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7716    return identifier

Builds an identifier.

Arguments:
  • name: The name to turn into an identifier.
  • quoted: Whether to force quote the identifier.
  • copy: Whether to copy name if it's an Identifier.
Returns:

The identifier ast node.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Identifier:
7719def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7720    """
7721    Parses a given string into an identifier.
7722
7723    Args:
7724        name: The name to parse into an identifier.
7725        dialect: The dialect to parse against.
7726
7727    Returns:
7728        The identifier ast node.
7729    """
7730    try:
7731        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7732    except (ParseError, TokenError):
7733        expression = to_identifier(name)
7734
7735    return expression

Parses a given string into an identifier.

Arguments:
  • name: The name to parse into an identifier.
  • dialect: The dialect to parse against.
Returns:

The identifier ast node.

INTERVAL_STRING_RE = re.compile('\\s*([0-9]+)\\s*([a-zA-Z]+)\\s*')
def to_interval( interval: str | Literal) -> Interval:
7741def to_interval(interval: str | Literal) -> Interval:
7742    """Builds an interval expression from a string like '1 day' or '5 months'."""
7743    if isinstance(interval, Literal):
7744        if not interval.is_string:
7745            raise ValueError("Invalid interval string.")
7746
7747        interval = interval.this
7748
7749    interval = maybe_parse(f"INTERVAL {interval}")
7750    assert isinstance(interval, Interval)
7751    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.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
7754def to_table(
7755    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7756) -> Table:
7757    """
7758    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7759    If a table is passed in then that table is returned.
7760
7761    Args:
7762        sql_path: a `[catalog].[schema].[table]` string.
7763        dialect: the source dialect according to which the table name will be parsed.
7764        copy: Whether to copy a table if it is passed in.
7765        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7766
7767    Returns:
7768        A table expression.
7769    """
7770    if isinstance(sql_path, Table):
7771        return maybe_copy(sql_path, copy=copy)
7772
7773    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7774
7775    for k, v in kwargs.items():
7776        table.set(k, v)
7777
7778    return table

Create a table expression from a [catalog].[schema].[table] sql path. Catalog and schema are optional. If a table is passed in then that table is returned.

Arguments:
  • sql_path: a [catalog].[schema].[table] string.
  • dialect: the source dialect according to which the table name will be parsed.
  • copy: Whether to copy a table if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Table expression with.
Returns:

A table expression.

def to_column( sql_path: str | Column, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
7781def to_column(
7782    sql_path: str | Column,
7783    quoted: t.Optional[bool] = None,
7784    dialect: DialectType = None,
7785    copy: bool = True,
7786    **kwargs,
7787) -> Column:
7788    """
7789    Create a column from a `[table].[column]` sql path. Table is optional.
7790    If a column is passed in then that column is returned.
7791
7792    Args:
7793        sql_path: a `[table].[column]` string.
7794        quoted: Whether or not to force quote identifiers.
7795        dialect: the source dialect according to which the column name will be parsed.
7796        copy: Whether to copy a column if it is passed in.
7797        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7798
7799    Returns:
7800        A column expression.
7801    """
7802    if isinstance(sql_path, Column):
7803        return maybe_copy(sql_path, copy=copy)
7804
7805    try:
7806        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7807    except ParseError:
7808        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7809
7810    for k, v in kwargs.items():
7811        col.set(k, v)
7812
7813    if quoted:
7814        for i in col.find_all(Identifier):
7815            i.set("quoted", True)
7816
7817    return col

Create a column from a [table].[column] sql path. Table is optional. If a column is passed in then that column is returned.

Arguments:
  • sql_path: a [table].[column] string.
  • quoted: Whether or not to force quote identifiers.
  • dialect: the source dialect according to which the column name will be parsed.
  • copy: Whether to copy a column if it is passed in.
  • kwargs: the kwargs to instantiate the resulting Column expression with.
Returns:

A column expression.

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True, **opts):
7820def alias_(
7821    expression: ExpOrStr,
7822    alias: t.Optional[str | Identifier],
7823    table: bool | t.Sequence[str | Identifier] = False,
7824    quoted: t.Optional[bool] = None,
7825    dialect: DialectType = None,
7826    copy: bool = True,
7827    **opts,
7828):
7829    """Create an Alias expression.
7830
7831    Example:
7832        >>> alias_('foo', 'bar').sql()
7833        'foo AS bar'
7834
7835        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7836        '(SELECT 1, 2) AS bar(a, b)'
7837
7838    Args:
7839        expression: the SQL code strings to parse.
7840            If an Expression instance is passed, this is used as-is.
7841        alias: the alias name to use. If the name has
7842            special characters it is quoted.
7843        table: Whether to create a table alias, can also be a list of columns.
7844        quoted: whether to quote the alias
7845        dialect: the dialect used to parse the input expression.
7846        copy: Whether to copy the expression.
7847        **opts: other options to use to parse the input expressions.
7848
7849    Returns:
7850        Alias: the aliased expression
7851    """
7852    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7853    alias = to_identifier(alias, quoted=quoted)
7854
7855    if table:
7856        table_alias = TableAlias(this=alias)
7857        exp.set("alias", table_alias)
7858
7859        if not isinstance(table, bool):
7860            for column in table:
7861                table_alias.append("columns", to_identifier(column, quoted=quoted))
7862
7863        return exp
7864
7865    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7866    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7867    # for the complete Window expression.
7868    #
7869    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7870
7871    if "alias" in exp.arg_types and not isinstance(exp, Window):
7872        exp.set("alias", alias)
7873        return exp
7874    return Alias(this=exp, alias=alias)

Create an Alias expression.

Example:
>>> alias_('foo', 'bar').sql()
'foo AS bar'
>>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
'(SELECT 1, 2) AS bar(a, b)'
Arguments:
  • expression: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • alias: the alias name to use. If the name has special characters it is quoted.
  • table: Whether to create a table alias, can also be a list of columns.
  • quoted: whether to quote the alias
  • dialect: the dialect used to parse the input expression.
  • copy: Whether to copy the expression.
  • **opts: other options to use to parse the input expressions.
Returns:

Alias: the aliased expression

def subquery( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Select:
7877def subquery(
7878    expression: ExpOrStr,
7879    alias: t.Optional[Identifier | str] = None,
7880    dialect: DialectType = None,
7881    **opts,
7882) -> Select:
7883    """
7884    Build a subquery expression that's selected from.
7885
7886    Example:
7887        >>> subquery('select x from tbl', 'bar').select('x').sql()
7888        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7889
7890    Args:
7891        expression: the SQL code strings to parse.
7892            If an Expression instance is passed, this is used as-is.
7893        alias: the alias name to use.
7894        dialect: the dialect used to parse the input expression.
7895        **opts: other options to use to parse the input expressions.
7896
7897    Returns:
7898        A new Select instance with the subquery expression included.
7899    """
7900
7901    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7902    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):
7933def column(
7934    col,
7935    table=None,
7936    db=None,
7937    catalog=None,
7938    *,
7939    fields=None,
7940    quoted=None,
7941    copy=True,
7942):
7943    """
7944    Build a Column.
7945
7946    Args:
7947        col: Column name.
7948        table: Table name.
7949        db: Database name.
7950        catalog: Catalog name.
7951        fields: Additional fields using dots.
7952        quoted: Whether to force quotes on the column's identifiers.
7953        copy: Whether to copy identifiers if passed in.
7954
7955    Returns:
7956        The new Column instance.
7957    """
7958    this = Column(
7959        this=to_identifier(col, quoted=quoted, copy=copy),
7960        table=to_identifier(table, quoted=quoted, copy=copy),
7961        db=to_identifier(db, quoted=quoted, copy=copy),
7962        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
7963    )
7964
7965    if fields:
7966        this = Dot.build(
7967            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
7968        )
7969    return this

Build a Column.

Arguments:
  • col: Column name.
  • table: Table name.
  • db: Database name.
  • catalog: Catalog name.
  • fields: Additional fields using dots.
  • quoted: Whether to force quotes on the column's identifiers.
  • copy: Whether to copy identifiers if passed in.
Returns:

The new Column instance.

def cast( expression: Union[str, Expression], to: Union[str, DataType, DataType.Type], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **opts) -> Cast:
7972def cast(
7973    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
7974) -> Cast:
7975    """Cast an expression to a data type.
7976
7977    Example:
7978        >>> cast('x + 1', 'int').sql()
7979        'CAST(x + 1 AS INT)'
7980
7981    Args:
7982        expression: The expression to cast.
7983        to: The datatype to cast to.
7984        copy: Whether to copy the supplied expressions.
7985        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
7986            - The expression to be cast is already a exp.Cast expression
7987            - The existing cast is to a type that is logically equivalent to new type
7988
7989            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
7990            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
7991            and instead just return the original expression `CAST(x as DATETIME)`.
7992
7993            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
7994            mapping is applied in the target dialect generator.
7995
7996    Returns:
7997        The new Cast instance.
7998    """
7999    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8000    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8001
8002    # dont re-cast if the expression is already a cast to the correct type
8003    if isinstance(expr, Cast):
8004        from sqlglot.dialects.dialect import Dialect
8005
8006        target_dialect = Dialect.get_or_raise(dialect)
8007        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8008
8009        existing_cast_type: DataType.Type = expr.to.this
8010        new_cast_type: DataType.Type = data_type.this
8011        types_are_equivalent = type_mapping.get(
8012            existing_cast_type, existing_cast_type.value
8013        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8014
8015        if expr.is_type(data_type) or types_are_equivalent:
8016            return expr
8017
8018    expr = Cast(this=expr, to=data_type)
8019    expr.type = data_type
8020
8021    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:
8024def table_(
8025    table: Identifier | str,
8026    db: t.Optional[Identifier | str] = None,
8027    catalog: t.Optional[Identifier | str] = None,
8028    quoted: t.Optional[bool] = None,
8029    alias: t.Optional[Identifier | str] = None,
8030) -> Table:
8031    """Build a Table.
8032
8033    Args:
8034        table: Table name.
8035        db: Database name.
8036        catalog: Catalog name.
8037        quote: Whether to force quotes on the table's identifiers.
8038        alias: Table's alias.
8039
8040    Returns:
8041        The new Table instance.
8042    """
8043    return Table(
8044        this=to_identifier(table, quoted=quoted) if table else None,
8045        db=to_identifier(db, quoted=quoted) if db else None,
8046        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8047        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8048    )

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:
8051def values(
8052    values: t.Iterable[t.Tuple[t.Any, ...]],
8053    alias: t.Optional[str] = None,
8054    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8055) -> Values:
8056    """Build VALUES statement.
8057
8058    Example:
8059        >>> values([(1, '2')]).sql()
8060        "VALUES (1, '2')"
8061
8062    Args:
8063        values: values statements that will be converted to SQL
8064        alias: optional alias
8065        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8066         If either are provided then an alias is also required.
8067
8068    Returns:
8069        Values: the Values expression object
8070    """
8071    if columns and not alias:
8072        raise ValueError("Alias is required when providing columns")
8073
8074    return Values(
8075        expressions=[convert(tup) for tup in values],
8076        alias=(
8077            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8078            if columns
8079            else (TableAlias(this=to_identifier(alias)) if alias else None)
8080        ),
8081    )

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:
8084def var(name: t.Optional[ExpOrStr]) -> Var:
8085    """Build a SQL variable.
8086
8087    Example:
8088        >>> repr(var('x'))
8089        'Var(this=x)'
8090
8091        >>> repr(var(column('x', table='y')))
8092        'Var(this=x)'
8093
8094    Args:
8095        name: The name of the var or an expression who's name will become the var.
8096
8097    Returns:
8098        The new variable node.
8099    """
8100    if not name:
8101        raise ValueError("Cannot convert empty name into var.")
8102
8103    if isinstance(name, Expression):
8104        name = name.name
8105    return Var(this=name)

Build a SQL variable.

Example:
>>> repr(var('x'))
'Var(this=x)'
>>> repr(var(column('x', table='y')))
'Var(this=x)'
Arguments:
  • name: The name of the var or an expression who's name will become the var.
Returns:

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Alter:
8108def rename_table(
8109    old_name: str | Table,
8110    new_name: str | Table,
8111    dialect: DialectType = None,
8112) -> Alter:
8113    """Build ALTER TABLE... RENAME... expression
8114
8115    Args:
8116        old_name: The old name of the table
8117        new_name: The new name of the table
8118        dialect: The dialect to parse the table.
8119
8120    Returns:
8121        Alter table expression
8122    """
8123    old_table = to_table(old_name, dialect=dialect)
8124    new_table = to_table(new_name, dialect=dialect)
8125    return Alter(
8126        this=old_table,
8127        kind="TABLE",
8128        actions=[
8129            AlterRename(this=new_table),
8130        ],
8131    )

Build ALTER TABLE... RENAME... expression

Arguments:
  • old_name: The old name of the table
  • new_name: The new name of the table
  • dialect: The dialect to parse the table.
Returns:

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None) -> Alter:
8134def rename_column(
8135    table_name: str | Table,
8136    old_column_name: str | Column,
8137    new_column_name: str | Column,
8138    exists: t.Optional[bool] = None,
8139    dialect: DialectType = None,
8140) -> Alter:
8141    """Build ALTER TABLE... RENAME COLUMN... expression
8142
8143    Args:
8144        table_name: Name of the table
8145        old_column: The old name of the column
8146        new_column: The new name of the column
8147        exists: Whether to add the `IF EXISTS` clause
8148        dialect: The dialect to parse the table/column.
8149
8150    Returns:
8151        Alter table expression
8152    """
8153    table = to_table(table_name, dialect=dialect)
8154    old_column = to_column(old_column_name, dialect=dialect)
8155    new_column = to_column(new_column_name, dialect=dialect)
8156    return Alter(
8157        this=table,
8158        kind="TABLE",
8159        actions=[
8160            RenameColumn(this=old_column, to=new_column, exists=exists),
8161        ],
8162    )

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:
8165def convert(value: t.Any, copy: bool = False) -> Expression:
8166    """Convert a python value into an expression object.
8167
8168    Raises an error if a conversion is not possible.
8169
8170    Args:
8171        value: A python object.
8172        copy: Whether to copy `value` (only applies to Expressions and collections).
8173
8174    Returns:
8175        The equivalent expression object.
8176    """
8177    if isinstance(value, Expression):
8178        return maybe_copy(value, copy)
8179    if isinstance(value, str):
8180        return Literal.string(value)
8181    if isinstance(value, bool):
8182        return Boolean(this=value)
8183    if value is None or (isinstance(value, float) and math.isnan(value)):
8184        return null()
8185    if isinstance(value, numbers.Number):
8186        return Literal.number(value)
8187    if isinstance(value, bytes):
8188        return HexString(this=value.hex())
8189    if isinstance(value, datetime.datetime):
8190        datetime_literal = Literal.string(value.isoformat(sep=" "))
8191
8192        tz = None
8193        if value.tzinfo:
8194            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8195            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8196            tz = Literal.string(str(value.tzinfo))
8197
8198        return TimeStrToTime(this=datetime_literal, zone=tz)
8199    if isinstance(value, datetime.date):
8200        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8201        return DateStrToDate(this=date_literal)
8202    if isinstance(value, tuple):
8203        if hasattr(value, "_fields"):
8204            return Struct(
8205                expressions=[
8206                    PropertyEQ(
8207                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8208                    )
8209                    for k in value._fields
8210                ]
8211            )
8212        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8213    if isinstance(value, list):
8214        return Array(expressions=[convert(v, copy=copy) for v in value])
8215    if isinstance(value, dict):
8216        return Map(
8217            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8218            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8219        )
8220    if hasattr(value, "__dict__"):
8221        return Struct(
8222            expressions=[
8223                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8224                for k, v in value.__dict__.items()
8225            ]
8226        )
8227    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:
8230def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8231    """
8232    Replace children of an expression with the result of a lambda fun(child) -> exp.
8233    """
8234    for k, v in tuple(expression.args.items()):
8235        is_list_arg = type(v) is list
8236
8237        child_nodes = v if is_list_arg else [v]
8238        new_child_nodes = []
8239
8240        for cn in child_nodes:
8241            if isinstance(cn, Expression):
8242                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8243                    new_child_nodes.append(child_node)
8244            else:
8245                new_child_nodes.append(cn)
8246
8247        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:
8250def replace_tree(
8251    expression: Expression,
8252    fun: t.Callable,
8253    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8254) -> Expression:
8255    """
8256    Replace an entire tree with the result of function calls on each node.
8257
8258    This will be traversed in reverse dfs, so leaves first.
8259    If new nodes are created as a result of function calls, they will also be traversed.
8260    """
8261    stack = list(expression.dfs(prune=prune))
8262
8263    while stack:
8264        node = stack.pop()
8265        new_node = fun(node)
8266
8267        if new_node is not node:
8268            node.replace(new_node)
8269
8270            if isinstance(new_node, Expression):
8271                stack.append(new_node)
8272
8273    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]:
8276def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8277    """
8278    Return all table names referenced through columns in an expression.
8279
8280    Example:
8281        >>> import sqlglot
8282        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8283        ['a', 'c']
8284
8285    Args:
8286        expression: expression to find table names.
8287        exclude: a table name to exclude
8288
8289    Returns:
8290        A list of unique names.
8291    """
8292    return {
8293        table
8294        for table in (column.table for column in expression.find_all(Column))
8295        if table and table != exclude
8296    }

Return all table names referenced through columns in an expression.

Example:
>>> import sqlglot
>>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
['a', 'c']
Arguments:
  • expression: expression to find table names.
  • exclude: a table name to exclude
Returns:

A list of unique names.

def table_name( table: Table | str, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, identify: bool = False) -> str:
8299def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8300    """Get the full name of a table as a string.
8301
8302    Args:
8303        table: Table expression node or string.
8304        dialect: The dialect to generate the table name for.
8305        identify: Determines when an identifier should be quoted. Possible values are:
8306            False (default): Never quote, except in cases where it's mandatory by the dialect.
8307            True: Always quote.
8308
8309    Examples:
8310        >>> from sqlglot import exp, parse_one
8311        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8312        'a.b.c'
8313
8314    Returns:
8315        The table name.
8316    """
8317
8318    table = maybe_parse(table, into=Table, dialect=dialect)
8319
8320    if not table:
8321        raise ValueError(f"Cannot parse {table}")
8322
8323    return ".".join(
8324        (
8325            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8326            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8327            else part.name
8328        )
8329        for part in table.parts
8330    )

Get the full name of a table as a string.

Arguments:
  • table: Table expression node or string.
  • dialect: The dialect to generate the table name for.
  • identify: Determines when an identifier should be quoted. Possible values are: False (default): Never quote, except in cases where it's mandatory by the dialect. True: Always quote.
Examples:
>>> from sqlglot import exp, parse_one
>>> table_name(parse_one("select * from a.b.c").find(exp.Table))
'a.b.c'
Returns:

The table name.

def normalize_table_name( table: str | Table, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> str:
8333def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8334    """Returns a case normalized table name without quotes.
8335
8336    Args:
8337        table: the table to normalize
8338        dialect: the dialect to use for normalization rules
8339        copy: whether to copy the expression.
8340
8341    Examples:
8342        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8343        'A-B.c'
8344    """
8345    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8346
8347    return ".".join(
8348        p.name
8349        for p in normalize_identifiers(
8350            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8351        ).parts
8352    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> ~E:
8355def replace_tables(
8356    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8357) -> E:
8358    """Replace all tables in expression according to the mapping.
8359
8360    Args:
8361        expression: expression node to be transformed and replaced.
8362        mapping: mapping of table names.
8363        dialect: the dialect of the mapping table
8364        copy: whether to copy the expression.
8365
8366    Examples:
8367        >>> from sqlglot import exp, parse_one
8368        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8369        'SELECT * FROM c /* a.b */'
8370
8371    Returns:
8372        The mapped expression.
8373    """
8374
8375    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8376
8377    def _replace_tables(node: Expression) -> Expression:
8378        if isinstance(node, Table) and node.meta.get("replace") is not False:
8379            original = normalize_table_name(node, dialect=dialect)
8380            new_name = mapping.get(original)
8381
8382            if new_name:
8383                table = to_table(
8384                    new_name,
8385                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8386                    dialect=dialect,
8387                )
8388                table.add_comments([original])
8389                return table
8390        return node
8391
8392    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:
8395def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8396    """Replace placeholders in an expression.
8397
8398    Args:
8399        expression: expression node to be transformed and replaced.
8400        args: positional names that will substitute unnamed placeholders in the given order.
8401        kwargs: keyword arguments that will substitute named placeholders.
8402
8403    Examples:
8404        >>> from sqlglot import exp, parse_one
8405        >>> replace_placeholders(
8406        ...     parse_one("select * from :tbl where ? = ?"),
8407        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8408        ... ).sql()
8409        "SELECT * FROM foo WHERE str_col = 'b'"
8410
8411    Returns:
8412        The mapped expression.
8413    """
8414
8415    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8416        if isinstance(node, Placeholder):
8417            if node.this:
8418                new_name = kwargs.get(node.this)
8419                if new_name is not None:
8420                    return convert(new_name)
8421            else:
8422                try:
8423                    return convert(next(args))
8424                except StopIteration:
8425                    pass
8426        return node
8427
8428    return expression.transform(_replace_placeholders, iter(args), **kwargs)

Replace placeholders in an expression.

Arguments:
  • expression: expression node to be transformed and replaced.
  • args: positional names that will substitute unnamed placeholders in the given order.
  • kwargs: keyword arguments that will substitute named placeholders.
Examples:
>>> from sqlglot import exp, parse_one
>>> replace_placeholders(
...     parse_one("select * from :tbl where ? = ?"),
...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
... ).sql()
"SELECT * FROM foo WHERE str_col = 'b'"
Returns:

The mapped expression.

def expand( expression: Expression, sources: Dict[str, Query], dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, copy: bool = True) -> Expression:
8431def expand(
8432    expression: Expression,
8433    sources: t.Dict[str, Query],
8434    dialect: DialectType = None,
8435    copy: bool = True,
8436) -> Expression:
8437    """Transforms an expression by expanding all referenced sources into subqueries.
8438
8439    Examples:
8440        >>> from sqlglot import parse_one
8441        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8442        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8443
8444        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8445        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8446
8447    Args:
8448        expression: The expression to expand.
8449        sources: A dictionary of name to Queries.
8450        dialect: The dialect of the sources dict.
8451        copy: Whether to copy the expression during transformation. Defaults to True.
8452
8453    Returns:
8454        The transformed expression.
8455    """
8456    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8457
8458    def _expand(node: Expression):
8459        if isinstance(node, Table):
8460            name = normalize_table_name(node, dialect=dialect)
8461            source = sources.get(name)
8462            if source:
8463                subquery = source.subquery(node.alias or name)
8464                subquery.comments = [f"source: {name}"]
8465                return subquery.transform(_expand, copy=False)
8466        return node
8467
8468    return expression.transform(_expand, copy=copy)

Transforms an expression by expanding all referenced sources into subqueries.

Examples:
>>> from sqlglot import parse_one
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
>>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
Arguments:
  • expression: The expression to expand.
  • sources: A dictionary of name to Queries.
  • dialect: The dialect of the sources dict.
  • copy: Whether to copy the expression during transformation. Defaults to True.
Returns:

The transformed expression.

def func( name: str, *args, copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Func:
8471def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8472    """
8473    Returns a Func expression.
8474
8475    Examples:
8476        >>> func("abs", 5).sql()
8477        'ABS(5)'
8478
8479        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8480        'CAST(5 AS DOUBLE)'
8481
8482    Args:
8483        name: the name of the function to build.
8484        args: the args used to instantiate the function of interest.
8485        copy: whether to copy the argument expressions.
8486        dialect: the source dialect.
8487        kwargs: the kwargs used to instantiate the function of interest.
8488
8489    Note:
8490        The arguments `args` and `kwargs` are mutually exclusive.
8491
8492    Returns:
8493        An instance of the function of interest, or an anonymous function, if `name` doesn't
8494        correspond to an existing `sqlglot.expressions.Func` class.
8495    """
8496    if args and kwargs:
8497        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8498
8499    from sqlglot.dialects.dialect import Dialect
8500
8501    dialect = Dialect.get_or_raise(dialect)
8502
8503    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8504    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8505
8506    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8507    if constructor:
8508        if converted:
8509            if "dialect" in constructor.__code__.co_varnames:
8510                function = constructor(converted, dialect=dialect)
8511            else:
8512                function = constructor(converted)
8513        elif constructor.__name__ == "from_arg_list":
8514            function = constructor.__self__(**kwargs)  # type: ignore
8515        else:
8516            constructor = FUNCTION_BY_NAME.get(name.upper())
8517            if constructor:
8518                function = constructor(**kwargs)
8519            else:
8520                raise ValueError(
8521                    f"Unable to convert '{name}' into a Func. Either manually construct "
8522                    "the Func expression of interest or parse the function call."
8523                )
8524    else:
8525        kwargs = kwargs or {"expressions": converted}
8526        function = Anonymous(this=name, **kwargs)
8527
8528    for error_message in function.error_messages(converted):
8529        raise ValueError(error_message)
8530
8531    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:
8534def case(
8535    expression: t.Optional[ExpOrStr] = None,
8536    **opts,
8537) -> Case:
8538    """
8539    Initialize a CASE statement.
8540
8541    Example:
8542        case().when("a = 1", "foo").else_("bar")
8543
8544    Args:
8545        expression: Optionally, the input expression (not all dialects support this)
8546        **opts: Extra keyword arguments for parsing `expression`
8547    """
8548    if expression is not None:
8549        this = maybe_parse(expression, **opts)
8550    else:
8551        this = None
8552    return Case(this=this, ifs=[])

Initialize a CASE statement.

Example:

case().when("a = 1", "foo").else_("bar")

Arguments:
  • expression: Optionally, the input expression (not all dialects support this)
  • **opts: Extra keyword arguments for parsing expression
def array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Array:
8555def array(
8556    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8557) -> Array:
8558    """
8559    Returns an array.
8560
8561    Examples:
8562        >>> array(1, 'x').sql()
8563        'ARRAY(1, x)'
8564
8565    Args:
8566        expressions: the expressions to add to the array.
8567        copy: whether to copy the argument expressions.
8568        dialect: the source dialect.
8569        kwargs: the kwargs used to instantiate the function of interest.
8570
8571    Returns:
8572        An array expression.
8573    """
8574    return Array(
8575        expressions=[
8576            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8577            for expression in expressions
8578        ]
8579    )

Returns an array.

Examples:
>>> array(1, 'x').sql()
'ARRAY(1, x)'
Arguments:
  • expressions: the expressions to add to the array.
  • copy: whether to copy the argument expressions.
  • dialect: the source dialect.
  • kwargs: the kwargs used to instantiate the function of interest.
Returns:

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.dialect.Dialect, Type[sqlglot.dialects.dialect.Dialect], NoneType] = None, **kwargs) -> Tuple:
8582def tuple_(
8583    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8584) -> Tuple:
8585    """
8586    Returns an tuple.
8587
8588    Examples:
8589        >>> tuple_(1, 'x').sql()
8590        '(1, x)'
8591
8592    Args:
8593        expressions: the expressions to add to the tuple.
8594        copy: whether to copy the argument expressions.
8595        dialect: the source dialect.
8596        kwargs: the kwargs used to instantiate the function of interest.
8597
8598    Returns:
8599        A tuple expression.
8600    """
8601    return Tuple(
8602        expressions=[
8603            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8604            for expression in expressions
8605        ]
8606    )

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:
8609def true() -> Boolean:
8610    """
8611    Returns a true Boolean expression.
8612    """
8613    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8616def false() -> Boolean:
8617    """
8618    Returns a false Boolean expression.
8619    """
8620    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8623def null() -> Null:
8624    """
8625    Returns a Null expression.
8626    """
8627    return Null()

Returns a Null expression.

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