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

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

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

Converts the column into a dot expression.

key = 'column'
class ColumnPosition(Expression):
1673class ColumnPosition(Expression):
1674    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
class ColumnDef(Expression):
1677class ColumnDef(Expression):
1678    arg_types = {
1679        "this": True,
1680        "kind": False,
1681        "constraints": False,
1682        "exists": False,
1683        "position": False,
1684        "default": False,
1685        "output": False,
1686    }
1687
1688    @property
1689    def constraints(self) -> t.List[ColumnConstraint]:
1690        return self.args.get("constraints") or []
1691
1692    @property
1693    def kind(self) -> t.Optional[DataType]:
1694        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1688    @property
1689    def constraints(self) -> t.List[ColumnConstraint]:
1690        return self.args.get("constraints") or []
kind: Optional[DataType]
1692    @property
1693    def kind(self) -> t.Optional[DataType]:
1694        return self.args.get("kind")
key = 'columndef'
class AlterColumn(Expression):
1697class AlterColumn(Expression):
1698    arg_types = {
1699        "this": True,
1700        "dtype": False,
1701        "collate": False,
1702        "using": False,
1703        "default": False,
1704        "drop": False,
1705        "comment": False,
1706        "allow_null": False,
1707    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False}
key = 'altercolumn'
class AlterIndex(Expression):
1711class AlterIndex(Expression):
1712    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1716class AlterDistStyle(Expression):
1717    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1720class AlterSortKey(Expression):
1721    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1724class AlterSet(Expression):
1725    arg_types = {
1726        "expressions": False,
1727        "option": False,
1728        "tablespace": False,
1729        "access_method": False,
1730        "file_format": False,
1731        "copy_options": False,
1732        "tag": False,
1733        "location": False,
1734        "serde": False,
1735    }
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):
1738class RenameColumn(Expression):
1739    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1742class AlterRename(Expression):
1743    pass
key = 'alterrename'
class SwapTable(Expression):
1746class SwapTable(Expression):
1747    pass
key = 'swaptable'
class Comment(Expression):
1750class Comment(Expression):
1751    arg_types = {
1752        "this": True,
1753        "kind": True,
1754        "expression": True,
1755        "exists": False,
1756        "materialized": False,
1757    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1760class Comprehension(Expression):
1761    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):
1765class MergeTreeTTLAction(Expression):
1766    arg_types = {
1767        "this": True,
1768        "delete": False,
1769        "recompress": False,
1770        "to_disk": False,
1771        "to_volume": False,
1772    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1776class MergeTreeTTL(Expression):
1777    arg_types = {
1778        "expressions": True,
1779        "where": False,
1780        "group": False,
1781        "aggregates": False,
1782    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1786class IndexConstraintOption(Expression):
1787    arg_types = {
1788        "key_block_size": False,
1789        "using": False,
1790        "parser": False,
1791        "comment": False,
1792        "visible": False,
1793        "engine_attr": False,
1794        "secondary_engine_attr": False,
1795    }
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):
1798class ColumnConstraint(Expression):
1799    arg_types = {"this": False, "kind": True}
1800
1801    @property
1802    def kind(self) -> ColumnConstraintKind:
1803        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1801    @property
1802    def kind(self) -> ColumnConstraintKind:
1803        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1806class ColumnConstraintKind(Expression):
1807    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1810class AutoIncrementColumnConstraint(ColumnConstraintKind):
1811    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1814class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1815    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1818class CaseSpecificColumnConstraint(ColumnConstraintKind):
1819    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1822class CharacterSetColumnConstraint(ColumnConstraintKind):
1823    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1826class CheckColumnConstraint(ColumnConstraintKind):
1827    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1830class ClusteredColumnConstraint(ColumnConstraintKind):
1831    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1834class CollateColumnConstraint(ColumnConstraintKind):
1835    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1838class CommentColumnConstraint(ColumnConstraintKind):
1839    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1842class CompressColumnConstraint(ColumnConstraintKind):
1843    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1846class DateFormatColumnConstraint(ColumnConstraintKind):
1847    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1850class DefaultColumnConstraint(ColumnConstraintKind):
1851    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1854class EncodeColumnConstraint(ColumnConstraintKind):
1855    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1859class ExcludeColumnConstraint(ColumnConstraintKind):
1860    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1863class EphemeralColumnConstraint(ColumnConstraintKind):
1864    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1867class WithOperator(Expression):
1868    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1871class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1872    # this: True -> ALWAYS, this: False -> BY DEFAULT
1873    arg_types = {
1874        "this": False,
1875        "expression": False,
1876        "on_null": False,
1877        "start": False,
1878        "increment": False,
1879        "minvalue": False,
1880        "maxvalue": False,
1881        "cycle": False,
1882    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1885class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1886    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1891class IndexColumnConstraint(ColumnConstraintKind):
1892    arg_types = {
1893        "this": False,
1894        "expressions": False,
1895        "kind": False,
1896        "index_type": False,
1897        "options": False,
1898        "expression": False,  # Clickhouse
1899        "granularity": False,
1900    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1903class InlineLengthColumnConstraint(ColumnConstraintKind):
1904    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1907class NonClusteredColumnConstraint(ColumnConstraintKind):
1908    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1911class NotForReplicationColumnConstraint(ColumnConstraintKind):
1912    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1916class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1917    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1920class NotNullColumnConstraint(ColumnConstraintKind):
1921    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1925class OnUpdateColumnConstraint(ColumnConstraintKind):
1926    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1930class TransformColumnConstraint(ColumnConstraintKind):
1931    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1934class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1935    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1938class TitleColumnConstraint(ColumnConstraintKind):
1939    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1942class UniqueColumnConstraint(ColumnConstraintKind):
1943    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):
1946class UppercaseColumnConstraint(ColumnConstraintKind):
1947    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
1951class WatermarkColumnConstraint(Expression):
1952    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1955class PathColumnConstraint(ColumnConstraintKind):
1956    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1960class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1961    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1966class ComputedColumnConstraint(ColumnConstraintKind):
1967    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1970class Constraint(Expression):
1971    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1974class Delete(DML):
1975    arg_types = {
1976        "with": False,
1977        "this": False,
1978        "using": False,
1979        "where": False,
1980        "returning": False,
1981        "limit": False,
1982        "tables": False,  # Multiple-Table Syntax (MySQL)
1983        "cluster": False,  # Clickhouse
1984    }
1985
1986    def delete(
1987        self,
1988        table: ExpOrStr,
1989        dialect: DialectType = None,
1990        copy: bool = True,
1991        **opts,
1992    ) -> Delete:
1993        """
1994        Create a DELETE expression or replace the table on an existing DELETE expression.
1995
1996        Example:
1997            >>> delete("tbl").sql()
1998            'DELETE FROM tbl'
1999
2000        Args:
2001            table: the table from which to delete.
2002            dialect: the dialect used to parse the input expression.
2003            copy: if `False`, modify this expression instance in-place.
2004            opts: other options to use to parse the input expressions.
2005
2006        Returns:
2007            Delete: the modified expression.
2008        """
2009        return _apply_builder(
2010            expression=table,
2011            instance=self,
2012            arg="this",
2013            dialect=dialect,
2014            into=Table,
2015            copy=copy,
2016            **opts,
2017        )
2018
2019    def where(
2020        self,
2021        *expressions: t.Optional[ExpOrStr],
2022        append: bool = True,
2023        dialect: DialectType = None,
2024        copy: bool = True,
2025        **opts,
2026    ) -> Delete:
2027        """
2028        Append to or set the WHERE expressions.
2029
2030        Example:
2031            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2032            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2033
2034        Args:
2035            *expressions: the SQL code strings to parse.
2036                If an `Expression` instance is passed, it will be used as-is.
2037                Multiple expressions are combined with an AND operator.
2038            append: if `True`, AND the new expressions to any existing expression.
2039                Otherwise, this resets the expression.
2040            dialect: the dialect used to parse the input expressions.
2041            copy: if `False`, modify this expression instance in-place.
2042            opts: other options to use to parse the input expressions.
2043
2044        Returns:
2045            Delete: the modified expression.
2046        """
2047        return _apply_conjunction_builder(
2048            *expressions,
2049            instance=self,
2050            arg="where",
2051            append=append,
2052            into=Where,
2053            dialect=dialect,
2054            copy=copy,
2055            **opts,
2056        )
arg_types = {'with': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'limit': False, 'tables': False, 'cluster': False}
def delete( self, table: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Delete:
1986    def delete(
1987        self,
1988        table: ExpOrStr,
1989        dialect: DialectType = None,
1990        copy: bool = True,
1991        **opts,
1992    ) -> Delete:
1993        """
1994        Create a DELETE expression or replace the table on an existing DELETE expression.
1995
1996        Example:
1997            >>> delete("tbl").sql()
1998            'DELETE FROM tbl'
1999
2000        Args:
2001            table: the table from which to delete.
2002            dialect: the dialect used to parse the input expression.
2003            copy: if `False`, modify this expression instance in-place.
2004            opts: other options to use to parse the input expressions.
2005
2006        Returns:
2007            Delete: the modified expression.
2008        """
2009        return _apply_builder(
2010            expression=table,
2011            instance=self,
2012            arg="this",
2013            dialect=dialect,
2014            into=Table,
2015            copy=copy,
2016            **opts,
2017        )

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

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

Delete: the modified expression.

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

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):
2059class Drop(Expression):
2060    arg_types = {
2061        "this": False,
2062        "kind": False,
2063        "expressions": False,
2064        "exists": False,
2065        "temporary": False,
2066        "materialized": False,
2067        "cascade": False,
2068        "constraints": False,
2069        "purge": False,
2070        "cluster": False,
2071        "concurrently": False,
2072    }
2073
2074    @property
2075    def kind(self) -> t.Optional[str]:
2076        kind = self.args.get("kind")
2077        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]
2074    @property
2075    def kind(self) -> t.Optional[str]:
2076        kind = self.args.get("kind")
2077        return kind and kind.upper()
key = 'drop'
class Export(Expression):
2081class Export(Expression):
2082    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
class Filter(Expression):
2085class Filter(Expression):
2086    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
class Check(Expression):
2089class Check(Expression):
2090    pass
key = 'check'
class Changes(Expression):
2093class Changes(Expression):
2094    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
class Connect(Expression):
2098class Connect(Expression):
2099    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
class CopyParameter(Expression):
2102class CopyParameter(Expression):
2103    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
class Copy(DML):
2106class Copy(DML):
2107    arg_types = {
2108        "this": True,
2109        "kind": True,
2110        "files": True,
2111        "credentials": False,
2112        "format": False,
2113        "params": False,
2114    }
arg_types = {'this': True, 'kind': True, 'files': True, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
class Credentials(Expression):
2117class Credentials(Expression):
2118    arg_types = {
2119        "credentials": False,
2120        "encryption": False,
2121        "storage": False,
2122        "iam_role": False,
2123        "region": False,
2124    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
class Prior(Expression):
2127class Prior(Expression):
2128    pass
key = 'prior'
class Directory(Expression):
2131class Directory(Expression):
2132    # https://spark.apache.org/docs/3.0.0-preview/sql-ref-syntax-dml-insert-overwrite-directory-hive.html
2133    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
class ForeignKey(Expression):
2136class ForeignKey(Expression):
2137    arg_types = {
2138        "expressions": False,
2139        "reference": False,
2140        "delete": False,
2141        "update": False,
2142    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False}
key = 'foreignkey'
class ColumnPrefix(Expression):
2145class ColumnPrefix(Expression):
2146    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
class PrimaryKey(Expression):
2149class PrimaryKey(Expression):
2150    arg_types = {"expressions": True, "options": False}
arg_types = {'expressions': True, 'options': False}
key = 'primarykey'
class Into(Expression):
2155class Into(Expression):
2156    arg_types = {
2157        "this": False,
2158        "temporary": False,
2159        "unlogged": False,
2160        "bulk_collect": False,
2161        "expressions": False,
2162    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
class From(Expression):
2165class From(Expression):
2166    @property
2167    def name(self) -> str:
2168        return self.this.name
2169
2170    @property
2171    def alias_or_name(self) -> str:
2172        return self.this.alias_or_name
name: str
2166    @property
2167    def name(self) -> str:
2168        return self.this.name
alias_or_name: str
2170    @property
2171    def alias_or_name(self) -> str:
2172        return self.this.alias_or_name
key = 'from'
class Having(Expression):
2175class Having(Expression):
2176    pass
key = 'having'
class Hint(Expression):
2179class Hint(Expression):
2180    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
class JoinHint(Expression):
2183class JoinHint(Expression):
2184    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
class Identifier(Expression):
2187class Identifier(Expression):
2188    arg_types = {"this": True, "quoted": False, "global": False, "temporary": False}
2189
2190    @property
2191    def quoted(self) -> bool:
2192        return bool(self.args.get("quoted"))
2193
2194    @property
2195    def hashable_args(self) -> t.Any:
2196        return (self.this, self.quoted)
2197
2198    @property
2199    def output_name(self) -> str:
2200        return self.name
arg_types = {'this': True, 'quoted': False, 'global': False, 'temporary': False}
quoted: bool
2190    @property
2191    def quoted(self) -> bool:
2192        return bool(self.args.get("quoted"))
hashable_args: Any
2194    @property
2195    def hashable_args(self) -> t.Any:
2196        return (self.this, self.quoted)
output_name: str
2198    @property
2199    def output_name(self) -> str:
2200        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):
2204class Opclass(Expression):
2205    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
class Index(Expression):
2208class Index(Expression):
2209    arg_types = {
2210        "this": False,
2211        "table": False,
2212        "unique": False,
2213        "primary": False,
2214        "amp": False,  # teradata
2215        "params": False,
2216    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
class IndexParameters(Expression):
2219class IndexParameters(Expression):
2220    arg_types = {
2221        "using": False,
2222        "include": False,
2223        "columns": False,
2224        "with_storage": False,
2225        "partition_by": False,
2226        "tablespace": False,
2227        "where": False,
2228        "on": False,
2229    }
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):
2232class Insert(DDL, DML):
2233    arg_types = {
2234        "hint": False,
2235        "with": False,
2236        "is_function": False,
2237        "this": False,
2238        "expression": False,
2239        "conflict": False,
2240        "returning": False,
2241        "overwrite": False,
2242        "exists": False,
2243        "alternative": False,
2244        "where": False,
2245        "ignore": False,
2246        "by_name": False,
2247        "stored": False,
2248        "partition": False,
2249        "settings": False,
2250        "source": False,
2251    }
2252
2253    def with_(
2254        self,
2255        alias: ExpOrStr,
2256        as_: ExpOrStr,
2257        recursive: t.Optional[bool] = None,
2258        materialized: t.Optional[bool] = None,
2259        append: bool = True,
2260        dialect: DialectType = None,
2261        copy: bool = True,
2262        **opts,
2263    ) -> Insert:
2264        """
2265        Append to or set the common table expressions.
2266
2267        Example:
2268            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2269            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2270
2271        Args:
2272            alias: the SQL code string to parse as the table name.
2273                If an `Expression` instance is passed, this is used as-is.
2274            as_: the SQL code string to parse as the table expression.
2275                If an `Expression` instance is passed, it will be used as-is.
2276            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2277            materialized: set the MATERIALIZED part of the expression.
2278            append: if `True`, add to any existing expressions.
2279                Otherwise, this resets the expressions.
2280            dialect: the dialect used to parse the input expression.
2281            copy: if `False`, modify this expression instance in-place.
2282            opts: other options to use to parse the input expressions.
2283
2284        Returns:
2285            The modified expression.
2286        """
2287        return _apply_cte_builder(
2288            self,
2289            alias,
2290            as_,
2291            recursive=recursive,
2292            materialized=materialized,
2293            append=append,
2294            dialect=dialect,
2295            copy=copy,
2296            **opts,
2297        )
arg_types = {'hint': False, 'with': False, 'is_function': False, 'this': False, 'expression': False, 'conflict': False, 'returning': False, 'overwrite': False, 'exists': False, 'alternative': False, 'where': False, 'ignore': False, 'by_name': False, 'stored': False, 'partition': False, 'settings': False, 'source': False}
def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
2253    def with_(
2254        self,
2255        alias: ExpOrStr,
2256        as_: ExpOrStr,
2257        recursive: t.Optional[bool] = None,
2258        materialized: t.Optional[bool] = None,
2259        append: bool = True,
2260        dialect: DialectType = None,
2261        copy: bool = True,
2262        **opts,
2263    ) -> Insert:
2264        """
2265        Append to or set the common table expressions.
2266
2267        Example:
2268            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
2269            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
2270
2271        Args:
2272            alias: the SQL code string to parse as the table name.
2273                If an `Expression` instance is passed, this is used as-is.
2274            as_: the SQL code string to parse as the table expression.
2275                If an `Expression` instance is passed, it will be used as-is.
2276            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
2277            materialized: set the MATERIALIZED part of the expression.
2278            append: if `True`, add to any existing expressions.
2279                Otherwise, this resets the expressions.
2280            dialect: the dialect used to parse the input expression.
2281            copy: if `False`, modify this expression instance in-place.
2282            opts: other options to use to parse the input expressions.
2283
2284        Returns:
2285            The modified expression.
2286        """
2287        return _apply_cte_builder(
2288            self,
2289            alias,
2290            as_,
2291            recursive=recursive,
2292            materialized=materialized,
2293            append=append,
2294            dialect=dialect,
2295            copy=copy,
2296            **opts,
2297        )

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):
2300class ConditionalInsert(Expression):
2301    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
class MultitableInserts(Expression):
2304class MultitableInserts(Expression):
2305    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
class OnConflict(Expression):
2308class OnConflict(Expression):
2309    arg_types = {
2310        "duplicate": False,
2311        "expressions": False,
2312        "action": False,
2313        "conflict_keys": False,
2314        "constraint": False,
2315        "where": False,
2316    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'constraint': False, 'where': False}
key = 'onconflict'
class OnCondition(Expression):
2319class OnCondition(Expression):
2320    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
class Returning(Expression):
2323class Returning(Expression):
2324    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
class Introducer(Expression):
2328class Introducer(Expression):
2329    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
class National(Expression):
2333class National(Expression):
2334    pass
key = 'national'
class LoadData(Expression):
2337class LoadData(Expression):
2338    arg_types = {
2339        "this": True,
2340        "local": False,
2341        "overwrite": False,
2342        "inpath": True,
2343        "partition": False,
2344        "input_format": False,
2345        "serde": False,
2346    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
class Partition(Expression):
2349class Partition(Expression):
2350    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
class PartitionRange(Expression):
2353class PartitionRange(Expression):
2354    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionrange'
class PartitionId(Expression):
2358class PartitionId(Expression):
2359    pass
key = 'partitionid'
class Fetch(Expression):
2362class Fetch(Expression):
2363    arg_types = {
2364        "direction": False,
2365        "count": False,
2366        "limit_options": False,
2367    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
class Grant(Expression):
2370class Grant(Expression):
2371    arg_types = {
2372        "privileges": True,
2373        "kind": False,
2374        "securable": True,
2375        "principals": True,
2376        "grant_option": False,
2377    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
class Group(Expression):
2380class Group(Expression):
2381    arg_types = {
2382        "expressions": False,
2383        "grouping_sets": False,
2384        "cube": False,
2385        "rollup": False,
2386        "totals": False,
2387        "all": False,
2388    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
class Cube(Expression):
2391class Cube(Expression):
2392    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
class Rollup(Expression):
2395class Rollup(Expression):
2396    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
class GroupingSets(Expression):
2399class GroupingSets(Expression):
2400    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
class Lambda(Expression):
2403class Lambda(Expression):
2404    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'lambda'
class Limit(Expression):
2407class Limit(Expression):
2408    arg_types = {
2409        "this": False,
2410        "expression": True,
2411        "offset": False,
2412        "limit_options": False,
2413        "expressions": False,
2414    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
class LimitOptions(Expression):
2417class LimitOptions(Expression):
2418    arg_types = {
2419        "percent": False,
2420        "rows": False,
2421        "with_ties": False,
2422    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
class Literal(Condition):
2425class Literal(Condition):
2426    arg_types = {"this": True, "is_string": True}
2427
2428    @property
2429    def hashable_args(self) -> t.Any:
2430        return (self.this, self.args.get("is_string"))
2431
2432    @classmethod
2433    def number(cls, number) -> Literal:
2434        return cls(this=str(number), is_string=False)
2435
2436    @classmethod
2437    def string(cls, string) -> Literal:
2438        return cls(this=str(string), is_string=True)
2439
2440    @property
2441    def output_name(self) -> str:
2442        return self.name
2443
2444    def to_py(self) -> int | str | Decimal:
2445        if self.is_number:
2446            try:
2447                return int(self.this)
2448            except ValueError:
2449                return Decimal(self.this)
2450        return self.this
arg_types = {'this': True, 'is_string': True}
hashable_args: Any
2428    @property
2429    def hashable_args(self) -> t.Any:
2430        return (self.this, self.args.get("is_string"))
@classmethod
def number(cls, number) -> Literal:
2432    @classmethod
2433    def number(cls, number) -> Literal:
2434        return cls(this=str(number), is_string=False)
@classmethod
def string(cls, string) -> Literal:
2436    @classmethod
2437    def string(cls, string) -> Literal:
2438        return cls(this=str(string), is_string=True)
output_name: str
2440    @property
2441    def output_name(self) -> str:
2442        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:
2444    def to_py(self) -> int | str | Decimal:
2445        if self.is_number:
2446            try:
2447                return int(self.this)
2448            except ValueError:
2449                return Decimal(self.this)
2450        return self.this

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2453class Join(Expression):
2454    arg_types = {
2455        "this": True,
2456        "on": False,
2457        "side": False,
2458        "kind": False,
2459        "using": False,
2460        "method": False,
2461        "global": False,
2462        "hint": False,
2463        "match_condition": False,  # Snowflake
2464        "expressions": False,
2465    }
2466
2467    @property
2468    def method(self) -> str:
2469        return self.text("method").upper()
2470
2471    @property
2472    def kind(self) -> str:
2473        return self.text("kind").upper()
2474
2475    @property
2476    def side(self) -> str:
2477        return self.text("side").upper()
2478
2479    @property
2480    def hint(self) -> str:
2481        return self.text("hint").upper()
2482
2483    @property
2484    def alias_or_name(self) -> str:
2485        return self.this.alias_or_name
2486
2487    @property
2488    def is_semi_or_anti_join(self) -> bool:
2489        return self.kind in ("SEMI", "ANTI")
2490
2491    def on(
2492        self,
2493        *expressions: t.Optional[ExpOrStr],
2494        append: bool = True,
2495        dialect: DialectType = None,
2496        copy: bool = True,
2497        **opts,
2498    ) -> Join:
2499        """
2500        Append to or set the ON expressions.
2501
2502        Example:
2503            >>> import sqlglot
2504            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2505            'JOIN x ON y = 1'
2506
2507        Args:
2508            *expressions: the SQL code strings to parse.
2509                If an `Expression` instance is passed, it will be used as-is.
2510                Multiple expressions are combined with an AND operator.
2511            append: if `True`, AND the new expressions to any existing expression.
2512                Otherwise, this resets the expression.
2513            dialect: the dialect used to parse the input expressions.
2514            copy: if `False`, modify this expression instance in-place.
2515            opts: other options to use to parse the input expressions.
2516
2517        Returns:
2518            The modified Join expression.
2519        """
2520        join = _apply_conjunction_builder(
2521            *expressions,
2522            instance=self,
2523            arg="on",
2524            append=append,
2525            dialect=dialect,
2526            copy=copy,
2527            **opts,
2528        )
2529
2530        if join.kind == "CROSS":
2531            join.set("kind", None)
2532
2533        return join
2534
2535    def using(
2536        self,
2537        *expressions: t.Optional[ExpOrStr],
2538        append: bool = True,
2539        dialect: DialectType = None,
2540        copy: bool = True,
2541        **opts,
2542    ) -> Join:
2543        """
2544        Append to or set the USING expressions.
2545
2546        Example:
2547            >>> import sqlglot
2548            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2549            'JOIN x USING (foo, bla)'
2550
2551        Args:
2552            *expressions: the SQL code strings to parse.
2553                If an `Expression` instance is passed, it will be used as-is.
2554            append: if `True`, concatenate the new expressions to the existing "using" list.
2555                Otherwise, this resets the expression.
2556            dialect: the dialect used to parse the input expressions.
2557            copy: if `False`, modify this expression instance in-place.
2558            opts: other options to use to parse the input expressions.
2559
2560        Returns:
2561            The modified Join expression.
2562        """
2563        join = _apply_list_builder(
2564            *expressions,
2565            instance=self,
2566            arg="using",
2567            append=append,
2568            dialect=dialect,
2569            copy=copy,
2570            **opts,
2571        )
2572
2573        if join.kind == "CROSS":
2574            join.set("kind", None)
2575
2576        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
2467    @property
2468    def method(self) -> str:
2469        return self.text("method").upper()
kind: str
2471    @property
2472    def kind(self) -> str:
2473        return self.text("kind").upper()
side: str
2475    @property
2476    def side(self) -> str:
2477        return self.text("side").upper()
hint: str
2479    @property
2480    def hint(self) -> str:
2481        return self.text("hint").upper()
alias_or_name: str
2483    @property
2484    def alias_or_name(self) -> str:
2485        return self.this.alias_or_name
is_semi_or_anti_join: bool
2487    @property
2488    def is_semi_or_anti_join(self) -> bool:
2489        return self.kind in ("SEMI", "ANTI")
def on( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2491    def on(
2492        self,
2493        *expressions: t.Optional[ExpOrStr],
2494        append: bool = True,
2495        dialect: DialectType = None,
2496        copy: bool = True,
2497        **opts,
2498    ) -> Join:
2499        """
2500        Append to or set the ON expressions.
2501
2502        Example:
2503            >>> import sqlglot
2504            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2505            'JOIN x ON y = 1'
2506
2507        Args:
2508            *expressions: the SQL code strings to parse.
2509                If an `Expression` instance is passed, it will be used as-is.
2510                Multiple expressions are combined with an AND operator.
2511            append: if `True`, AND the new expressions to any existing expression.
2512                Otherwise, this resets the expression.
2513            dialect: the dialect used to parse the input expressions.
2514            copy: if `False`, modify this expression instance in-place.
2515            opts: other options to use to parse the input expressions.
2516
2517        Returns:
2518            The modified Join expression.
2519        """
2520        join = _apply_conjunction_builder(
2521            *expressions,
2522            instance=self,
2523            arg="on",
2524            append=append,
2525            dialect=dialect,
2526            copy=copy,
2527            **opts,
2528        )
2529
2530        if join.kind == "CROSS":
2531            join.set("kind", None)
2532
2533        return join

Append to or set the ON expressions.

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

The modified Join expression.

def using( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Join:
2535    def using(
2536        self,
2537        *expressions: t.Optional[ExpOrStr],
2538        append: bool = True,
2539        dialect: DialectType = None,
2540        copy: bool = True,
2541        **opts,
2542    ) -> Join:
2543        """
2544        Append to or set the USING expressions.
2545
2546        Example:
2547            >>> import sqlglot
2548            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2549            'JOIN x USING (foo, bla)'
2550
2551        Args:
2552            *expressions: the SQL code strings to parse.
2553                If an `Expression` instance is passed, it will be used as-is.
2554            append: if `True`, concatenate the new expressions to the existing "using" list.
2555                Otherwise, this resets the expression.
2556            dialect: the dialect used to parse the input expressions.
2557            copy: if `False`, modify this expression instance in-place.
2558            opts: other options to use to parse the input expressions.
2559
2560        Returns:
2561            The modified Join expression.
2562        """
2563        join = _apply_list_builder(
2564            *expressions,
2565            instance=self,
2566            arg="using",
2567            append=append,
2568            dialect=dialect,
2569            copy=copy,
2570            **opts,
2571        )
2572
2573        if join.kind == "CROSS":
2574            join.set("kind", None)
2575
2576        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):
2579class Lateral(UDTF):
2580    arg_types = {
2581        "this": True,
2582        "view": False,
2583        "outer": False,
2584        "alias": False,
2585        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2586    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2589class MatchRecognizeMeasure(Expression):
2590    arg_types = {
2591        "this": True,
2592        "window_frame": False,
2593    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2596class MatchRecognize(Expression):
2597    arg_types = {
2598        "partition_by": False,
2599        "order": False,
2600        "measures": False,
2601        "rows": False,
2602        "after": False,
2603        "pattern": False,
2604        "define": False,
2605        "alias": False,
2606    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2611class Final(Expression):
2612    pass
key = 'final'
class Offset(Expression):
2615class Offset(Expression):
2616    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2619class Order(Expression):
2620    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2624class WithFill(Expression):
2625    arg_types = {
2626        "from": False,
2627        "to": False,
2628        "step": False,
2629        "interpolate": False,
2630    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2635class Cluster(Order):
2636    pass
key = 'cluster'
class Distribute(Order):
2639class Distribute(Order):
2640    pass
key = 'distribute'
class Sort(Order):
2643class Sort(Order):
2644    pass
key = 'sort'
class Ordered(Expression):
2647class Ordered(Expression):
2648    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):
2651class Property(Expression):
2652    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2655class GrantPrivilege(Expression):
2656    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2659class GrantPrincipal(Expression):
2660    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2663class AllowedValuesProperty(Expression):
2664    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2667class AlgorithmProperty(Property):
2668    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2671class AutoIncrementProperty(Property):
2672    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2676class AutoRefreshProperty(Property):
2677    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2680class BackupProperty(Property):
2681    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2684class BlockCompressionProperty(Property):
2685    arg_types = {
2686        "autotemp": False,
2687        "always": False,
2688        "default": False,
2689        "manual": False,
2690        "never": False,
2691    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2694class CharacterSetProperty(Property):
2695    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2698class ChecksumProperty(Property):
2699    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2702class CollateProperty(Property):
2703    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2706class CopyGrantsProperty(Property):
2707    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2710class DataBlocksizeProperty(Property):
2711    arg_types = {
2712        "size": False,
2713        "units": False,
2714        "minimum": False,
2715        "maximum": False,
2716        "default": False,
2717    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2720class DataDeletionProperty(Property):
2721    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):
2724class DefinerProperty(Property):
2725    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2728class DistKeyProperty(Property):
2729    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2734class DistributedByProperty(Property):
2735    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):
2738class DistStyleProperty(Property):
2739    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2742class DuplicateKeyProperty(Property):
2743    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2746class EngineProperty(Property):
2747    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2750class HeapProperty(Property):
2751    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2754class ToTableProperty(Property):
2755    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2758class ExecuteAsProperty(Property):
2759    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2762class ExternalProperty(Property):
2763    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2766class FallbackProperty(Property):
2767    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2770class FileFormatProperty(Property):
2771    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2774class FreespaceProperty(Property):
2775    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2778class GlobalProperty(Property):
2779    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2782class IcebergProperty(Property):
2783    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2786class InheritsProperty(Property):
2787    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2790class InputModelProperty(Property):
2791    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2794class OutputModelProperty(Property):
2795    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2798class IsolatedLoadingProperty(Property):
2799    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2802class JournalProperty(Property):
2803    arg_types = {
2804        "no": False,
2805        "dual": False,
2806        "before": False,
2807        "local": False,
2808        "after": False,
2809    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2812class LanguageProperty(Property):
2813    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2817class ClusteredByProperty(Property):
2818    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2821class DictProperty(Property):
2822    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2825class DictSubProperty(Property):
2826    pass
key = 'dictsubproperty'
class DictRange(Property):
2829class DictRange(Property):
2830    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2833class DynamicProperty(Property):
2834    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2839class OnCluster(Property):
2840    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2844class EmptyProperty(Property):
2845    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2848class LikeProperty(Property):
2849    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2852class LocationProperty(Property):
2853    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2856class LockProperty(Property):
2857    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2860class LockingProperty(Property):
2861    arg_types = {
2862        "this": False,
2863        "kind": True,
2864        "for_or_in": False,
2865        "lock_type": True,
2866        "override": False,
2867    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2870class LogProperty(Property):
2871    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2874class MaterializedProperty(Property):
2875    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2878class MergeBlockRatioProperty(Property):
2879    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):
2882class NoPrimaryIndexProperty(Property):
2883    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2886class OnProperty(Property):
2887    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2890class OnCommitProperty(Property):
2891    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2894class PartitionedByProperty(Property):
2895    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionByRangeProperty(Property):
2899class PartitionByRangeProperty(Property):
2900    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
2904class PartitionByRangePropertyDynamic(Expression):
2905    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):
2909class UniqueKeyProperty(Property):
2910    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
2914class PartitionBoundSpec(Expression):
2915    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2916    arg_types = {
2917        "this": False,
2918        "expression": False,
2919        "from_expressions": False,
2920        "to_expressions": False,
2921    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2924class PartitionedOfProperty(Property):
2925    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2926    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2929class StreamingTableProperty(Property):
2930    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2933class RemoteWithConnectionModelProperty(Property):
2934    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2937class ReturnsProperty(Property):
2938    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):
2941class StrictProperty(Property):
2942    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2945class RowFormatProperty(Property):
2946    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2949class RowFormatDelimitedProperty(Property):
2950    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2951    arg_types = {
2952        "fields": False,
2953        "escaped": False,
2954        "collection_items": False,
2955        "map_keys": False,
2956        "lines": False,
2957        "null": False,
2958        "serde": False,
2959    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2962class RowFormatSerdeProperty(Property):
2963    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2967class QueryTransform(Expression):
2968    arg_types = {
2969        "expressions": True,
2970        "command_script": True,
2971        "schema": False,
2972        "row_format_before": False,
2973        "record_writer": False,
2974        "row_format_after": False,
2975        "record_reader": False,
2976    }
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):
2979class SampleProperty(Property):
2980    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2984class SecurityProperty(Property):
2985    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2988class SchemaCommentProperty(Property):
2989    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2992class SerdeProperties(Property):
2993    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2996class SetProperty(Property):
2997    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3000class SharingProperty(Property):
3001    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3004class SetConfigProperty(Property):
3005    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3008class SettingsProperty(Property):
3009    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3012class SortKeyProperty(Property):
3013    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3016class SqlReadWriteProperty(Property):
3017    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3020class SqlSecurityProperty(Property):
3021    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3024class StabilityProperty(Property):
3025    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
3028class TemporaryProperty(Property):
3029    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3032class SecureProperty(Property):
3033    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3037class Tags(ColumnConstraintKind, Property):
3038    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3041class TransformModelProperty(Property):
3042    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3045class TransientProperty(Property):
3046    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3049class UnloggedProperty(Property):
3050    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
3054class ViewAttributeProperty(Property):
3055    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3058class VolatileProperty(Property):
3059    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3062class WithDataProperty(Property):
3063    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3066class WithJournalTableProperty(Property):
3067    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3070class WithSchemaBindingProperty(Property):
3071    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3074class WithSystemVersioningProperty(Property):
3075    arg_types = {
3076        "on": False,
3077        "this": False,
3078        "data_consistency": False,
3079        "retention_period": False,
3080        "with": True,
3081    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3084class WithProcedureOptions(Property):
3085    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3088class EncodeProperty(Property):
3089    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3092class IncludeProperty(Property):
3093    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class Properties(Expression):
3096class Properties(Expression):
3097    arg_types = {"expressions": True}
3098
3099    NAME_TO_PROPERTY = {
3100        "ALGORITHM": AlgorithmProperty,
3101        "AUTO_INCREMENT": AutoIncrementProperty,
3102        "CHARACTER SET": CharacterSetProperty,
3103        "CLUSTERED_BY": ClusteredByProperty,
3104        "COLLATE": CollateProperty,
3105        "COMMENT": SchemaCommentProperty,
3106        "DEFINER": DefinerProperty,
3107        "DISTKEY": DistKeyProperty,
3108        "DISTRIBUTED_BY": DistributedByProperty,
3109        "DISTSTYLE": DistStyleProperty,
3110        "ENGINE": EngineProperty,
3111        "EXECUTE AS": ExecuteAsProperty,
3112        "FORMAT": FileFormatProperty,
3113        "LANGUAGE": LanguageProperty,
3114        "LOCATION": LocationProperty,
3115        "LOCK": LockProperty,
3116        "PARTITIONED_BY": PartitionedByProperty,
3117        "RETURNS": ReturnsProperty,
3118        "ROW_FORMAT": RowFormatProperty,
3119        "SORTKEY": SortKeyProperty,
3120        "ENCODE": EncodeProperty,
3121        "INCLUDE": IncludeProperty,
3122    }
3123
3124    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3125
3126    # CREATE property locations
3127    # Form: schema specified
3128    #   create [POST_CREATE]
3129    #     table a [POST_NAME]
3130    #     (b int) [POST_SCHEMA]
3131    #     with ([POST_WITH])
3132    #     index (b) [POST_INDEX]
3133    #
3134    # Form: alias selection
3135    #   create [POST_CREATE]
3136    #     table a [POST_NAME]
3137    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3138    #     index (c) [POST_INDEX]
3139    class Location(AutoName):
3140        POST_CREATE = auto()
3141        POST_NAME = auto()
3142        POST_SCHEMA = auto()
3143        POST_WITH = auto()
3144        POST_ALIAS = auto()
3145        POST_EXPRESSION = auto()
3146        POST_INDEX = auto()
3147        UNSUPPORTED = auto()
3148
3149    @classmethod
3150    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3151        expressions = []
3152        for key, value in properties_dict.items():
3153            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3154            if property_cls:
3155                expressions.append(property_cls(this=convert(value)))
3156            else:
3157                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3158
3159        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:
3149    @classmethod
3150    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3151        expressions = []
3152        for key, value in properties_dict.items():
3153            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3154            if property_cls:
3155                expressions.append(property_cls(this=convert(value)))
3156            else:
3157                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3158
3159        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3139    class Location(AutoName):
3140        POST_CREATE = auto()
3141        POST_NAME = auto()
3142        POST_SCHEMA = auto()
3143        POST_WITH = auto()
3144        POST_ALIAS = auto()
3145        POST_EXPRESSION = auto()
3146        POST_INDEX = auto()
3147        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):
3162class Qualify(Expression):
3163    pass
key = 'qualify'
class InputOutputFormat(Expression):
3166class InputOutputFormat(Expression):
3167    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3171class Return(Expression):
3172    pass
key = 'return'
class Reference(Expression):
3175class Reference(Expression):
3176    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3179class Tuple(Expression):
3180    arg_types = {"expressions": False}
3181
3182    def isin(
3183        self,
3184        *expressions: t.Any,
3185        query: t.Optional[ExpOrStr] = None,
3186        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3187        copy: bool = True,
3188        **opts,
3189    ) -> In:
3190        return In(
3191            this=maybe_copy(self, copy),
3192            expressions=[convert(e, copy=copy) for e in expressions],
3193            query=maybe_parse(query, copy=copy, **opts) if query else None,
3194            unnest=(
3195                Unnest(
3196                    expressions=[
3197                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3198                        for e in ensure_list(unnest)
3199                    ]
3200                )
3201                if unnest
3202                else None
3203            ),
3204        )
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:
3182    def isin(
3183        self,
3184        *expressions: t.Any,
3185        query: t.Optional[ExpOrStr] = None,
3186        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3187        copy: bool = True,
3188        **opts,
3189    ) -> In:
3190        return In(
3191            this=maybe_copy(self, copy),
3192            expressions=[convert(e, copy=copy) for e in expressions],
3193            query=maybe_parse(query, copy=copy, **opts) if query else None,
3194            unnest=(
3195                Unnest(
3196                    expressions=[
3197                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3198                        for e in ensure_list(unnest)
3199                    ]
3200                )
3201                if unnest
3202                else None
3203            ),
3204        )
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):
3235class QueryOption(Expression):
3236    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3240class WithTableHint(Expression):
3241    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3245class IndexTableHint(Expression):
3246    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3250class HistoricalData(Expression):
3251    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3254class Table(Expression):
3255    arg_types = {
3256        "this": False,
3257        "alias": False,
3258        "db": False,
3259        "catalog": False,
3260        "laterals": False,
3261        "joins": False,
3262        "pivots": False,
3263        "hints": False,
3264        "system_time": False,
3265        "version": False,
3266        "format": False,
3267        "pattern": False,
3268        "ordinality": False,
3269        "when": False,
3270        "only": False,
3271        "partition": False,
3272        "changes": False,
3273        "rows_from": False,
3274        "sample": False,
3275    }
3276
3277    @property
3278    def name(self) -> str:
3279        if not self.this or isinstance(self.this, Func):
3280            return ""
3281        return self.this.name
3282
3283    @property
3284    def db(self) -> str:
3285        return self.text("db")
3286
3287    @property
3288    def catalog(self) -> str:
3289        return self.text("catalog")
3290
3291    @property
3292    def selects(self) -> t.List[Expression]:
3293        return []
3294
3295    @property
3296    def named_selects(self) -> t.List[str]:
3297        return []
3298
3299    @property
3300    def parts(self) -> t.List[Expression]:
3301        """Return the parts of a table in order catalog, db, table."""
3302        parts: t.List[Expression] = []
3303
3304        for arg in ("catalog", "db", "this"):
3305            part = self.args.get(arg)
3306
3307            if isinstance(part, Dot):
3308                parts.extend(part.flatten())
3309            elif isinstance(part, Expression):
3310                parts.append(part)
3311
3312        return parts
3313
3314    def to_column(self, copy: bool = True) -> Expression:
3315        parts = self.parts
3316        last_part = parts[-1]
3317
3318        if isinstance(last_part, Identifier):
3319            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3320        else:
3321            # This branch will be reached if a function or array is wrapped in a `Table`
3322            col = last_part
3323
3324        alias = self.args.get("alias")
3325        if alias:
3326            col = alias_(col, alias.this, copy=copy)
3327
3328        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
3277    @property
3278    def name(self) -> str:
3279        if not self.this or isinstance(self.this, Func):
3280            return ""
3281        return self.this.name
db: str
3283    @property
3284    def db(self) -> str:
3285        return self.text("db")
catalog: str
3287    @property
3288    def catalog(self) -> str:
3289        return self.text("catalog")
selects: List[Expression]
3291    @property
3292    def selects(self) -> t.List[Expression]:
3293        return []
named_selects: List[str]
3295    @property
3296    def named_selects(self) -> t.List[str]:
3297        return []
parts: List[Expression]
3299    @property
3300    def parts(self) -> t.List[Expression]:
3301        """Return the parts of a table in order catalog, db, table."""
3302        parts: t.List[Expression] = []
3303
3304        for arg in ("catalog", "db", "this"):
3305            part = self.args.get(arg)
3306
3307            if isinstance(part, Dot):
3308                parts.extend(part.flatten())
3309            elif isinstance(part, Expression):
3310                parts.append(part)
3311
3312        return parts

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

def to_column(self, copy: bool = True) -> Expression:
3314    def to_column(self, copy: bool = True) -> Expression:
3315        parts = self.parts
3316        last_part = parts[-1]
3317
3318        if isinstance(last_part, Identifier):
3319            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3320        else:
3321            # This branch will be reached if a function or array is wrapped in a `Table`
3322            col = last_part
3323
3324        alias = self.args.get("alias")
3325        if alias:
3326            col = alias_(col, alias.this, copy=copy)
3327
3328        return col
key = 'table'
class SetOperation(Query):
3331class SetOperation(Query):
3332    arg_types = {
3333        "with": False,
3334        "this": True,
3335        "expression": True,
3336        "distinct": False,
3337        "by_name": False,
3338        **QUERY_MODIFIERS,
3339    }
3340
3341    def select(
3342        self: S,
3343        *expressions: t.Optional[ExpOrStr],
3344        append: bool = True,
3345        dialect: DialectType = None,
3346        copy: bool = True,
3347        **opts,
3348    ) -> S:
3349        this = maybe_copy(self, copy)
3350        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3351        this.expression.unnest().select(
3352            *expressions, append=append, dialect=dialect, copy=False, **opts
3353        )
3354        return this
3355
3356    @property
3357    def named_selects(self) -> t.List[str]:
3358        return self.this.unnest().named_selects
3359
3360    @property
3361    def is_star(self) -> bool:
3362        return self.this.is_star or self.expression.is_star
3363
3364    @property
3365    def selects(self) -> t.List[Expression]:
3366        return self.this.unnest().selects
3367
3368    @property
3369    def left(self) -> Query:
3370        return self.this
3371
3372    @property
3373    def right(self) -> Query:
3374        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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~S:
3341    def select(
3342        self: S,
3343        *expressions: t.Optional[ExpOrStr],
3344        append: bool = True,
3345        dialect: DialectType = None,
3346        copy: bool = True,
3347        **opts,
3348    ) -> S:
3349        this = maybe_copy(self, copy)
3350        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
3351        this.expression.unnest().select(
3352            *expressions, append=append, dialect=dialect, copy=False, **opts
3353        )
3354        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]
3356    @property
3357    def named_selects(self) -> t.List[str]:
3358        return self.this.unnest().named_selects

Returns the output names of the query's projections.

is_star: bool
3360    @property
3361    def is_star(self) -> bool:
3362        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: List[Expression]
3364    @property
3365    def selects(self) -> t.List[Expression]:
3366        return self.this.unnest().selects

Returns the query's projections.

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

Set the table to update.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • expression : the SQL code strings to parse. If a Table instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a Table.
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Update expression.

def set_( self, *expressions: Union[str, Expression], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3433    def set_(
3434        self,
3435        *expressions: ExpOrStr,
3436        append: bool = True,
3437        dialect: DialectType = None,
3438        copy: bool = True,
3439        **opts,
3440    ) -> Update:
3441        """
3442        Append to or set the SET expressions.
3443
3444        Example:
3445            >>> Update().table("my_table").set_("x = 1").sql()
3446            'UPDATE my_table SET x = 1'
3447
3448        Args:
3449            *expressions: the SQL code strings to parse.
3450                If `Expression` instance(s) are passed, they will be used as-is.
3451                Multiple expressions are combined with a comma.
3452            append: if `True`, add the new expressions to any existing SET expressions.
3453                Otherwise, this resets the expressions.
3454            dialect: the dialect used to parse the input expressions.
3455            copy: if `False`, modify this expression instance in-place.
3456            opts: other options to use to parse the input expressions.
3457        """
3458        return _apply_list_builder(
3459            *expressions,
3460            instance=self,
3461            arg="expressions",
3462            append=append,
3463            into=Expression,
3464            prefix=None,
3465            dialect=dialect,
3466            copy=copy,
3467            **opts,
3468        )

Append to or set the SET expressions.

Example:
>>> Update().table("my_table").set_("x = 1").sql()
'UPDATE my_table SET x = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If Expression instance(s) are passed, they will be used as-is. Multiple expressions are combined with a comma.
  • append: if True, add the new expressions to any existing SET expressions. Otherwise, this resets the expressions.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
def where( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3470    def where(
3471        self,
3472        *expressions: t.Optional[ExpOrStr],
3473        append: bool = True,
3474        dialect: DialectType = None,
3475        copy: bool = True,
3476        **opts,
3477    ) -> Select:
3478        """
3479        Append to or set the WHERE expressions.
3480
3481        Example:
3482            >>> Update().table("tbl").set_("x = 1").where("x = 'a' OR x < 'b'").sql()
3483            "UPDATE tbl SET x = 1 WHERE x = 'a' OR x < 'b'"
3484
3485        Args:
3486            *expressions: the SQL code strings to parse.
3487                If an `Expression` instance is passed, it will be used as-is.
3488                Multiple expressions are combined with an AND operator.
3489            append: if `True`, AND the new expressions to any existing expression.
3490                Otherwise, this resets the expression.
3491            dialect: the dialect used to parse the input expressions.
3492            copy: if `False`, modify this expression instance in-place.
3493            opts: other options to use to parse the input expressions.
3494
3495        Returns:
3496            Select: the modified expression.
3497        """
3498        return _apply_conjunction_builder(
3499            *expressions,
3500            instance=self,
3501            arg="where",
3502            append=append,
3503            into=Where,
3504            dialect=dialect,
3505            copy=copy,
3506            **opts,
3507        )

Append to or set the WHERE expressions.

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

Select: the modified expression.

def from_( self, expression: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3509    def from_(
3510        self,
3511        expression: t.Optional[ExpOrStr] = None,
3512        dialect: DialectType = None,
3513        copy: bool = True,
3514        **opts,
3515    ) -> Update:
3516        """
3517        Set the FROM expression.
3518
3519        Example:
3520            >>> Update().table("my_table").set_("x = 1").from_("baz").sql()
3521            'UPDATE my_table SET x = 1 FROM baz'
3522
3523        Args:
3524            expression : the SQL code strings to parse.
3525                If a `From` instance is passed, this is used as-is.
3526                If another `Expression` instance is passed, it will be wrapped in a `From`.
3527                If nothing is passed in then a from is not applied to the expression
3528            dialect: the dialect used to parse the input expression.
3529            copy: if `False`, modify this expression instance in-place.
3530            opts: other options to use to parse the input expressions.
3531
3532        Returns:
3533            The modified Update expression.
3534        """
3535        if not expression:
3536            return maybe_copy(self, copy)
3537
3538        return _apply_builder(
3539            expression=expression,
3540            instance=self,
3541            arg="from",
3542            into=From,
3543            prefix="FROM",
3544            dialect=dialect,
3545            copy=copy,
3546            **opts,
3547        )

Set the FROM expression.

Example:
>>> Update().table("my_table").set_("x = 1").from_("baz").sql()
'UPDATE my_table SET x = 1 FROM baz'
Arguments:
  • expression : the SQL code strings to parse. If a From instance is passed, this is used as-is. If another Expression instance is passed, it will be wrapped in a From. If nothing is passed in then a from is not applied to the expression
  • dialect: the dialect used to parse the input expression.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Update expression.

def with_( self, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Update:
3549    def with_(
3550        self,
3551        alias: ExpOrStr,
3552        as_: ExpOrStr,
3553        recursive: t.Optional[bool] = None,
3554        materialized: t.Optional[bool] = None,
3555        append: bool = True,
3556        dialect: DialectType = None,
3557        copy: bool = True,
3558        **opts,
3559    ) -> Update:
3560        """
3561        Append to or set the common table expressions.
3562
3563        Example:
3564            >>> Update().table("my_table").set_("x = 1").from_("baz").with_("baz", "SELECT id FROM foo").sql()
3565            'WITH baz AS (SELECT id FROM foo) UPDATE my_table SET x = 1 FROM baz'
3566
3567        Args:
3568            alias: the SQL code string to parse as the table name.
3569                If an `Expression` instance is passed, this is used as-is.
3570            as_: the SQL code string to parse as the table expression.
3571                If an `Expression` instance is passed, it will be used as-is.
3572            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
3573            materialized: set the MATERIALIZED part of the expression.
3574            append: if `True`, add to any existing expressions.
3575                Otherwise, this resets the expressions.
3576            dialect: the dialect used to parse the input expression.
3577            copy: if `False`, modify this expression instance in-place.
3578            opts: other options to use to parse the input expressions.
3579
3580        Returns:
3581            The modified expression.
3582        """
3583        return _apply_cte_builder(
3584            self,
3585            alias,
3586            as_,
3587            recursive=recursive,
3588            materialized=materialized,
3589            append=append,
3590            dialect=dialect,
3591            copy=copy,
3592            **opts,
3593        )

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

Set the FROM expression.

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

The modified Select expression.

def group_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3673    def group_by(
3674        self,
3675        *expressions: t.Optional[ExpOrStr],
3676        append: bool = True,
3677        dialect: DialectType = None,
3678        copy: bool = True,
3679        **opts,
3680    ) -> Select:
3681        """
3682        Set the GROUP BY expression.
3683
3684        Example:
3685            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
3686            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
3687
3688        Args:
3689            *expressions: the SQL code strings to parse.
3690                If a `Group` instance is passed, this is used as-is.
3691                If another `Expression` instance is passed, it will be wrapped in a `Group`.
3692                If nothing is passed in then a group by is not applied to the expression
3693            append: if `True`, add to any existing expressions.
3694                Otherwise, this flattens all the `Group` expression into a single expression.
3695            dialect: the dialect used to parse the input expression.
3696            copy: if `False`, modify this expression instance in-place.
3697            opts: other options to use to parse the input expressions.
3698
3699        Returns:
3700            The modified Select expression.
3701        """
3702        if not expressions:
3703            return self if not copy else self.copy()
3704
3705        return _apply_child_list_builder(
3706            *expressions,
3707            instance=self,
3708            arg="group",
3709            append=append,
3710            copy=copy,
3711            prefix="GROUP BY",
3712            into=Group,
3713            dialect=dialect,
3714            **opts,
3715        )

Set the GROUP BY expression.

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

The modified Select expression.

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

Set the SORT BY expression.

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

The modified Select expression.

def cluster_by( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3757    def cluster_by(
3758        self,
3759        *expressions: t.Optional[ExpOrStr],
3760        append: bool = True,
3761        dialect: DialectType = None,
3762        copy: bool = True,
3763        **opts,
3764    ) -> Select:
3765        """
3766        Set the CLUSTER BY expression.
3767
3768        Example:
3769            >>> Select().from_("tbl").select("x").cluster_by("x DESC").sql(dialect="hive")
3770            'SELECT x FROM tbl CLUSTER BY x DESC'
3771
3772        Args:
3773            *expressions: the SQL code strings to parse.
3774                If a `Group` instance is passed, this is used as-is.
3775                If another `Expression` instance is passed, it will be wrapped in a `Cluster`.
3776            append: if `True`, add to any existing expressions.
3777                Otherwise, this flattens all the `Order` expression into a single expression.
3778            dialect: the dialect used to parse the input expression.
3779            copy: if `False`, modify this expression instance in-place.
3780            opts: other options to use to parse the input expressions.
3781
3782        Returns:
3783            The modified Select expression.
3784        """
3785        return _apply_child_list_builder(
3786            *expressions,
3787            instance=self,
3788            arg="cluster",
3789            append=append,
3790            copy=copy,
3791            prefix="CLUSTER BY",
3792            into=Cluster,
3793            dialect=dialect,
3794            **opts,
3795        )

Set the CLUSTER BY expression.

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

The modified Select expression.

def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3797    def select(
3798        self,
3799        *expressions: t.Optional[ExpOrStr],
3800        append: bool = True,
3801        dialect: DialectType = None,
3802        copy: bool = True,
3803        **opts,
3804    ) -> Select:
3805        return _apply_list_builder(
3806            *expressions,
3807            instance=self,
3808            arg="expressions",
3809            append=append,
3810            dialect=dialect,
3811            into=Expression,
3812            copy=copy,
3813            **opts,
3814        )

Append to or set the SELECT expressions.

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

The modified Query expression.

def lateral( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3816    def lateral(
3817        self,
3818        *expressions: t.Optional[ExpOrStr],
3819        append: bool = True,
3820        dialect: DialectType = None,
3821        copy: bool = True,
3822        **opts,
3823    ) -> Select:
3824        """
3825        Append to or set the LATERAL expressions.
3826
3827        Example:
3828            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
3829            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
3830
3831        Args:
3832            *expressions: the SQL code strings to parse.
3833                If an `Expression` instance is passed, it will be used as-is.
3834            append: if `True`, add to any existing expressions.
3835                Otherwise, this resets the expressions.
3836            dialect: the dialect used to parse the input expressions.
3837            copy: if `False`, modify this expression instance in-place.
3838            opts: other options to use to parse the input expressions.
3839
3840        Returns:
3841            The modified Select expression.
3842        """
3843        return _apply_list_builder(
3844            *expressions,
3845            instance=self,
3846            arg="laterals",
3847            append=append,
3848            into=Lateral,
3849            prefix="LATERAL VIEW",
3850            dialect=dialect,
3851            copy=copy,
3852            **opts,
3853        )

Append to or set the LATERAL expressions.

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

The modified Select expression.

def join( self, expression: Union[str, Expression], on: Union[str, Expression, NoneType] = None, using: Union[str, Expression, Collection[Union[str, Expression]], NoneType] = None, append: bool = True, join_type: Optional[str] = None, join_alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3855    def join(
3856        self,
3857        expression: ExpOrStr,
3858        on: t.Optional[ExpOrStr] = None,
3859        using: t.Optional[ExpOrStr | t.Collection[ExpOrStr]] = None,
3860        append: bool = True,
3861        join_type: t.Optional[str] = None,
3862        join_alias: t.Optional[Identifier | str] = None,
3863        dialect: DialectType = None,
3864        copy: bool = True,
3865        **opts,
3866    ) -> Select:
3867        """
3868        Append to or set the JOIN expressions.
3869
3870        Example:
3871            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
3872            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
3873
3874            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
3875            'SELECT 1 FROM a JOIN b USING (x, y, z)'
3876
3877            Use `join_type` to change the type of join:
3878
3879            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
3880            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
3881
3882        Args:
3883            expression: the SQL code string to parse.
3884                If an `Expression` instance is passed, it will be used as-is.
3885            on: optionally specify the join "on" criteria as a SQL string.
3886                If an `Expression` instance is passed, it will be used as-is.
3887            using: optionally specify the join "using" criteria as a SQL string.
3888                If an `Expression` instance is passed, it will be used as-is.
3889            append: if `True`, add to any existing expressions.
3890                Otherwise, this resets the expressions.
3891            join_type: if set, alter the parsed join type.
3892            join_alias: an optional alias for the joined source.
3893            dialect: the dialect used to parse the input expressions.
3894            copy: if `False`, modify this expression instance in-place.
3895            opts: other options to use to parse the input expressions.
3896
3897        Returns:
3898            Select: the modified expression.
3899        """
3900        parse_args: t.Dict[str, t.Any] = {"dialect": dialect, **opts}
3901
3902        try:
3903            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
3904        except ParseError:
3905            expression = maybe_parse(expression, into=(Join, Expression), **parse_args)
3906
3907        join = expression if isinstance(expression, Join) else Join(this=expression)
3908
3909        if isinstance(join.this, Select):
3910            join.this.replace(join.this.subquery())
3911
3912        if join_type:
3913            method: t.Optional[Token]
3914            side: t.Optional[Token]
3915            kind: t.Optional[Token]
3916
3917            method, side, kind = maybe_parse(join_type, into="JOIN_TYPE", **parse_args)  # type: ignore
3918
3919            if method:
3920                join.set("method", method.text)
3921            if side:
3922                join.set("side", side.text)
3923            if kind:
3924                join.set("kind", kind.text)
3925
3926        if on:
3927            on = and_(*ensure_list(on), dialect=dialect, copy=copy, **opts)
3928            join.set("on", on)
3929
3930        if using:
3931            join = _apply_list_builder(
3932                *ensure_list(using),
3933                instance=join,
3934                arg="using",
3935                append=append,
3936                copy=copy,
3937                into=Identifier,
3938                **opts,
3939            )
3940
3941        if join_alias:
3942            join.set("this", alias_(join.this, join_alias, table=True))
3943
3944        return _apply_list_builder(
3945            join,
3946            instance=self,
3947            arg="joins",
3948            append=append,
3949            copy=copy,
3950            **opts,
3951        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3953    def where(
3954        self,
3955        *expressions: t.Optional[ExpOrStr],
3956        append: bool = True,
3957        dialect: DialectType = None,
3958        copy: bool = True,
3959        **opts,
3960    ) -> Select:
3961        """
3962        Append to or set the WHERE expressions.
3963
3964        Example:
3965            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
3966            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
3967
3968        Args:
3969            *expressions: the SQL code strings to parse.
3970                If an `Expression` instance is passed, it will be used as-is.
3971                Multiple expressions are combined with an AND operator.
3972            append: if `True`, AND the new expressions to any existing expression.
3973                Otherwise, this resets the expression.
3974            dialect: the dialect used to parse the input expressions.
3975            copy: if `False`, modify this expression instance in-place.
3976            opts: other options to use to parse the input expressions.
3977
3978        Returns:
3979            Select: the modified expression.
3980        """
3981        return _apply_conjunction_builder(
3982            *expressions,
3983            instance=self,
3984            arg="where",
3985            append=append,
3986            into=Where,
3987            dialect=dialect,
3988            copy=copy,
3989            **opts,
3990        )

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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
3992    def having(
3993        self,
3994        *expressions: t.Optional[ExpOrStr],
3995        append: bool = True,
3996        dialect: DialectType = None,
3997        copy: bool = True,
3998        **opts,
3999    ) -> Select:
4000        """
4001        Append to or set the HAVING expressions.
4002
4003        Example:
4004            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
4005            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
4006
4007        Args:
4008            *expressions: the SQL code strings to parse.
4009                If an `Expression` instance is passed, it will be used as-is.
4010                Multiple expressions are combined with an AND operator.
4011            append: if `True`, AND the new expressions to any existing expression.
4012                Otherwise, this resets the expression.
4013            dialect: the dialect used to parse the input expressions.
4014            copy: if `False`, modify this expression instance in-place.
4015            opts: other options to use to parse the input expressions.
4016
4017        Returns:
4018            The modified Select expression.
4019        """
4020        return _apply_conjunction_builder(
4021            *expressions,
4022            instance=self,
4023            arg="having",
4024            append=append,
4025            into=Having,
4026            dialect=dialect,
4027            copy=copy,
4028            **opts,
4029        )

Append to or set the HAVING expressions.

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

The modified Select expression.

def window( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4031    def window(
4032        self,
4033        *expressions: t.Optional[ExpOrStr],
4034        append: bool = True,
4035        dialect: DialectType = None,
4036        copy: bool = True,
4037        **opts,
4038    ) -> Select:
4039        return _apply_list_builder(
4040            *expressions,
4041            instance=self,
4042            arg="windows",
4043            append=append,
4044            into=Window,
4045            dialect=dialect,
4046            copy=copy,
4047            **opts,
4048        )
def qualify( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Select:
4050    def qualify(
4051        self,
4052        *expressions: t.Optional[ExpOrStr],
4053        append: bool = True,
4054        dialect: DialectType = None,
4055        copy: bool = True,
4056        **opts,
4057    ) -> Select:
4058        return _apply_conjunction_builder(
4059            *expressions,
4060            instance=self,
4061            arg="qualify",
4062            append=append,
4063            into=Qualify,
4064            dialect=dialect,
4065            copy=copy,
4066            **opts,
4067        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4069    def distinct(
4070        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4071    ) -> Select:
4072        """
4073        Set the OFFSET expression.
4074
4075        Example:
4076            >>> Select().from_("tbl").select("x").distinct().sql()
4077            'SELECT DISTINCT x FROM tbl'
4078
4079        Args:
4080            ons: the expressions to distinct on
4081            distinct: whether the Select should be distinct
4082            copy: if `False`, modify this expression instance in-place.
4083
4084        Returns:
4085            Select: the modified expression.
4086        """
4087        instance = maybe_copy(self, copy)
4088        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4089        instance.set("distinct", Distinct(on=on) if distinct else None)
4090        return instance

Set the OFFSET expression.

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

Select: the modified expression.

def ctas( self, table: Union[str, Expression], properties: Optional[Dict] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Create:
4092    def ctas(
4093        self,
4094        table: ExpOrStr,
4095        properties: t.Optional[t.Dict] = None,
4096        dialect: DialectType = None,
4097        copy: bool = True,
4098        **opts,
4099    ) -> Create:
4100        """
4101        Convert this expression to a CREATE TABLE AS statement.
4102
4103        Example:
4104            >>> Select().select("*").from_("tbl").ctas("x").sql()
4105            'CREATE TABLE x AS SELECT * FROM tbl'
4106
4107        Args:
4108            table: the SQL code string to parse as the table name.
4109                If another `Expression` instance is passed, it will be used as-is.
4110            properties: an optional mapping of table properties
4111            dialect: the dialect used to parse the input table.
4112            copy: if `False`, modify this expression instance in-place.
4113            opts: other options to use to parse the input table.
4114
4115        Returns:
4116            The new Create expression.
4117        """
4118        instance = maybe_copy(self, copy)
4119        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4120
4121        properties_expression = None
4122        if properties:
4123            properties_expression = Properties.from_dict(properties)
4124
4125        return Create(
4126            this=table_expression,
4127            kind="TABLE",
4128            expression=instance,
4129            properties=properties_expression,
4130        )

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:
4132    def lock(self, update: bool = True, copy: bool = True) -> Select:
4133        """
4134        Set the locking read mode for this expression.
4135
4136        Examples:
4137            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4138            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4139
4140            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4141            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4142
4143        Args:
4144            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4145            copy: if `False`, modify this expression instance in-place.
4146
4147        Returns:
4148            The modified expression.
4149        """
4150        inst = maybe_copy(self, copy)
4151        inst.set("locks", [Lock(update=update)])
4152
4153        return inst

Set the locking read mode for this expression.

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

The modified expression.

def hint( self, *hints: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Select:
4155    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4156        """
4157        Set hints for this expression.
4158
4159        Examples:
4160            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4161            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4162
4163        Args:
4164            hints: The SQL code strings to parse as the hints.
4165                If an `Expression` instance is passed, it will be used as-is.
4166            dialect: The dialect used to parse the hints.
4167            copy: If `False`, modify this expression instance in-place.
4168
4169        Returns:
4170            The modified expression.
4171        """
4172        inst = maybe_copy(self, copy)
4173        inst.set(
4174            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4175        )
4176
4177        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]
4179    @property
4180    def named_selects(self) -> t.List[str]:
4181        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
4183    @property
4184    def is_star(self) -> bool:
4185        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: List[Expression]
4187    @property
4188    def selects(self) -> t.List[Expression]:
4189        return self.expressions

Returns the query's projections.

key = 'select'
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
class Subquery(DerivedTable, Query):
4195class Subquery(DerivedTable, Query):
4196    arg_types = {
4197        "this": True,
4198        "alias": False,
4199        "with": False,
4200        **QUERY_MODIFIERS,
4201    }
4202
4203    def unnest(self):
4204        """Returns the first non subquery."""
4205        expression = self
4206        while isinstance(expression, Subquery):
4207            expression = expression.this
4208        return expression
4209
4210    def unwrap(self) -> Subquery:
4211        expression = self
4212        while expression.same_parent and expression.is_wrapper:
4213            expression = t.cast(Subquery, expression.parent)
4214        return expression
4215
4216    def select(
4217        self,
4218        *expressions: t.Optional[ExpOrStr],
4219        append: bool = True,
4220        dialect: DialectType = None,
4221        copy: bool = True,
4222        **opts,
4223    ) -> Subquery:
4224        this = maybe_copy(self, copy)
4225        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4226        return this
4227
4228    @property
4229    def is_wrapper(self) -> bool:
4230        """
4231        Whether this Subquery acts as a simple wrapper around another expression.
4232
4233        SELECT * FROM (((SELECT * FROM t)))
4234                      ^
4235                      This corresponds to a "wrapper" Subquery node
4236        """
4237        return all(v is None for k, v in self.args.items() if k != "this")
4238
4239    @property
4240    def is_star(self) -> bool:
4241        return self.this.is_star
4242
4243    @property
4244    def output_name(self) -> str:
4245        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):
4203    def unnest(self):
4204        """Returns the first non subquery."""
4205        expression = self
4206        while isinstance(expression, Subquery):
4207            expression = expression.this
4208        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
4210    def unwrap(self) -> Subquery:
4211        expression = self
4212        while expression.same_parent and expression.is_wrapper:
4213            expression = t.cast(Subquery, expression.parent)
4214        return expression
def select( self, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Subquery:
4216    def select(
4217        self,
4218        *expressions: t.Optional[ExpOrStr],
4219        append: bool = True,
4220        dialect: DialectType = None,
4221        copy: bool = True,
4222        **opts,
4223    ) -> Subquery:
4224        this = maybe_copy(self, copy)
4225        this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
4226        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
4228    @property
4229    def is_wrapper(self) -> bool:
4230        """
4231        Whether this Subquery acts as a simple wrapper around another expression.
4232
4233        SELECT * FROM (((SELECT * FROM t)))
4234                      ^
4235                      This corresponds to a "wrapper" Subquery node
4236        """
4237        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
4239    @property
4240    def is_star(self) -> bool:
4241        return self.this.is_star

Checks whether an expression is a star.

output_name: str
4243    @property
4244    def output_name(self) -> str:
4245        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):
4248class TableSample(Expression):
4249    arg_types = {
4250        "expressions": False,
4251        "method": False,
4252        "bucket_numerator": False,
4253        "bucket_denominator": False,
4254        "bucket_field": False,
4255        "percent": False,
4256        "rows": False,
4257        "size": False,
4258        "seed": False,
4259    }
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):
4262class Tag(Expression):
4263    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
4264
4265    arg_types = {
4266        "this": False,
4267        "prefix": False,
4268        "postfix": False,
4269    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key = 'tag'
class Pivot(Expression):
4274class Pivot(Expression):
4275    arg_types = {
4276        "this": False,
4277        "alias": False,
4278        "expressions": False,
4279        "field": False,
4280        "unpivot": False,
4281        "using": False,
4282        "group": False,
4283        "columns": False,
4284        "include_nulls": False,
4285        "default_on_null": False,
4286        "into": False,
4287    }
4288
4289    @property
4290    def unpivot(self) -> bool:
4291        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
4289    @property
4290    def unpivot(self) -> bool:
4291        return bool(self.args.get("unpivot"))
key = 'pivot'
class UnpivotColumns(Expression):
4296class UnpivotColumns(Expression):
4297    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'unpivotcolumns'
class Window(Condition):
4300class Window(Condition):
4301    arg_types = {
4302        "this": True,
4303        "partition_by": False,
4304        "order": False,
4305        "spec": False,
4306        "alias": False,
4307        "over": False,
4308        "first": False,
4309    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key = 'window'
class WindowSpec(Expression):
4312class WindowSpec(Expression):
4313    arg_types = {
4314        "kind": False,
4315        "start": False,
4316        "start_side": False,
4317        "end": False,
4318        "end_side": False,
4319    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False}
key = 'windowspec'
class PreWhere(Expression):
4322class PreWhere(Expression):
4323    pass
key = 'prewhere'
class Where(Expression):
4326class Where(Expression):
4327    pass
key = 'where'
class Star(Expression):
4330class Star(Expression):
4331    arg_types = {"except": False, "replace": False, "rename": False}
4332
4333    @property
4334    def name(self) -> str:
4335        return "*"
4336
4337    @property
4338    def output_name(self) -> str:
4339        return self.name
arg_types = {'except': False, 'replace': False, 'rename': False}
name: str
4333    @property
4334    def name(self) -> str:
4335        return "*"
output_name: str
4337    @property
4338    def output_name(self) -> str:
4339        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):
4342class Parameter(Condition):
4343    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'parameter'
class SessionParameter(Condition):
4346class SessionParameter(Condition):
4347    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'sessionparameter'
class Placeholder(Condition):
4350class Placeholder(Condition):
4351    arg_types = {"this": False, "kind": False}
4352
4353    @property
4354    def name(self) -> str:
4355        return self.this or "?"
arg_types = {'this': False, 'kind': False}
name: str
4353    @property
4354    def name(self) -> str:
4355        return self.this or "?"
key = 'placeholder'
class Null(Condition):
4358class Null(Condition):
4359    arg_types: t.Dict[str, t.Any] = {}
4360
4361    @property
4362    def name(self) -> str:
4363        return "NULL"
4364
4365    def to_py(self) -> Lit[None]:
4366        return None
arg_types: Dict[str, Any] = {}
name: str
4361    @property
4362    def name(self) -> str:
4363        return "NULL"
def to_py(self) -> Literal[None]:
4365    def to_py(self) -> Lit[None]:
4366        return None

Returns a Python object equivalent of the SQL node.

key = 'null'
class Boolean(Condition):
4369class Boolean(Condition):
4370    def to_py(self) -> bool:
4371        return self.this
def to_py(self) -> bool:
4370    def to_py(self) -> bool:
4371        return self.this

Returns a Python object equivalent of the SQL node.

key = 'boolean'
class DataTypeParam(Expression):
4374class DataTypeParam(Expression):
4375    arg_types = {"this": True, "expression": False}
4376
4377    @property
4378    def name(self) -> str:
4379        return self.this.name
arg_types = {'this': True, 'expression': False}
name: str
4377    @property
4378    def name(self) -> str:
4379        return self.this.name
key = 'datatypeparam'
class DataType(Expression):
4384class DataType(Expression):
4385    arg_types = {
4386        "this": True,
4387        "expressions": False,
4388        "nested": False,
4389        "values": False,
4390        "prefix": False,
4391        "kind": False,
4392        "nullable": False,
4393    }
4394
4395    class Type(AutoName):
4396        ARRAY = auto()
4397        AGGREGATEFUNCTION = auto()
4398        SIMPLEAGGREGATEFUNCTION = auto()
4399        BIGDECIMAL = auto()
4400        BIGINT = auto()
4401        BIGSERIAL = auto()
4402        BINARY = auto()
4403        BIT = auto()
4404        BOOLEAN = auto()
4405        BPCHAR = auto()
4406        CHAR = auto()
4407        DATE = auto()
4408        DATE32 = auto()
4409        DATEMULTIRANGE = auto()
4410        DATERANGE = auto()
4411        DATETIME = auto()
4412        DATETIME2 = auto()
4413        DATETIME64 = auto()
4414        DECIMAL = auto()
4415        DECIMAL32 = auto()
4416        DECIMAL64 = auto()
4417        DECIMAL128 = auto()
4418        DECIMAL256 = auto()
4419        DOUBLE = auto()
4420        DYNAMIC = auto()
4421        ENUM = auto()
4422        ENUM8 = auto()
4423        ENUM16 = auto()
4424        FIXEDSTRING = auto()
4425        FLOAT = auto()
4426        GEOGRAPHY = auto()
4427        GEOMETRY = auto()
4428        POINT = auto()
4429        RING = auto()
4430        LINESTRING = auto()
4431        MULTILINESTRING = auto()
4432        POLYGON = auto()
4433        MULTIPOLYGON = auto()
4434        HLLSKETCH = auto()
4435        HSTORE = auto()
4436        IMAGE = auto()
4437        INET = auto()
4438        INT = auto()
4439        INT128 = auto()
4440        INT256 = auto()
4441        INT4MULTIRANGE = auto()
4442        INT4RANGE = auto()
4443        INT8MULTIRANGE = auto()
4444        INT8RANGE = auto()
4445        INTERVAL = auto()
4446        IPADDRESS = auto()
4447        IPPREFIX = auto()
4448        IPV4 = auto()
4449        IPV6 = auto()
4450        JSON = auto()
4451        JSONB = auto()
4452        LIST = auto()
4453        LONGBLOB = auto()
4454        LONGTEXT = auto()
4455        LOWCARDINALITY = auto()
4456        MAP = auto()
4457        MEDIUMBLOB = auto()
4458        MEDIUMINT = auto()
4459        MEDIUMTEXT = auto()
4460        MONEY = auto()
4461        NAME = auto()
4462        NCHAR = auto()
4463        NESTED = auto()
4464        NULL = auto()
4465        NUMMULTIRANGE = auto()
4466        NUMRANGE = auto()
4467        NVARCHAR = auto()
4468        OBJECT = auto()
4469        RANGE = auto()
4470        ROWVERSION = auto()
4471        SERIAL = auto()
4472        SET = auto()
4473        SMALLDATETIME = auto()
4474        SMALLINT = auto()
4475        SMALLMONEY = auto()
4476        SMALLSERIAL = auto()
4477        STRUCT = auto()
4478        SUPER = auto()
4479        TEXT = auto()
4480        TINYBLOB = auto()
4481        TINYTEXT = auto()
4482        TIME = auto()
4483        TIMETZ = auto()
4484        TIMESTAMP = auto()
4485        TIMESTAMPNTZ = auto()
4486        TIMESTAMPLTZ = auto()
4487        TIMESTAMPTZ = auto()
4488        TIMESTAMP_S = auto()
4489        TIMESTAMP_MS = auto()
4490        TIMESTAMP_NS = auto()
4491        TINYINT = auto()
4492        TSMULTIRANGE = auto()
4493        TSRANGE = auto()
4494        TSTZMULTIRANGE = auto()
4495        TSTZRANGE = auto()
4496        UBIGINT = auto()
4497        UINT = auto()
4498        UINT128 = auto()
4499        UINT256 = auto()
4500        UMEDIUMINT = auto()
4501        UDECIMAL = auto()
4502        UDOUBLE = auto()
4503        UNION = auto()
4504        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4505        USERDEFINED = "USER-DEFINED"
4506        USMALLINT = auto()
4507        UTINYINT = auto()
4508        UUID = auto()
4509        VARBINARY = auto()
4510        VARCHAR = auto()
4511        VARIANT = auto()
4512        VECTOR = auto()
4513        XML = auto()
4514        YEAR = auto()
4515        TDIGEST = auto()
4516
4517    STRUCT_TYPES = {
4518        Type.NESTED,
4519        Type.OBJECT,
4520        Type.STRUCT,
4521        Type.UNION,
4522    }
4523
4524    ARRAY_TYPES = {
4525        Type.ARRAY,
4526        Type.LIST,
4527    }
4528
4529    NESTED_TYPES = {
4530        *STRUCT_TYPES,
4531        *ARRAY_TYPES,
4532        Type.MAP,
4533    }
4534
4535    TEXT_TYPES = {
4536        Type.CHAR,
4537        Type.NCHAR,
4538        Type.NVARCHAR,
4539        Type.TEXT,
4540        Type.VARCHAR,
4541        Type.NAME,
4542    }
4543
4544    SIGNED_INTEGER_TYPES = {
4545        Type.BIGINT,
4546        Type.INT,
4547        Type.INT128,
4548        Type.INT256,
4549        Type.MEDIUMINT,
4550        Type.SMALLINT,
4551        Type.TINYINT,
4552    }
4553
4554    UNSIGNED_INTEGER_TYPES = {
4555        Type.UBIGINT,
4556        Type.UINT,
4557        Type.UINT128,
4558        Type.UINT256,
4559        Type.UMEDIUMINT,
4560        Type.USMALLINT,
4561        Type.UTINYINT,
4562    }
4563
4564    INTEGER_TYPES = {
4565        *SIGNED_INTEGER_TYPES,
4566        *UNSIGNED_INTEGER_TYPES,
4567        Type.BIT,
4568    }
4569
4570    FLOAT_TYPES = {
4571        Type.DOUBLE,
4572        Type.FLOAT,
4573    }
4574
4575    REAL_TYPES = {
4576        *FLOAT_TYPES,
4577        Type.BIGDECIMAL,
4578        Type.DECIMAL,
4579        Type.DECIMAL32,
4580        Type.DECIMAL64,
4581        Type.DECIMAL128,
4582        Type.DECIMAL256,
4583        Type.MONEY,
4584        Type.SMALLMONEY,
4585        Type.UDECIMAL,
4586        Type.UDOUBLE,
4587    }
4588
4589    NUMERIC_TYPES = {
4590        *INTEGER_TYPES,
4591        *REAL_TYPES,
4592    }
4593
4594    TEMPORAL_TYPES = {
4595        Type.DATE,
4596        Type.DATE32,
4597        Type.DATETIME,
4598        Type.DATETIME2,
4599        Type.DATETIME64,
4600        Type.SMALLDATETIME,
4601        Type.TIME,
4602        Type.TIMESTAMP,
4603        Type.TIMESTAMPNTZ,
4604        Type.TIMESTAMPLTZ,
4605        Type.TIMESTAMPTZ,
4606        Type.TIMESTAMP_MS,
4607        Type.TIMESTAMP_NS,
4608        Type.TIMESTAMP_S,
4609        Type.TIMETZ,
4610    }
4611
4612    @classmethod
4613    def build(
4614        cls,
4615        dtype: DATA_TYPE,
4616        dialect: DialectType = None,
4617        udt: bool = False,
4618        copy: bool = True,
4619        **kwargs,
4620    ) -> DataType:
4621        """
4622        Constructs a DataType object.
4623
4624        Args:
4625            dtype: the data type of interest.
4626            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4627            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4628                DataType, thus creating a user-defined type.
4629            copy: whether to copy the data type.
4630            kwargs: additional arguments to pass in the constructor of DataType.
4631
4632        Returns:
4633            The constructed DataType object.
4634        """
4635        from sqlglot import parse_one
4636
4637        if isinstance(dtype, str):
4638            if dtype.upper() == "UNKNOWN":
4639                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4640
4641            try:
4642                data_type_exp = parse_one(
4643                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4644                )
4645            except ParseError:
4646                if udt:
4647                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4648                raise
4649        elif isinstance(dtype, DataType.Type):
4650            data_type_exp = DataType(this=dtype)
4651        elif isinstance(dtype, DataType):
4652            return maybe_copy(dtype, copy)
4653        else:
4654            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4655
4656        return DataType(**{**data_type_exp.args, **kwargs})
4657
4658    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4659        """
4660        Checks whether this DataType matches one of the provided data types. Nested types or precision
4661        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4662
4663        Args:
4664            dtypes: the data types to compare this DataType to.
4665            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4666                If false, it means that NULLABLE<INT> is equivalent to INT.
4667
4668        Returns:
4669            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4670        """
4671        self_is_nullable = self.args.get("nullable")
4672        for dtype in dtypes:
4673            other_type = DataType.build(dtype, copy=False, udt=True)
4674            other_is_nullable = other_type.args.get("nullable")
4675            if (
4676                other_type.expressions
4677                or (check_nullable and (self_is_nullable or other_is_nullable))
4678                or self.this == DataType.Type.USERDEFINED
4679                or other_type.this == DataType.Type.USERDEFINED
4680            ):
4681                matches = self == other_type
4682            else:
4683                matches = self.this == other_type.this
4684
4685            if matches:
4686                return True
4687        return False
arg_types = {'this': True, 'expressions': False, 'nested': False, 'values': False, 'prefix': False, 'kind': False, 'nullable': False}
STRUCT_TYPES = {<Type.STRUCT: 'STRUCT'>, <Type.UNION: 'UNION'>, <Type.NESTED: 'NESTED'>, <Type.OBJECT: 'OBJECT'>}
ARRAY_TYPES = {<Type.LIST: 'LIST'>, <Type.ARRAY: 'ARRAY'>}
NESTED_TYPES = {<Type.MAP: 'MAP'>, <Type.STRUCT: 'STRUCT'>, <Type.LIST: 'LIST'>, <Type.UNION: 'UNION'>, <Type.NESTED: 'NESTED'>, <Type.ARRAY: 'ARRAY'>, <Type.OBJECT: 'OBJECT'>}
TEXT_TYPES = {<Type.CHAR: 'CHAR'>, <Type.NCHAR: 'NCHAR'>, <Type.NVARCHAR: 'NVARCHAR'>, <Type.VARCHAR: 'VARCHAR'>, <Type.NAME: 'NAME'>, <Type.TEXT: 'TEXT'>}
SIGNED_INTEGER_TYPES = {<Type.TINYINT: 'TINYINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT256: 'INT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
UNSIGNED_INTEGER_TYPES = {<Type.UINT256: 'UINT256'>, <Type.UBIGINT: 'UBIGINT'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT128: 'UINT128'>}
INTEGER_TYPES = {<Type.BIT: 'BIT'>, <Type.UINT256: 'UINT256'>, <Type.UBIGINT: 'UBIGINT'>, <Type.TINYINT: 'TINYINT'>, <Type.UINT: 'UINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.BIGINT: 'BIGINT'>, <Type.UTINYINT: 'UTINYINT'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT128: 'UINT128'>, <Type.INT256: 'INT256'>, <Type.MEDIUMINT: 'MEDIUMINT'>}
FLOAT_TYPES = {<Type.DOUBLE: 'DOUBLE'>, <Type.FLOAT: 'FLOAT'>}
REAL_TYPES = {<Type.UDECIMAL: 'UDECIMAL'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.FLOAT: 'FLOAT'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.MONEY: 'MONEY'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DOUBLE: 'DOUBLE'>}
NUMERIC_TYPES = {<Type.BIT: 'BIT'>, <Type.UBIGINT: 'UBIGINT'>, <Type.DECIMAL64: 'DECIMAL64'>, <Type.UINT: 'UINT'>, <Type.DECIMAL128: 'DECIMAL128'>, <Type.BIGINT: 'BIGINT'>, <Type.DECIMAL256: 'DECIMAL256'>, <Type.FLOAT: 'FLOAT'>, <Type.UDOUBLE: 'UDOUBLE'>, <Type.DECIMAL: 'DECIMAL'>, <Type.MEDIUMINT: 'MEDIUMINT'>, <Type.BIGDECIMAL: 'BIGDECIMAL'>, <Type.MONEY: 'MONEY'>, <Type.SMALLMONEY: 'SMALLMONEY'>, <Type.DOUBLE: 'DOUBLE'>, <Type.INT256: 'INT256'>, <Type.UTINYINT: 'UTINYINT'>, <Type.UINT256: 'UINT256'>, <Type.UDECIMAL: 'UDECIMAL'>, <Type.TINYINT: 'TINYINT'>, <Type.UMEDIUMINT: 'UMEDIUMINT'>, <Type.SMALLINT: 'SMALLINT'>, <Type.INT128: 'INT128'>, <Type.INT: 'INT'>, <Type.DECIMAL32: 'DECIMAL32'>, <Type.USMALLINT: 'USMALLINT'>, <Type.UINT128: 'UINT128'>}
TEMPORAL_TYPES = {<Type.DATETIME: 'DATETIME'>, <Type.TIMETZ: 'TIMETZ'>, <Type.TIMESTAMP_MS: 'TIMESTAMP_MS'>, <Type.TIMESTAMP_S: 'TIMESTAMP_S'>, <Type.DATE32: 'DATE32'>, <Type.TIMESTAMPLTZ: 'TIMESTAMPLTZ'>, <Type.TIMESTAMPNTZ: 'TIMESTAMPNTZ'>, <Type.DATETIME64: 'DATETIME64'>, <Type.DATETIME2: 'DATETIME2'>, <Type.TIMESTAMP: 'TIMESTAMP'>, <Type.TIMESTAMPTZ: 'TIMESTAMPTZ'>, <Type.SMALLDATETIME: 'SMALLDATETIME'>, <Type.TIME: 'TIME'>, <Type.DATE: 'DATE'>, <Type.TIMESTAMP_NS: 'TIMESTAMP_NS'>}
@classmethod
def build( cls, dtype: Union[str, DataType, DataType.Type], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, udt: bool = False, copy: bool = True, **kwargs) -> DataType:
4612    @classmethod
4613    def build(
4614        cls,
4615        dtype: DATA_TYPE,
4616        dialect: DialectType = None,
4617        udt: bool = False,
4618        copy: bool = True,
4619        **kwargs,
4620    ) -> DataType:
4621        """
4622        Constructs a DataType object.
4623
4624        Args:
4625            dtype: the data type of interest.
4626            dialect: the dialect to use for parsing `dtype`, in case it's a string.
4627            udt: when set to True, `dtype` will be used as-is if it can't be parsed into a
4628                DataType, thus creating a user-defined type.
4629            copy: whether to copy the data type.
4630            kwargs: additional arguments to pass in the constructor of DataType.
4631
4632        Returns:
4633            The constructed DataType object.
4634        """
4635        from sqlglot import parse_one
4636
4637        if isinstance(dtype, str):
4638            if dtype.upper() == "UNKNOWN":
4639                return DataType(this=DataType.Type.UNKNOWN, **kwargs)
4640
4641            try:
4642                data_type_exp = parse_one(
4643                    dtype, read=dialect, into=DataType, error_level=ErrorLevel.IGNORE
4644                )
4645            except ParseError:
4646                if udt:
4647                    return DataType(this=DataType.Type.USERDEFINED, kind=dtype, **kwargs)
4648                raise
4649        elif isinstance(dtype, DataType.Type):
4650            data_type_exp = DataType(this=dtype)
4651        elif isinstance(dtype, DataType):
4652            return maybe_copy(dtype, copy)
4653        else:
4654            raise ValueError(f"Invalid data type: {type(dtype)}. Expected str or DataType.Type")
4655
4656        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:
4658    def is_type(self, *dtypes: DATA_TYPE, check_nullable: bool = False) -> bool:
4659        """
4660        Checks whether this DataType matches one of the provided data types. Nested types or precision
4661        will be compared using "structural equivalence" semantics, so e.g. array<int> != array<float>.
4662
4663        Args:
4664            dtypes: the data types to compare this DataType to.
4665            check_nullable: whether to take the NULLABLE type constructor into account for the comparison.
4666                If false, it means that NULLABLE<INT> is equivalent to INT.
4667
4668        Returns:
4669            True, if and only if there is a type in `dtypes` which is equal to this DataType.
4670        """
4671        self_is_nullable = self.args.get("nullable")
4672        for dtype in dtypes:
4673            other_type = DataType.build(dtype, copy=False, udt=True)
4674            other_is_nullable = other_type.args.get("nullable")
4675            if (
4676                other_type.expressions
4677                or (check_nullable and (self_is_nullable or other_is_nullable))
4678                or self.this == DataType.Type.USERDEFINED
4679                or other_type.this == DataType.Type.USERDEFINED
4680            ):
4681                matches = self == other_type
4682            else:
4683                matches = self.this == other_type.this
4684
4685            if matches:
4686                return True
4687        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):
4395    class Type(AutoName):
4396        ARRAY = auto()
4397        AGGREGATEFUNCTION = auto()
4398        SIMPLEAGGREGATEFUNCTION = auto()
4399        BIGDECIMAL = auto()
4400        BIGINT = auto()
4401        BIGSERIAL = auto()
4402        BINARY = auto()
4403        BIT = auto()
4404        BOOLEAN = auto()
4405        BPCHAR = auto()
4406        CHAR = auto()
4407        DATE = auto()
4408        DATE32 = auto()
4409        DATEMULTIRANGE = auto()
4410        DATERANGE = auto()
4411        DATETIME = auto()
4412        DATETIME2 = auto()
4413        DATETIME64 = auto()
4414        DECIMAL = auto()
4415        DECIMAL32 = auto()
4416        DECIMAL64 = auto()
4417        DECIMAL128 = auto()
4418        DECIMAL256 = auto()
4419        DOUBLE = auto()
4420        DYNAMIC = auto()
4421        ENUM = auto()
4422        ENUM8 = auto()
4423        ENUM16 = auto()
4424        FIXEDSTRING = auto()
4425        FLOAT = auto()
4426        GEOGRAPHY = auto()
4427        GEOMETRY = auto()
4428        POINT = auto()
4429        RING = auto()
4430        LINESTRING = auto()
4431        MULTILINESTRING = auto()
4432        POLYGON = auto()
4433        MULTIPOLYGON = auto()
4434        HLLSKETCH = auto()
4435        HSTORE = auto()
4436        IMAGE = auto()
4437        INET = auto()
4438        INT = auto()
4439        INT128 = auto()
4440        INT256 = auto()
4441        INT4MULTIRANGE = auto()
4442        INT4RANGE = auto()
4443        INT8MULTIRANGE = auto()
4444        INT8RANGE = auto()
4445        INTERVAL = auto()
4446        IPADDRESS = auto()
4447        IPPREFIX = auto()
4448        IPV4 = auto()
4449        IPV6 = auto()
4450        JSON = auto()
4451        JSONB = auto()
4452        LIST = auto()
4453        LONGBLOB = auto()
4454        LONGTEXT = auto()
4455        LOWCARDINALITY = auto()
4456        MAP = auto()
4457        MEDIUMBLOB = auto()
4458        MEDIUMINT = auto()
4459        MEDIUMTEXT = auto()
4460        MONEY = auto()
4461        NAME = auto()
4462        NCHAR = auto()
4463        NESTED = auto()
4464        NULL = auto()
4465        NUMMULTIRANGE = auto()
4466        NUMRANGE = auto()
4467        NVARCHAR = auto()
4468        OBJECT = auto()
4469        RANGE = auto()
4470        ROWVERSION = auto()
4471        SERIAL = auto()
4472        SET = auto()
4473        SMALLDATETIME = auto()
4474        SMALLINT = auto()
4475        SMALLMONEY = auto()
4476        SMALLSERIAL = auto()
4477        STRUCT = auto()
4478        SUPER = auto()
4479        TEXT = auto()
4480        TINYBLOB = auto()
4481        TINYTEXT = auto()
4482        TIME = auto()
4483        TIMETZ = auto()
4484        TIMESTAMP = auto()
4485        TIMESTAMPNTZ = auto()
4486        TIMESTAMPLTZ = auto()
4487        TIMESTAMPTZ = auto()
4488        TIMESTAMP_S = auto()
4489        TIMESTAMP_MS = auto()
4490        TIMESTAMP_NS = auto()
4491        TINYINT = auto()
4492        TSMULTIRANGE = auto()
4493        TSRANGE = auto()
4494        TSTZMULTIRANGE = auto()
4495        TSTZRANGE = auto()
4496        UBIGINT = auto()
4497        UINT = auto()
4498        UINT128 = auto()
4499        UINT256 = auto()
4500        UMEDIUMINT = auto()
4501        UDECIMAL = auto()
4502        UDOUBLE = auto()
4503        UNION = auto()
4504        UNKNOWN = auto()  # Sentinel value, useful for type annotation
4505        USERDEFINED = "USER-DEFINED"
4506        USMALLINT = auto()
4507        UTINYINT = auto()
4508        UUID = auto()
4509        VARBINARY = auto()
4510        VARCHAR = auto()
4511        VARIANT = auto()
4512        VECTOR = auto()
4513        XML = auto()
4514        YEAR = auto()
4515        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'>
UDOUBLE = <Type.UDOUBLE: 'UDOUBLE'>
UNION = <Type.UNION: 'UNION'>
UNKNOWN = <Type.UNKNOWN: 'UNKNOWN'>
USERDEFINED = <Type.USERDEFINED: 'USER-DEFINED'>
USMALLINT = <Type.USMALLINT: 'USMALLINT'>
UTINYINT = <Type.UTINYINT: 'UTINYINT'>
UUID = <Type.UUID: 'UUID'>
VARBINARY = <Type.VARBINARY: 'VARBINARY'>
VARCHAR = <Type.VARCHAR: 'VARCHAR'>
VARIANT = <Type.VARIANT: 'VARIANT'>
VECTOR = <Type.VECTOR: 'VECTOR'>
XML = <Type.XML: 'XML'>
YEAR = <Type.YEAR: 'YEAR'>
TDIGEST = <Type.TDIGEST: 'TDIGEST'>
DATA_TYPE = typing.Union[str, DataType, DataType.Type]
class PseudoType(DataType):
4694class PseudoType(DataType):
4695    arg_types = {"this": True}
arg_types = {'this': True}
key = 'pseudotype'
class ObjectIdentifier(DataType):
4699class ObjectIdentifier(DataType):
4700    arg_types = {"this": True}
arg_types = {'this': True}
key = 'objectidentifier'
class SubqueryPredicate(Predicate):
4704class SubqueryPredicate(Predicate):
4705    pass
key = 'subquerypredicate'
class All(SubqueryPredicate):
4708class All(SubqueryPredicate):
4709    pass
key = 'all'
class Any(SubqueryPredicate):
4712class Any(SubqueryPredicate):
4713    pass
key = 'any'
class Command(Expression):
4718class Command(Expression):
4719    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'command'
class Transaction(Expression):
4722class Transaction(Expression):
4723    arg_types = {"this": False, "modes": False, "mark": False}
arg_types = {'this': False, 'modes': False, 'mark': False}
key = 'transaction'
class Commit(Expression):
4726class Commit(Expression):
4727    arg_types = {"chain": False, "this": False, "durability": False}
arg_types = {'chain': False, 'this': False, 'durability': False}
key = 'commit'
class Rollback(Expression):
4730class Rollback(Expression):
4731    arg_types = {"savepoint": False, "this": False}
arg_types = {'savepoint': False, 'this': False}
key = 'rollback'
class Alter(Expression):
4734class Alter(Expression):
4735    arg_types = {
4736        "this": True,
4737        "kind": True,
4738        "actions": True,
4739        "exists": False,
4740        "only": False,
4741        "options": False,
4742        "cluster": False,
4743        "not_valid": False,
4744    }
4745
4746    @property
4747    def kind(self) -> t.Optional[str]:
4748        kind = self.args.get("kind")
4749        return kind and kind.upper()
4750
4751    @property
4752    def actions(self) -> t.List[Expression]:
4753        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]
4746    @property
4747    def kind(self) -> t.Optional[str]:
4748        kind = self.args.get("kind")
4749        return kind and kind.upper()
actions: List[Expression]
4751    @property
4752    def actions(self) -> t.List[Expression]:
4753        return self.args.get("actions") or []
key = 'alter'
class Analyze(Expression):
4756class Analyze(Expression):
4757    arg_types = {
4758        "kind": False,
4759        "this": False,
4760        "options": False,
4761        "mode": False,
4762        "partition": False,
4763        "expression": False,
4764        "properties": False,
4765    }
arg_types = {'kind': False, 'this': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key = 'analyze'
class AnalyzeStatistics(Expression):
4768class AnalyzeStatistics(Expression):
4769    arg_types = {
4770        "kind": True,
4771        "option": False,
4772        "this": False,
4773        "expressions": False,
4774    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key = 'analyzestatistics'
class AnalyzeHistogram(Expression):
4777class AnalyzeHistogram(Expression):
4778    arg_types = {
4779        "this": True,
4780        "expressions": True,
4781        "expression": False,
4782        "update_options": False,
4783    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key = 'analyzehistogram'
class AnalyzeSample(Expression):
4786class AnalyzeSample(Expression):
4787    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key = 'analyzesample'
class AnalyzeListChainedRows(Expression):
4790class AnalyzeListChainedRows(Expression):
4791    arg_types = {"expression": False}
arg_types = {'expression': False}
key = 'analyzelistchainedrows'
class AnalyzeDelete(Expression):
4794class AnalyzeDelete(Expression):
4795    arg_types = {"kind": False}
arg_types = {'kind': False}
key = 'analyzedelete'
class AnalyzeWith(Expression):
4798class AnalyzeWith(Expression):
4799    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'analyzewith'
class AnalyzeValidate(Expression):
4802class AnalyzeValidate(Expression):
4803    arg_types = {
4804        "kind": True,
4805        "this": False,
4806        "expression": False,
4807    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key = 'analyzevalidate'
class AnalyzeColumns(Expression):
4810class AnalyzeColumns(Expression):
4811    pass
key = 'analyzecolumns'
class UsingData(Expression):
4814class UsingData(Expression):
4815    pass
key = 'usingdata'
class AddConstraint(Expression):
4818class AddConstraint(Expression):
4819    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'addconstraint'
class AttachOption(Expression):
4822class AttachOption(Expression):
4823    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'attachoption'
class DropPartition(Expression):
4826class DropPartition(Expression):
4827    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key = 'droppartition'
class ReplacePartition(Expression):
4831class ReplacePartition(Expression):
4832    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key = 'replacepartition'
class Binary(Condition):
4836class Binary(Condition):
4837    arg_types = {"this": True, "expression": True}
4838
4839    @property
4840    def left(self) -> Expression:
4841        return self.this
4842
4843    @property
4844    def right(self) -> Expression:
4845        return self.expression
arg_types = {'this': True, 'expression': True}
left: Expression
4839    @property
4840    def left(self) -> Expression:
4841        return self.this
right: Expression
4843    @property
4844    def right(self) -> Expression:
4845        return self.expression
key = 'binary'
class Add(Binary):
4848class Add(Binary):
4849    pass
key = 'add'
class Connector(Binary):
4852class Connector(Binary):
4853    pass
key = 'connector'
class And(Connector):
4856class And(Connector):
4857    pass
key = 'and'
class Or(Connector):
4860class Or(Connector):
4861    pass
key = 'or'
class BitwiseAnd(Binary):
4864class BitwiseAnd(Binary):
4865    pass
key = 'bitwiseand'
class BitwiseLeftShift(Binary):
4868class BitwiseLeftShift(Binary):
4869    pass
key = 'bitwiseleftshift'
class BitwiseOr(Binary):
4872class BitwiseOr(Binary):
4873    pass
key = 'bitwiseor'
class BitwiseRightShift(Binary):
4876class BitwiseRightShift(Binary):
4877    pass
key = 'bitwiserightshift'
class BitwiseXor(Binary):
4880class BitwiseXor(Binary):
4881    pass
key = 'bitwisexor'
class Div(Binary):
4884class Div(Binary):
4885    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):
4888class Overlaps(Binary):
4889    pass
key = 'overlaps'
class Dot(Binary):
4892class Dot(Binary):
4893    @property
4894    def is_star(self) -> bool:
4895        return self.expression.is_star
4896
4897    @property
4898    def name(self) -> str:
4899        return self.expression.name
4900
4901    @property
4902    def output_name(self) -> str:
4903        return self.name
4904
4905    @classmethod
4906    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4907        """Build a Dot object with a sequence of expressions."""
4908        if len(expressions) < 2:
4909            raise ValueError("Dot requires >= 2 expressions.")
4910
4911        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4912
4913    @property
4914    def parts(self) -> t.List[Expression]:
4915        """Return the parts of a table / column in order catalog, db, table."""
4916        this, *parts = self.flatten()
4917
4918        parts.reverse()
4919
4920        for arg in COLUMN_PARTS:
4921            part = this.args.get(arg)
4922
4923            if isinstance(part, Expression):
4924                parts.append(part)
4925
4926        parts.reverse()
4927        return parts
is_star: bool
4893    @property
4894    def is_star(self) -> bool:
4895        return self.expression.is_star

Checks whether an expression is a star.

name: str
4897    @property
4898    def name(self) -> str:
4899        return self.expression.name
output_name: str
4901    @property
4902    def output_name(self) -> str:
4903        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:
4905    @classmethod
4906    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4907        """Build a Dot object with a sequence of expressions."""
4908        if len(expressions) < 2:
4909            raise ValueError("Dot requires >= 2 expressions.")
4910
4911        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]
4913    @property
4914    def parts(self) -> t.List[Expression]:
4915        """Return the parts of a table / column in order catalog, db, table."""
4916        this, *parts = self.flatten()
4917
4918        parts.reverse()
4919
4920        for arg in COLUMN_PARTS:
4921            part = this.args.get(arg)
4922
4923            if isinstance(part, Expression):
4924                parts.append(part)
4925
4926        parts.reverse()
4927        return parts

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

key = 'dot'
class DPipe(Binary):
4930class DPipe(Binary):
4931    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4934class EQ(Binary, Predicate):
4935    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4938class NullSafeEQ(Binary, Predicate):
4939    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4942class NullSafeNEQ(Binary, Predicate):
4943    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4947class PropertyEQ(Binary):
4948    pass
key = 'propertyeq'
class Distance(Binary):
4951class Distance(Binary):
4952    pass
key = 'distance'
class Escape(Binary):
4955class Escape(Binary):
4956    pass
key = 'escape'
class Glob(Binary, Predicate):
4959class Glob(Binary, Predicate):
4960    pass
key = 'glob'
class GT(Binary, Predicate):
4963class GT(Binary, Predicate):
4964    pass
key = 'gt'
class GTE(Binary, Predicate):
4967class GTE(Binary, Predicate):
4968    pass
key = 'gte'
class ILike(Binary, Predicate):
4971class ILike(Binary, Predicate):
4972    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4975class ILikeAny(Binary, Predicate):
4976    pass
key = 'ilikeany'
class IntDiv(Binary):
4979class IntDiv(Binary):
4980    pass
key = 'intdiv'
class Is(Binary, Predicate):
4983class Is(Binary, Predicate):
4984    pass
key = 'is'
class Kwarg(Binary):
4987class Kwarg(Binary):
4988    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4991class Like(Binary, Predicate):
4992    pass
key = 'like'
class LikeAny(Binary, Predicate):
4995class LikeAny(Binary, Predicate):
4996    pass
key = 'likeany'
class LT(Binary, Predicate):
4999class LT(Binary, Predicate):
5000    pass
key = 'lt'
class LTE(Binary, Predicate):
5003class LTE(Binary, Predicate):
5004    pass
key = 'lte'
class Mod(Binary):
5007class Mod(Binary):
5008    pass
key = 'mod'
class Mul(Binary):
5011class Mul(Binary):
5012    pass
key = 'mul'
class NEQ(Binary, Predicate):
5015class NEQ(Binary, Predicate):
5016    pass
key = 'neq'
class Operator(Binary):
5020class Operator(Binary):
5021    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5024class SimilarTo(Binary, Predicate):
5025    pass
key = 'similarto'
class Slice(Binary):
5028class Slice(Binary):
5029    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5032class Sub(Binary):
5033    pass
key = 'sub'
class Unary(Condition):
5038class Unary(Condition):
5039    pass
key = 'unary'
class BitwiseNot(Unary):
5042class BitwiseNot(Unary):
5043    pass
key = 'bitwisenot'
class Not(Unary):
5046class Not(Unary):
5047    pass
key = 'not'
class Paren(Unary):
5050class Paren(Unary):
5051    @property
5052    def output_name(self) -> str:
5053        return self.this.name
output_name: str
5051    @property
5052    def output_name(self) -> str:
5053        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):
5056class Neg(Unary):
5057    def to_py(self) -> int | Decimal:
5058        if self.is_number:
5059            return self.this.to_py() * -1
5060        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5057    def to_py(self) -> int | Decimal:
5058        if self.is_number:
5059            return self.this.to_py() * -1
5060        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5063class Alias(Expression):
5064    arg_types = {"this": True, "alias": False}
5065
5066    @property
5067    def output_name(self) -> str:
5068        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5066    @property
5067    def output_name(self) -> str:
5068        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):
5073class PivotAlias(Alias):
5074    pass
key = 'pivotalias'
class PivotAny(Expression):
5079class PivotAny(Expression):
5080    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5083class Aliases(Expression):
5084    arg_types = {"this": True, "expressions": True}
5085
5086    @property
5087    def aliases(self):
5088        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5086    @property
5087    def aliases(self):
5088        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5092class AtIndex(Expression):
5093    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5096class AtTimeZone(Expression):
5097    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5100class FromTimeZone(Expression):
5101    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
5104class Between(Predicate):
5105    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5108class Bracket(Condition):
5109    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5110    arg_types = {
5111        "this": True,
5112        "expressions": True,
5113        "offset": False,
5114        "safe": False,
5115        "returns_list_for_maps": False,
5116    }
5117
5118    @property
5119    def output_name(self) -> str:
5120        if len(self.expressions) == 1:
5121            return self.expressions[0].output_name
5122
5123        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5118    @property
5119    def output_name(self) -> str:
5120        if len(self.expressions) == 1:
5121            return self.expressions[0].output_name
5122
5123        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):
5126class Distinct(Expression):
5127    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5130class In(Predicate):
5131    arg_types = {
5132        "this": True,
5133        "expressions": False,
5134        "query": False,
5135        "unnest": False,
5136        "field": False,
5137        "is_global": False,
5138    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5142class ForIn(Expression):
5143    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5146class TimeUnit(Expression):
5147    """Automatically converts unit arg into a var."""
5148
5149    arg_types = {"unit": False}
5150
5151    UNABBREVIATED_UNIT_NAME = {
5152        "D": "DAY",
5153        "H": "HOUR",
5154        "M": "MINUTE",
5155        "MS": "MILLISECOND",
5156        "NS": "NANOSECOND",
5157        "Q": "QUARTER",
5158        "S": "SECOND",
5159        "US": "MICROSECOND",
5160        "W": "WEEK",
5161        "Y": "YEAR",
5162    }
5163
5164    VAR_LIKE = (Column, Literal, Var)
5165
5166    def __init__(self, **args):
5167        unit = args.get("unit")
5168        if isinstance(unit, self.VAR_LIKE):
5169            args["unit"] = Var(
5170                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5171            )
5172        elif isinstance(unit, Week):
5173            unit.set("this", Var(this=unit.this.name.upper()))
5174
5175        super().__init__(**args)
5176
5177    @property
5178    def unit(self) -> t.Optional[Var | IntervalSpan]:
5179        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5166    def __init__(self, **args):
5167        unit = args.get("unit")
5168        if isinstance(unit, self.VAR_LIKE):
5169            args["unit"] = Var(
5170                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5171            )
5172        elif isinstance(unit, Week):
5173            unit.set("this", Var(this=unit.this.name.upper()))
5174
5175        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]
5177    @property
5178    def unit(self) -> t.Optional[Var | IntervalSpan]:
5179        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5182class IntervalOp(TimeUnit):
5183    arg_types = {"unit": False, "expression": True}
5184
5185    def interval(self):
5186        return Interval(
5187            this=self.expression.copy(),
5188            unit=self.unit.copy() if self.unit else None,
5189        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5185    def interval(self):
5186        return Interval(
5187            this=self.expression.copy(),
5188            unit=self.unit.copy() if self.unit else None,
5189        )
key = 'intervalop'
class IntervalSpan(DataType):
5195class IntervalSpan(DataType):
5196    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5199class Interval(TimeUnit):
5200    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5203class IgnoreNulls(Expression):
5204    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5207class RespectNulls(Expression):
5208    pass
key = 'respectnulls'
class HavingMax(Expression):
5212class HavingMax(Expression):
5213    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5217class Func(Condition):
5218    """
5219    The base class for all function expressions.
5220
5221    Attributes:
5222        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5223            treated as a variable length argument and the argument's value will be stored as a list.
5224        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5225            function expression. These values are used to map this node to a name during parsing as
5226            well as to provide the function's name during SQL string generation. By default the SQL
5227            name is set to the expression's class name transformed to snake case.
5228    """
5229
5230    is_var_len_args = False
5231
5232    @classmethod
5233    def from_arg_list(cls, args):
5234        if cls.is_var_len_args:
5235            all_arg_keys = list(cls.arg_types)
5236            # If this function supports variable length argument treat the last argument as such.
5237            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5238            num_non_var = len(non_var_len_arg_keys)
5239
5240            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5241            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5242        else:
5243            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5244
5245        return cls(**args_dict)
5246
5247    @classmethod
5248    def sql_names(cls):
5249        if cls is Func:
5250            raise NotImplementedError(
5251                "SQL name is only supported by concrete function implementations"
5252            )
5253        if "_sql_names" not in cls.__dict__:
5254            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5255        return cls._sql_names
5256
5257    @classmethod
5258    def sql_name(cls):
5259        return cls.sql_names()[0]
5260
5261    @classmethod
5262    def default_parser_mappings(cls):
5263        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):
5232    @classmethod
5233    def from_arg_list(cls, args):
5234        if cls.is_var_len_args:
5235            all_arg_keys = list(cls.arg_types)
5236            # If this function supports variable length argument treat the last argument as such.
5237            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5238            num_non_var = len(non_var_len_arg_keys)
5239
5240            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5241            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5242        else:
5243            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5244
5245        return cls(**args_dict)
@classmethod
def sql_names(cls):
5247    @classmethod
5248    def sql_names(cls):
5249        if cls is Func:
5250            raise NotImplementedError(
5251                "SQL name is only supported by concrete function implementations"
5252            )
5253        if "_sql_names" not in cls.__dict__:
5254            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5255        return cls._sql_names
@classmethod
def sql_name(cls):
5257    @classmethod
5258    def sql_name(cls):
5259        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5261    @classmethod
5262    def default_parser_mappings(cls):
5263        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5266class AggFunc(Func):
5267    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5270class ParameterizedAgg(AggFunc):
5271    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5274class Abs(Func):
5275    pass
key = 'abs'
class ArgMax(AggFunc):
5278class ArgMax(AggFunc):
5279    arg_types = {"this": True, "expression": True, "count": False}
5280    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5283class ArgMin(AggFunc):
5284    arg_types = {"this": True, "expression": True, "count": False}
5285    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5288class ApproxTopK(AggFunc):
5289    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5292class Flatten(Func):
5293    pass
key = 'flatten'
class Transform(Func):
5297class Transform(Func):
5298    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5301class Anonymous(Func):
5302    arg_types = {"this": True, "expressions": False}
5303    is_var_len_args = True
5304
5305    @property
5306    def name(self) -> str:
5307        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
5305    @property
5306    def name(self) -> str:
5307        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5310class AnonymousAggFunc(AggFunc):
5311    arg_types = {"this": True, "expressions": False}
5312    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5316class CombinedAggFunc(AnonymousAggFunc):
5317    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5320class CombinedParameterizedAgg(ParameterizedAgg):
5321    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5326class Hll(AggFunc):
5327    arg_types = {"this": True, "expressions": False}
5328    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5331class ApproxDistinct(AggFunc):
5332    arg_types = {"this": True, "accuracy": False}
5333    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5336class Apply(Func):
5337    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5340class Array(Func):
5341    arg_types = {"expressions": False, "bracket_notation": False}
5342    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5346class ToArray(Func):
5347    pass
key = 'toarray'
class List(Func):
5351class List(Func):
5352    arg_types = {"expressions": False}
5353    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5357class Pad(Func):
5358    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):
5363class ToChar(Func):
5364    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5369class ToNumber(Func):
5370    arg_types = {
5371        "this": True,
5372        "format": False,
5373        "nlsparam": False,
5374        "precision": False,
5375        "scale": False,
5376    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5380class ToDouble(Func):
5381    arg_types = {
5382        "this": True,
5383        "format": False,
5384    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5387class Columns(Func):
5388    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5392class Convert(Func):
5393    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5396class ConvertTimezone(Func):
5397    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):
5400class GenerateSeries(Func):
5401    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):
5407class ExplodingGenerateSeries(GenerateSeries):
5408    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5411class ArrayAgg(AggFunc):
5412    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5415class ArrayUniqueAgg(AggFunc):
5416    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5419class ArrayAll(Func):
5420    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5424class ArrayAny(Func):
5425    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5428class ArrayConcat(Func):
5429    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5430    arg_types = {"this": True, "expressions": False}
5431    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5434class ArrayConstructCompact(Func):
5435    arg_types = {"expressions": True}
5436    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5439class ArrayContains(Binary, Func):
5440    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5443class ArrayContainsAll(Binary, Func):
5444    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5447class ArrayFilter(Func):
5448    arg_types = {"this": True, "expression": True}
5449    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5452class ArrayToString(Func):
5453    arg_types = {"this": True, "expression": True, "null": False}
5454    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5458class String(Func):
5459    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5462class StringToArray(Func):
5463    arg_types = {"this": True, "expression": True, "null": False}
5464    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5467class ArrayOverlaps(Binary, Func):
5468    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5471class ArraySize(Func):
5472    arg_types = {"this": True, "expression": False}
5473    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5476class ArraySort(Func):
5477    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5480class ArraySum(Func):
5481    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5484class ArrayUnionAgg(AggFunc):
5485    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5488class Avg(AggFunc):
5489    pass
key = 'avg'
class AnyValue(AggFunc):
5492class AnyValue(AggFunc):
5493    pass
key = 'anyvalue'
class Lag(AggFunc):
5496class Lag(AggFunc):
5497    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5500class Lead(AggFunc):
5501    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5506class First(AggFunc):
5507    pass
key = 'first'
class Last(AggFunc):
5510class Last(AggFunc):
5511    pass
key = 'last'
class FirstValue(AggFunc):
5514class FirstValue(AggFunc):
5515    pass
key = 'firstvalue'
class LastValue(AggFunc):
5518class LastValue(AggFunc):
5519    pass
key = 'lastvalue'
class NthValue(AggFunc):
5522class NthValue(AggFunc):
5523    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5526class Case(Func):
5527    arg_types = {"this": False, "ifs": True, "default": False}
5528
5529    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5530        instance = maybe_copy(self, copy)
5531        instance.append(
5532            "ifs",
5533            If(
5534                this=maybe_parse(condition, copy=copy, **opts),
5535                true=maybe_parse(then, copy=copy, **opts),
5536            ),
5537        )
5538        return instance
5539
5540    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5541        instance = maybe_copy(self, copy)
5542        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5543        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:
5529    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5530        instance = maybe_copy(self, copy)
5531        instance.append(
5532            "ifs",
5533            If(
5534                this=maybe_parse(condition, copy=copy, **opts),
5535                true=maybe_parse(then, copy=copy, **opts),
5536            ),
5537        )
5538        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5540    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5541        instance = maybe_copy(self, copy)
5542        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5543        return instance
key = 'case'
class Cast(Func):
5546class Cast(Func):
5547    arg_types = {
5548        "this": True,
5549        "to": True,
5550        "format": False,
5551        "safe": False,
5552        "action": False,
5553        "default": False,
5554    }
5555
5556    @property
5557    def name(self) -> str:
5558        return self.this.name
5559
5560    @property
5561    def to(self) -> DataType:
5562        return self.args["to"]
5563
5564    @property
5565    def output_name(self) -> str:
5566        return self.name
5567
5568    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5569        """
5570        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5571        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5572        array<int> != array<float>.
5573
5574        Args:
5575            dtypes: the data types to compare this Cast's DataType to.
5576
5577        Returns:
5578            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5579        """
5580        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5556    @property
5557    def name(self) -> str:
5558        return self.this.name
to: DataType
5560    @property
5561    def to(self) -> DataType:
5562        return self.args["to"]
output_name: str
5564    @property
5565    def output_name(self) -> str:
5566        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:
5568    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5569        """
5570        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5571        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5572        array<int> != array<float>.
5573
5574        Args:
5575            dtypes: the data types to compare this Cast's DataType to.
5576
5577        Returns:
5578            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5579        """
5580        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):
5583class TryCast(Cast):
5584    pass
key = 'trycast'
class JSONCast(Cast):
5588class JSONCast(Cast):
5589    pass
key = 'jsoncast'
class Try(Func):
5592class Try(Func):
5593    pass
key = 'try'
class CastToStrType(Func):
5596class CastToStrType(Func):
5597    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5600class Collate(Binary, Func):
5601    pass
key = 'collate'
class Ceil(Func):
5604class Ceil(Func):
5605    arg_types = {"this": True, "decimals": False, "to": False}
5606    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5609class Coalesce(Func):
5610    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5611    is_var_len_args = True
5612    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5615class Chr(Func):
5616    arg_types = {"expressions": True, "charset": False}
5617    is_var_len_args = True
5618    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5621class Concat(Func):
5622    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5623    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5626class ConcatWs(Concat):
5627    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5630class Contains(Func):
5631    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5635class ConnectByRoot(Func):
5636    pass
key = 'connectbyroot'
class Count(AggFunc):
5639class Count(AggFunc):
5640    arg_types = {"this": False, "expressions": False, "big_int": False}
5641    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5644class CountIf(AggFunc):
5645    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5649class Cbrt(Func):
5650    pass
key = 'cbrt'
class CurrentDate(Func):
5653class CurrentDate(Func):
5654    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5657class CurrentDatetime(Func):
5658    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5661class CurrentTime(Func):
5662    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5665class CurrentTimestamp(Func):
5666    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5669class CurrentSchema(Func):
5670    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5673class CurrentUser(Func):
5674    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5677class DateAdd(Func, IntervalOp):
5678    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5681class DateBin(Func, IntervalOp):
5682    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
arg_types = {'this': True, 'expression': True, 'unit': False, 'zone': False}
key = 'datebin'
class DateSub(Func, IntervalOp):
5685class DateSub(Func, IntervalOp):
5686    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5689class DateDiff(Func, TimeUnit):
5690    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5691    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5694class DateTrunc(Func):
5695    arg_types = {"unit": True, "this": True, "zone": False}
5696
5697    def __init__(self, **args):
5698        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5699        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5700        unabbreviate = args.pop("unabbreviate", True)
5701
5702        unit = args.get("unit")
5703        if isinstance(unit, TimeUnit.VAR_LIKE):
5704            unit_name = unit.name.upper()
5705            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5706                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5707
5708            args["unit"] = Literal.string(unit_name)
5709        elif isinstance(unit, Week):
5710            unit.set("this", Literal.string(unit.this.name.upper()))
5711
5712        super().__init__(**args)
5713
5714    @property
5715    def unit(self) -> Expression:
5716        return self.args["unit"]
DateTrunc(**args)
5697    def __init__(self, **args):
5698        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5699        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5700        unabbreviate = args.pop("unabbreviate", True)
5701
5702        unit = args.get("unit")
5703        if isinstance(unit, TimeUnit.VAR_LIKE):
5704            unit_name = unit.name.upper()
5705            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5706                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5707
5708            args["unit"] = Literal.string(unit_name)
5709        elif isinstance(unit, Week):
5710            unit.set("this", Literal.string(unit.this.name.upper()))
5711
5712        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5714    @property
5715    def unit(self) -> Expression:
5716        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5721class Datetime(Func):
5722    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5725class DatetimeAdd(Func, IntervalOp):
5726    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5729class DatetimeSub(Func, IntervalOp):
5730    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5733class DatetimeDiff(Func, TimeUnit):
5734    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5737class DatetimeTrunc(Func, TimeUnit):
5738    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5741class DayOfWeek(Func):
5742    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5747class DayOfWeekIso(Func):
5748    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5751class DayOfMonth(Func):
5752    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5755class DayOfYear(Func):
5756    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5759class ToDays(Func):
5760    pass
key = 'todays'
class WeekOfYear(Func):
5763class WeekOfYear(Func):
5764    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5767class MonthsBetween(Func):
5768    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5771class MakeInterval(Func):
5772    arg_types = {
5773        "year": False,
5774        "month": False,
5775        "day": False,
5776        "hour": False,
5777        "minute": False,
5778        "second": False,
5779    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5782class LastDay(Func, TimeUnit):
5783    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5784    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5787class Extract(Func):
5788    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5791class Exists(Func, SubqueryPredicate):
5792    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5795class Timestamp(Func):
5796    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5799class TimestampAdd(Func, TimeUnit):
5800    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5803class TimestampSub(Func, TimeUnit):
5804    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5807class TimestampDiff(Func, TimeUnit):
5808    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5809    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5812class TimestampTrunc(Func, TimeUnit):
5813    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5816class TimeAdd(Func, TimeUnit):
5817    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5820class TimeSub(Func, TimeUnit):
5821    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5824class TimeDiff(Func, TimeUnit):
5825    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5828class TimeTrunc(Func, TimeUnit):
5829    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5832class DateFromParts(Func):
5833    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5834    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5837class TimeFromParts(Func):
5838    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5839    arg_types = {
5840        "hour": True,
5841        "min": True,
5842        "sec": True,
5843        "nano": False,
5844        "fractions": False,
5845        "precision": False,
5846    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5849class DateStrToDate(Func):
5850    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5853class DateToDateStr(Func):
5854    pass
key = 'datetodatestr'
class DateToDi(Func):
5857class DateToDi(Func):
5858    pass
key = 'datetodi'
class Date(Func):
5862class Date(Func):
5863    arg_types = {"this": False, "zone": False, "expressions": False}
5864    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5867class Day(Func):
5868    pass
key = 'day'
class Decode(Func):
5871class Decode(Func):
5872    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5875class DiToDate(Func):
5876    pass
key = 'ditodate'
class Encode(Func):
5879class Encode(Func):
5880    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5883class Exp(Func):
5884    pass
key = 'exp'
class Explode(Func, UDTF):
5888class Explode(Func, UDTF):
5889    arg_types = {"this": True, "expressions": False}
5890    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5894class Inline(Func):
5895    pass
key = 'inline'
class ExplodeOuter(Explode):
5898class ExplodeOuter(Explode):
5899    pass
key = 'explodeouter'
class Posexplode(Explode):
5902class Posexplode(Explode):
5903    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5906class PosexplodeOuter(Posexplode, ExplodeOuter):
5907    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5910class Unnest(Func, UDTF):
5911    arg_types = {
5912        "expressions": True,
5913        "alias": False,
5914        "offset": False,
5915        "explode_array": False,
5916    }
5917
5918    @property
5919    def selects(self) -> t.List[Expression]:
5920        columns = super().selects
5921        offset = self.args.get("offset")
5922        if offset:
5923            columns = columns + [to_identifier("offset") if offset is True else offset]
5924        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5918    @property
5919    def selects(self) -> t.List[Expression]:
5920        columns = super().selects
5921        offset = self.args.get("offset")
5922        if offset:
5923            columns = columns + [to_identifier("offset") if offset is True else offset]
5924        return columns
key = 'unnest'
class Floor(Func):
5927class Floor(Func):
5928    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
5931class FromBase64(Func):
5932    pass
key = 'frombase64'
class FeaturesAtTime(Func):
5935class FeaturesAtTime(Func):
5936    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):
5939class ToBase64(Func):
5940    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5944class FromISO8601Timestamp(Func):
5945    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5948class GapFill(Func):
5949    arg_types = {
5950        "this": True,
5951        "ts_column": True,
5952        "bucket_width": True,
5953        "partitioning_columns": False,
5954        "value_columns": False,
5955        "origin": False,
5956        "ignore_nulls": False,
5957    }
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):
5961class GenerateDateArray(Func):
5962    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5966class GenerateTimestampArray(Func):
5967    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5970class Greatest(Func):
5971    arg_types = {"this": True, "expressions": False}
5972    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
5977class OverflowTruncateBehavior(Expression):
5978    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
5981class GroupConcat(AggFunc):
5982    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
5985class Hex(Func):
5986    pass
key = 'hex'
class LowerHex(Hex):
5989class LowerHex(Hex):
5990    pass
key = 'lowerhex'
class Xor(Connector, Func):
5993class Xor(Connector, Func):
5994    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5997class If(Func):
5998    arg_types = {"this": True, "true": True, "false": False}
5999    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6002class Nullif(Func):
6003    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6006class Initcap(Func):
6007    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6010class IsAscii(Func):
6011    pass
key = 'isascii'
class IsNan(Func):
6014class IsNan(Func):
6015    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6019class Int64(Func):
6020    pass
key = 'int64'
class IsInf(Func):
6023class IsInf(Func):
6024    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6028class JSON(Expression):
6029    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6032class JSONPath(Expression):
6033    arg_types = {"expressions": True, "escape": False}
6034
6035    @property
6036    def output_name(self) -> str:
6037        last_segment = self.expressions[-1].this
6038        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6035    @property
6036    def output_name(self) -> str:
6037        last_segment = self.expressions[-1].this
6038        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):
6041class JSONPathPart(Expression):
6042    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6045class JSONPathFilter(JSONPathPart):
6046    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6049class JSONPathKey(JSONPathPart):
6050    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6053class JSONPathRecursive(JSONPathPart):
6054    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6057class JSONPathRoot(JSONPathPart):
6058    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6061class JSONPathScript(JSONPathPart):
6062    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6065class JSONPathSlice(JSONPathPart):
6066    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6069class JSONPathSelector(JSONPathPart):
6070    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6073class JSONPathSubscript(JSONPathPart):
6074    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6077class JSONPathUnion(JSONPathPart):
6078    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6081class JSONPathWildcard(JSONPathPart):
6082    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6085class FormatJson(Expression):
6086    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6089class JSONKeyValue(Expression):
6090    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6093class JSONObject(Func):
6094    arg_types = {
6095        "expressions": False,
6096        "null_handling": False,
6097        "unique_keys": False,
6098        "return_type": False,
6099        "encoding": False,
6100    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6103class JSONObjectAgg(AggFunc):
6104    arg_types = {
6105        "expressions": False,
6106        "null_handling": False,
6107        "unique_keys": False,
6108        "return_type": False,
6109        "encoding": False,
6110    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6114class JSONBObjectAgg(AggFunc):
6115    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6119class JSONArray(Func):
6120    arg_types = {
6121        "expressions": True,
6122        "null_handling": False,
6123        "return_type": False,
6124        "strict": False,
6125    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6129class JSONArrayAgg(Func):
6130    arg_types = {
6131        "this": True,
6132        "order": False,
6133        "null_handling": False,
6134        "return_type": False,
6135        "strict": False,
6136    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6139class JSONExists(Func):
6140    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):
6145class JSONColumnDef(Expression):
6146    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):
6149class JSONSchema(Expression):
6150    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6154class JSONValue(Expression):
6155    arg_types = {
6156        "this": True,
6157        "path": True,
6158        "returning": False,
6159        "on_condition": False,
6160    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6163class JSONValueArray(Func):
6164    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6168class JSONTable(Func):
6169    arg_types = {
6170        "this": True,
6171        "schema": True,
6172        "path": False,
6173        "error_handling": False,
6174        "empty_handling": False,
6175    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6179class ObjectInsert(Func):
6180    arg_types = {
6181        "this": True,
6182        "key": True,
6183        "value": True,
6184        "update_flag": False,
6185    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6188class OpenJSONColumnDef(Expression):
6189    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):
6192class OpenJSON(Func):
6193    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6196class JSONBContains(Binary, Func):
6197    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6200class JSONBExists(Func):
6201    arg_types = {"this": True, "path": True}
6202    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6205class JSONExtract(Binary, Func):
6206    arg_types = {
6207        "this": True,
6208        "expression": True,
6209        "only_json_types": False,
6210        "expressions": False,
6211        "variant_extract": False,
6212        "json_query": False,
6213        "option": False,
6214        "quote": False,
6215    }
6216    _sql_names = ["JSON_EXTRACT"]
6217    is_var_len_args = True
6218
6219    @property
6220    def output_name(self) -> str:
6221        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
6219    @property
6220    def output_name(self) -> str:
6221        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):
6225class JSONExtractQuote(Expression):
6226    arg_types = {
6227        "option": True,
6228        "scalar": False,
6229    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6232class JSONExtractArray(Func):
6233    arg_types = {"this": True, "expression": False}
6234    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6237class JSONExtractScalar(Binary, Func):
6238    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6239    _sql_names = ["JSON_EXTRACT_SCALAR"]
6240    is_var_len_args = True
6241
6242    @property
6243    def output_name(self) -> str:
6244        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
6242    @property
6243    def output_name(self) -> str:
6244        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):
6247class JSONBExtract(Binary, Func):
6248    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6251class JSONBExtractScalar(Binary, Func):
6252    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6255class JSONFormat(Func):
6256    arg_types = {"this": False, "options": False}
6257    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6261class JSONArrayContains(Binary, Predicate, Func):
6262    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6265class ParseJSON(Func):
6266    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6267    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6268    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6269    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6272class Least(Func):
6273    arg_types = {"this": True, "expressions": False}
6274    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6277class Left(Func):
6278    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6285class Length(Func):
6286    arg_types = {"this": True, "binary": False, "encoding": False}
6287    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6290class Levenshtein(Func):
6291    arg_types = {
6292        "this": True,
6293        "expression": False,
6294        "ins_cost": False,
6295        "del_cost": False,
6296        "sub_cost": False,
6297        "max_dist": False,
6298    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6301class Ln(Func):
6302    pass
key = 'ln'
class Log(Func):
6305class Log(Func):
6306    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6309class LogicalOr(AggFunc):
6310    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6313class LogicalAnd(AggFunc):
6314    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6317class Lower(Func):
6318    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6321class Map(Func):
6322    arg_types = {"keys": False, "values": False}
6323
6324    @property
6325    def keys(self) -> t.List[Expression]:
6326        keys = self.args.get("keys")
6327        return keys.expressions if keys else []
6328
6329    @property
6330    def values(self) -> t.List[Expression]:
6331        values = self.args.get("values")
6332        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6324    @property
6325    def keys(self) -> t.List[Expression]:
6326        keys = self.args.get("keys")
6327        return keys.expressions if keys else []
values: List[Expression]
6329    @property
6330    def values(self) -> t.List[Expression]:
6331        values = self.args.get("values")
6332        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6336class ToMap(Func):
6337    pass
key = 'tomap'
class MapFromEntries(Func):
6340class MapFromEntries(Func):
6341    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6345class ScopeResolution(Expression):
6346    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6349class Stream(Expression):
6350    pass
key = 'stream'
class StarMap(Func):
6353class StarMap(Func):
6354    pass
key = 'starmap'
class VarMap(Func):
6357class VarMap(Func):
6358    arg_types = {"keys": True, "values": True}
6359    is_var_len_args = True
6360
6361    @property
6362    def keys(self) -> t.List[Expression]:
6363        return self.args["keys"].expressions
6364
6365    @property
6366    def values(self) -> t.List[Expression]:
6367        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6361    @property
6362    def keys(self) -> t.List[Expression]:
6363        return self.args["keys"].expressions
values: List[Expression]
6365    @property
6366    def values(self) -> t.List[Expression]:
6367        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6371class MatchAgainst(Func):
6372    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6375class Max(AggFunc):
6376    arg_types = {"this": True, "expressions": False}
6377    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6380class MD5(Func):
6381    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6385class MD5Digest(Func):
6386    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6389class Median(AggFunc):
6390    pass
key = 'median'
class Min(AggFunc):
6393class Min(AggFunc):
6394    arg_types = {"this": True, "expressions": False}
6395    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6398class Month(Func):
6399    pass
key = 'month'
class AddMonths(Func):
6402class AddMonths(Func):
6403    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6406class Nvl2(Func):
6407    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6410class Normalize(Func):
6411    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6414class Overlay(Func):
6415    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):
6419class Predict(Func):
6420    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6423class Pow(Binary, Func):
6424    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6427class PercentileCont(AggFunc):
6428    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6431class PercentileDisc(AggFunc):
6432    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6435class Quantile(AggFunc):
6436    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6439class ApproxQuantile(Quantile):
6440    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):
6443class Quarter(Func):
6444    pass
key = 'quarter'
class Rand(Func):
6449class Rand(Func):
6450    _sql_names = ["RAND", "RANDOM"]
6451    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6454class Randn(Func):
6455    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6458class RangeN(Func):
6459    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6462class ReadCSV(Func):
6463    _sql_names = ["READ_CSV"]
6464    is_var_len_args = True
6465    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6468class Reduce(Func):
6469    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):
6472class RegexpExtract(Func):
6473    arg_types = {
6474        "this": True,
6475        "expression": True,
6476        "position": False,
6477        "occurrence": False,
6478        "parameters": False,
6479        "group": False,
6480    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6483class RegexpExtractAll(Func):
6484    arg_types = {
6485        "this": True,
6486        "expression": True,
6487        "position": False,
6488        "occurrence": False,
6489        "parameters": False,
6490        "group": False,
6491    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6494class RegexpReplace(Func):
6495    arg_types = {
6496        "this": True,
6497        "expression": True,
6498        "replacement": False,
6499        "position": False,
6500        "occurrence": False,
6501        "modifiers": False,
6502    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6505class RegexpLike(Binary, Func):
6506    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6509class RegexpILike(Binary, Func):
6510    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6515class RegexpSplit(Func):
6516    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6519class Repeat(Func):
6520    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6525class Round(Func):
6526    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6529class RowNumber(Func):
6530    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6533class SafeDivide(Func):
6534    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6537class SHA(Func):
6538    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6541class SHA2(Func):
6542    _sql_names = ["SHA2"]
6543    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6546class Sign(Func):
6547    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6550class SortArray(Func):
6551    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6554class Split(Func):
6555    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6559class SplitPart(Func):
6560    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6565class Substring(Func):
6566    _sql_names = ["SUBSTRING", "SUBSTR"]
6567    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6570class StandardHash(Func):
6571    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6574class StartsWith(Func):
6575    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6576    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6579class StrPosition(Func):
6580    arg_types = {
6581        "this": True,
6582        "substr": True,
6583        "position": False,
6584        "occurrence": False,
6585    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6588class StrToDate(Func):
6589    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6592class StrToTime(Func):
6593    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):
6598class StrToUnix(Func):
6599    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6604class StrToMap(Func):
6605    arg_types = {
6606        "this": True,
6607        "pair_delim": False,
6608        "key_value_delim": False,
6609        "duplicate_resolution_callback": False,
6610    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6613class NumberToStr(Func):
6614    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6617class FromBase(Func):
6618    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6621class Struct(Func):
6622    arg_types = {"expressions": False}
6623    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6626class StructExtract(Func):
6627    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6632class Stuff(Func):
6633    _sql_names = ["STUFF", "INSERT"]
6634    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):
6637class Sum(AggFunc):
6638    pass
key = 'sum'
class Sqrt(Func):
6641class Sqrt(Func):
6642    pass
key = 'sqrt'
class Stddev(AggFunc):
6645class Stddev(AggFunc):
6646    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6649class StddevPop(AggFunc):
6650    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6653class StddevSamp(AggFunc):
6654    pass
key = 'stddevsamp'
class Time(Func):
6658class Time(Func):
6659    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6662class TimeToStr(Func):
6663    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):
6666class TimeToTimeStr(Func):
6667    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6670class TimeToUnix(Func):
6671    pass
key = 'timetounix'
class TimeStrToDate(Func):
6674class TimeStrToDate(Func):
6675    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6678class TimeStrToTime(Func):
6679    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6682class TimeStrToUnix(Func):
6683    pass
key = 'timestrtounix'
class Trim(Func):
6686class Trim(Func):
6687    arg_types = {
6688        "this": True,
6689        "expression": False,
6690        "position": False,
6691        "collation": False,
6692    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6695class TsOrDsAdd(Func, TimeUnit):
6696    # return_type is used to correctly cast the arguments of this expression when transpiling it
6697    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6698
6699    @property
6700    def return_type(self) -> DataType:
6701        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
6699    @property
6700    def return_type(self) -> DataType:
6701        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6704class TsOrDsDiff(Func, TimeUnit):
6705    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6708class TsOrDsToDateStr(Func):
6709    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6712class TsOrDsToDate(Func):
6713    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6716class TsOrDsToDatetime(Func):
6717    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6720class TsOrDsToTime(Func):
6721    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6724class TsOrDsToTimestamp(Func):
6725    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6728class TsOrDiToDi(Func):
6729    pass
key = 'tsorditodi'
class Unhex(Func):
6732class Unhex(Func):
6733    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6736class Unicode(Func):
6737    pass
key = 'unicode'
class UnixDate(Func):
6741class UnixDate(Func):
6742    pass
key = 'unixdate'
class UnixToStr(Func):
6745class UnixToStr(Func):
6746    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6751class UnixToTime(Func):
6752    arg_types = {
6753        "this": True,
6754        "scale": False,
6755        "zone": False,
6756        "hours": False,
6757        "minutes": False,
6758        "format": False,
6759    }
6760
6761    SECONDS = Literal.number(0)
6762    DECIS = Literal.number(1)
6763    CENTIS = Literal.number(2)
6764    MILLIS = Literal.number(3)
6765    DECIMILLIS = Literal.number(4)
6766    CENTIMILLIS = Literal.number(5)
6767    MICROS = Literal.number(6)
6768    DECIMICROS = Literal.number(7)
6769    CENTIMICROS = Literal.number(8)
6770    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):
6773class UnixToTimeStr(Func):
6774    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6777class UnixSeconds(Func):
6778    pass
key = 'unixseconds'
class Uuid(Func):
6781class Uuid(Func):
6782    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6783
6784    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6787class TimestampFromParts(Func):
6788    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6789    arg_types = {
6790        "year": True,
6791        "month": True,
6792        "day": True,
6793        "hour": True,
6794        "min": True,
6795        "sec": True,
6796        "nano": False,
6797        "zone": False,
6798        "milli": False,
6799    }
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):
6802class Upper(Func):
6803    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6806class Corr(Binary, AggFunc):
6807    pass
key = 'corr'
class Variance(AggFunc):
6810class Variance(AggFunc):
6811    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6814class VariancePop(AggFunc):
6815    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6818class CovarSamp(Binary, AggFunc):
6819    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6822class CovarPop(Binary, AggFunc):
6823    pass
key = 'covarpop'
class Week(Func):
6826class Week(Func):
6827    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6830class XMLElement(Func):
6831    _sql_names = ["XMLELEMENT"]
6832    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6835class XMLTable(Func):
6836    arg_types = {
6837        "this": True,
6838        "namespaces": False,
6839        "passing": False,
6840        "columns": False,
6841        "by_ref": False,
6842    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6845class XMLNamespace(Expression):
6846    pass
key = 'xmlnamespace'
class Year(Func):
6849class Year(Func):
6850    pass
key = 'year'
class Use(Expression):
6853class Use(Expression):
6854    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
6857class Merge(DML):
6858    arg_types = {
6859        "this": True,
6860        "using": True,
6861        "on": True,
6862        "whens": True,
6863        "with": False,
6864        "returning": False,
6865    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6868class When(Expression):
6869    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):
6872class Whens(Expression):
6873    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6874
6875    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
6880class NextValueFor(Func):
6881    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6886class Semicolon(Expression):
6887    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 'CurrentSchema'>, <class 'CurrentTime'>, <class 'CurrentTimestamp'>, <class 'CurrentUser'>, <class 'Date'>, <class 'DateAdd'>, <class 'DateBin'>, <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 'JSONBObjectAgg'>, <class 'JSONCast'>, <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_SCHEMA': <class 'CurrentSchema'>, 'CURRENT_TIME': <class 'CurrentTime'>, 'CURRENT_TIMESTAMP': <class 'CurrentTimestamp'>, 'CURRENT_USER': <class 'CurrentUser'>, 'DATE': <class 'Date'>, 'DATE_ADD': <class 'DateAdd'>, 'DATE_BIN': <class 'DateBin'>, 'DATEDIFF': <class 'DateDiff'>, 'DATE_DIFF': <class 'DateDiff'>, 'DATE_FROM_PARTS': <class 'DateFromParts'>, 'DATEFROMPARTS': <class 'DateFromParts'>, 'DATE_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_B_OBJECT_AGG': <class 'JSONBObjectAgg'>, 'J_S_O_N_CAST': <class 'JSONCast'>, 'J_S_O_N_EXISTS': <class 'JSONExists'>, 'JSON_EXTRACT': <class 'JSONExtract'>, 'JSON_EXTRACT_ARRAY': <class 'JSONExtractArray'>, 'JSON_EXTRACT_SCALAR': <class 'JSONExtractScalar'>, 'JSON_FORMAT': <class 'JSONFormat'>, 'J_S_O_N_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, Type[sqlglot.dialects.Dialect], NoneType] = None, prefix: Optional[str] = None, copy: bool = False, **opts) -> Expression:
6927def maybe_parse(
6928    sql_or_expression: ExpOrStr,
6929    *,
6930    into: t.Optional[IntoType] = None,
6931    dialect: DialectType = None,
6932    prefix: t.Optional[str] = None,
6933    copy: bool = False,
6934    **opts,
6935) -> Expression:
6936    """Gracefully handle a possible string or expression.
6937
6938    Example:
6939        >>> maybe_parse("1")
6940        Literal(this=1, is_string=False)
6941        >>> maybe_parse(to_identifier("x"))
6942        Identifier(this=x, quoted=False)
6943
6944    Args:
6945        sql_or_expression: the SQL code string or an expression
6946        into: the SQLGlot Expression to parse into
6947        dialect: the dialect used to parse the input expressions (in the case that an
6948            input expression is a SQL string).
6949        prefix: a string to prefix the sql with before it gets parsed
6950            (automatically includes a space)
6951        copy: whether to copy the expression.
6952        **opts: other options to use to parse the input expressions (again, in the case
6953            that an input expression is a SQL string).
6954
6955    Returns:
6956        Expression: the parsed or given expression.
6957    """
6958    if isinstance(sql_or_expression, Expression):
6959        if copy:
6960            return sql_or_expression.copy()
6961        return sql_or_expression
6962
6963    if sql_or_expression is None:
6964        raise ParseError("SQL cannot be None")
6965
6966    import sqlglot
6967
6968    sql = str(sql_or_expression)
6969    if prefix:
6970        sql = f"{prefix} {sql}"
6971
6972    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):
6983def maybe_copy(instance, copy=True):
6984    return instance.copy() if copy and instance else instance
def union( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Union:
7232def union(
7233    *expressions: ExpOrStr,
7234    distinct: bool = True,
7235    dialect: DialectType = None,
7236    copy: bool = True,
7237    **opts,
7238) -> Union:
7239    """
7240    Initializes a syntax tree for the `UNION` operation.
7241
7242    Example:
7243        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7244        'SELECT * FROM foo UNION SELECT * FROM bla'
7245
7246    Args:
7247        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7248            If `Expression` instances are passed, they will be used as-is.
7249        distinct: set the DISTINCT flag if and only if this is true.
7250        dialect: the dialect used to parse the input expression.
7251        copy: whether to copy the expression.
7252        opts: other options to use to parse the input expressions.
7253
7254    Returns:
7255        The new Union instance.
7256    """
7257    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7258    return _apply_set_operation(
7259        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7260    )

Initializes a syntax tree for the UNION operation.

Example:
>>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo UNION SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the UNION's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Union instance.

def intersect( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Intersect:
7263def intersect(
7264    *expressions: ExpOrStr,
7265    distinct: bool = True,
7266    dialect: DialectType = None,
7267    copy: bool = True,
7268    **opts,
7269) -> Intersect:
7270    """
7271    Initializes a syntax tree for the `INTERSECT` operation.
7272
7273    Example:
7274        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7275        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7276
7277    Args:
7278        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7279            If `Expression` instances are passed, they will be used as-is.
7280        distinct: set the DISTINCT flag if and only if this is true.
7281        dialect: the dialect used to parse the input expression.
7282        copy: whether to copy the expression.
7283        opts: other options to use to parse the input expressions.
7284
7285    Returns:
7286        The new Intersect instance.
7287    """
7288    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7289    return _apply_set_operation(
7290        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7291    )

Initializes a syntax tree for the INTERSECT operation.

Example:
>>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo INTERSECT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the INTERSECT's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Intersect instance.

def except_( *expressions: Union[str, Expression], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Except:
7294def except_(
7295    *expressions: ExpOrStr,
7296    distinct: bool = True,
7297    dialect: DialectType = None,
7298    copy: bool = True,
7299    **opts,
7300) -> Except:
7301    """
7302    Initializes a syntax tree for the `EXCEPT` operation.
7303
7304    Example:
7305        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7306        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7307
7308    Args:
7309        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7310            If `Expression` instances are passed, they will be used as-is.
7311        distinct: set the DISTINCT flag if and only if this is true.
7312        dialect: the dialect used to parse the input expression.
7313        copy: whether to copy the expression.
7314        opts: other options to use to parse the input expressions.
7315
7316    Returns:
7317        The new Except instance.
7318    """
7319    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7320    return _apply_set_operation(
7321        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7322    )

Initializes a syntax tree for the EXCEPT operation.

Example:
>>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
'SELECT * FROM foo EXCEPT SELECT * FROM bla'
Arguments:
  • expressions: the SQL code strings, corresponding to the EXCEPT's operands. If Expression instances are passed, they will be used as-is.
  • distinct: set the DISTINCT flag if and only if this is true.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy the expression.
  • opts: other options to use to parse the input expressions.
Returns:

The new Except instance.

def select( *expressions: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7325def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7326    """
7327    Initializes a syntax tree from one or multiple SELECT expressions.
7328
7329    Example:
7330        >>> select("col1", "col2").from_("tbl").sql()
7331        'SELECT col1, col2 FROM tbl'
7332
7333    Args:
7334        *expressions: the SQL code string to parse as the expressions of a
7335            SELECT statement. If an Expression instance is passed, this is used as-is.
7336        dialect: the dialect used to parse the input expressions (in the case that an
7337            input expression is a SQL string).
7338        **opts: other options to use to parse the input expressions (again, in the case
7339            that an input expression is a SQL string).
7340
7341    Returns:
7342        Select: the syntax tree for the SELECT statement.
7343    """
7344    return Select().select(*expressions, dialect=dialect, **opts)

Initializes a syntax tree from one or multiple SELECT expressions.

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

Select: the syntax tree for the SELECT statement.

def from_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7347def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7348    """
7349    Initializes a syntax tree from a FROM expression.
7350
7351    Example:
7352        >>> from_("tbl").select("col1", "col2").sql()
7353        'SELECT col1, col2 FROM tbl'
7354
7355    Args:
7356        *expression: the SQL code string to parse as the FROM expressions of a
7357            SELECT statement. If an Expression instance is passed, this is used as-is.
7358        dialect: the dialect used to parse the input expression (in the case that the
7359            input expression is a SQL string).
7360        **opts: other options to use to parse the input expressions (again, in the case
7361            that the input expression is a SQL string).
7362
7363    Returns:
7364        Select: the syntax tree for the SELECT statement.
7365    """
7366    return Select().from_(expression, dialect=dialect, **opts)

Initializes a syntax tree from a FROM expression.

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

Select: the syntax tree for the SELECT statement.

def update( table: str | Table, properties: Optional[dict] = None, where: Union[str, Expression, NoneType] = None, from_: Union[str, Expression, NoneType] = None, with_: Optional[Dict[str, Union[str, Expression]]] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Update:
7369def update(
7370    table: str | Table,
7371    properties: t.Optional[dict] = None,
7372    where: t.Optional[ExpOrStr] = None,
7373    from_: t.Optional[ExpOrStr] = None,
7374    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7375    dialect: DialectType = None,
7376    **opts,
7377) -> Update:
7378    """
7379    Creates an update statement.
7380
7381    Example:
7382        >>> 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()
7383        "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"
7384
7385    Args:
7386        properties: dictionary of properties to SET which are
7387            auto converted to sql objects eg None -> NULL
7388        where: sql conditional parsed into a WHERE statement
7389        from_: sql statement parsed into a FROM statement
7390        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7391        dialect: the dialect used to parse the input expressions.
7392        **opts: other options to use to parse the input expressions.
7393
7394    Returns:
7395        Update: the syntax tree for the UPDATE statement.
7396    """
7397    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7398    if properties:
7399        update_expr.set(
7400            "expressions",
7401            [
7402                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7403                for k, v in properties.items()
7404            ],
7405        )
7406    if from_:
7407        update_expr.set(
7408            "from",
7409            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7410        )
7411    if isinstance(where, Condition):
7412        where = Where(this=where)
7413    if where:
7414        update_expr.set(
7415            "where",
7416            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7417        )
7418    if with_:
7419        cte_list = [
7420            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7421            for alias, qry in with_.items()
7422        ]
7423        update_expr.set(
7424            "with",
7425            With(expressions=cte_list),
7426        )
7427    return update_expr

Creates an update statement.

Example:
>>> update("my_table", {"x": 1, "y": "2", "z": None}, from_="baz_cte", where="baz_cte.id > 1 and my_table.id = baz_cte.id", with_={"baz_cte": "SELECT id FROM foo"}).sql()
"WITH baz_cte AS (SELECT id FROM foo) UPDATE my_table SET x = 1, y = '2', z = NULL FROM baz_cte WHERE baz_cte.id > 1 AND my_table.id = baz_cte.id"
Arguments:
  • properties: dictionary of properties to SET which are auto converted to sql objects eg None -> NULL
  • where: sql conditional parsed into a WHERE statement
  • from_: sql statement parsed into a FROM statement
  • with_: dictionary of CTE aliases / select statements to include in a WITH clause.
  • dialect: the dialect used to parse the input expressions.
  • **opts: other options to use to parse the input expressions.
Returns:

Update: the syntax tree for the UPDATE statement.

def delete( table: Union[str, Expression], where: Union[str, Expression, NoneType] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Delete:
7430def delete(
7431    table: ExpOrStr,
7432    where: t.Optional[ExpOrStr] = None,
7433    returning: t.Optional[ExpOrStr] = None,
7434    dialect: DialectType = None,
7435    **opts,
7436) -> Delete:
7437    """
7438    Builds a delete statement.
7439
7440    Example:
7441        >>> delete("my_table", where="id > 1").sql()
7442        'DELETE FROM my_table WHERE id > 1'
7443
7444    Args:
7445        where: sql conditional parsed into a WHERE statement
7446        returning: sql conditional parsed into a RETURNING statement
7447        dialect: the dialect used to parse the input expressions.
7448        **opts: other options to use to parse the input expressions.
7449
7450    Returns:
7451        Delete: the syntax tree for the DELETE statement.
7452    """
7453    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7454    if where:
7455        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7456    if returning:
7457        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7458    return delete_expr

Builds a delete statement.

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

Delete: the syntax tree for the DELETE statement.

def insert( expression: Union[str, Expression], into: Union[str, Expression], columns: Optional[Sequence[str | Identifier]] = None, overwrite: Optional[bool] = None, returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Insert:
7461def insert(
7462    expression: ExpOrStr,
7463    into: ExpOrStr,
7464    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7465    overwrite: t.Optional[bool] = None,
7466    returning: t.Optional[ExpOrStr] = None,
7467    dialect: DialectType = None,
7468    copy: bool = True,
7469    **opts,
7470) -> Insert:
7471    """
7472    Builds an INSERT statement.
7473
7474    Example:
7475        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7476        'INSERT INTO tbl VALUES (1, 2, 3)'
7477
7478    Args:
7479        expression: the sql string or expression of the INSERT statement
7480        into: the tbl to insert data to.
7481        columns: optionally the table's column names.
7482        overwrite: whether to INSERT OVERWRITE or not.
7483        returning: sql conditional parsed into a RETURNING statement
7484        dialect: the dialect used to parse the input expressions.
7485        copy: whether to copy the expression.
7486        **opts: other options to use to parse the input expressions.
7487
7488    Returns:
7489        Insert: the syntax tree for the INSERT statement.
7490    """
7491    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7492    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7493
7494    if columns:
7495        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7496
7497    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7498
7499    if returning:
7500        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7501
7502    return insert

Builds an INSERT statement.

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

Insert: the syntax tree for the INSERT statement.

def merge( *when_exprs: Union[str, Expression], into: Union[str, Expression], using: Union[str, Expression], on: Union[str, Expression], returning: Union[str, Expression, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Merge:
7505def merge(
7506    *when_exprs: ExpOrStr,
7507    into: ExpOrStr,
7508    using: ExpOrStr,
7509    on: ExpOrStr,
7510    returning: t.Optional[ExpOrStr] = None,
7511    dialect: DialectType = None,
7512    copy: bool = True,
7513    **opts,
7514) -> Merge:
7515    """
7516    Builds a MERGE statement.
7517
7518    Example:
7519        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7520        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7521        ...       into="my_table",
7522        ...       using="source_table",
7523        ...       on="my_table.id = source_table.id").sql()
7524        '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)'
7525
7526    Args:
7527        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7528        into: The target table to merge data into.
7529        using: The source table to merge data from.
7530        on: The join condition for the merge.
7531        returning: The columns to return from the merge.
7532        dialect: The dialect used to parse the input expressions.
7533        copy: Whether to copy the expression.
7534        **opts: Other options to use to parse the input expressions.
7535
7536    Returns:
7537        Merge: The syntax tree for the MERGE statement.
7538    """
7539    expressions: t.List[Expression] = []
7540    for when_expr in when_exprs:
7541        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7542        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7543
7544    merge = Merge(
7545        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7546        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7547        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7548        whens=Whens(expressions=expressions),
7549    )
7550    if returning:
7551        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7552
7553    return merge

Builds a MERGE statement.

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

Merge: The syntax tree for the MERGE statement.

def condition( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Condition:
7556def condition(
7557    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7558) -> Condition:
7559    """
7560    Initialize a logical condition expression.
7561
7562    Example:
7563        >>> condition("x=1").sql()
7564        'x = 1'
7565
7566        This is helpful for composing larger logical syntax trees:
7567        >>> where = condition("x=1")
7568        >>> where = where.and_("y=1")
7569        >>> Select().from_("tbl").select("*").where(where).sql()
7570        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7571
7572    Args:
7573        *expression: the SQL code string to parse.
7574            If an Expression instance is passed, this is used as-is.
7575        dialect: the dialect used to parse the input expression (in the case that the
7576            input expression is a SQL string).
7577        copy: Whether to copy `expression` (only applies to expressions).
7578        **opts: other options to use to parse the input expressions (again, in the case
7579            that the input expression is a SQL string).
7580
7581    Returns:
7582        The new Condition instance
7583    """
7584    return maybe_parse(
7585        expression,
7586        into=Condition,
7587        dialect=dialect,
7588        copy=copy,
7589        **opts,
7590    )

Initialize a logical condition expression.

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

This is helpful for composing larger logical syntax trees:

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

The new Condition instance

def and_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7593def and_(
7594    *expressions: t.Optional[ExpOrStr],
7595    dialect: DialectType = None,
7596    copy: bool = True,
7597    wrap: bool = True,
7598    **opts,
7599) -> Condition:
7600    """
7601    Combine multiple conditions with an AND logical operator.
7602
7603    Example:
7604        >>> and_("x=1", and_("y=1", "z=1")).sql()
7605        'x = 1 AND (y = 1 AND z = 1)'
7606
7607    Args:
7608        *expressions: the SQL code strings to parse.
7609            If an Expression instance is passed, this is used as-is.
7610        dialect: the dialect used to parse the input expression.
7611        copy: whether to copy `expressions` (only applies to Expressions).
7612        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7613            precedence issues, but can be turned off when the produced AST is too deep and
7614            causes recursion-related issues.
7615        **opts: other options to use to parse the input expressions.
7616
7617    Returns:
7618        The new condition
7619    """
7620    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an AND logical operator.

Example:
>>> and_("x=1", and_("y=1", "z=1")).sql()
'x = 1 AND (y = 1 AND z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition

def or_( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7623def or_(
7624    *expressions: t.Optional[ExpOrStr],
7625    dialect: DialectType = None,
7626    copy: bool = True,
7627    wrap: bool = True,
7628    **opts,
7629) -> Condition:
7630    """
7631    Combine multiple conditions with an OR logical operator.
7632
7633    Example:
7634        >>> or_("x=1", or_("y=1", "z=1")).sql()
7635        'x = 1 OR (y = 1 OR z = 1)'
7636
7637    Args:
7638        *expressions: the SQL code strings to parse.
7639            If an Expression instance is passed, this is used as-is.
7640        dialect: the dialect used to parse the input expression.
7641        copy: whether to copy `expressions` (only applies to Expressions).
7642        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7643            precedence issues, but can be turned off when the produced AST is too deep and
7644            causes recursion-related issues.
7645        **opts: other options to use to parse the input expressions.
7646
7647    Returns:
7648        The new condition
7649    """
7650    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an OR logical operator.

Example:
>>> or_("x=1", or_("y=1", "z=1")).sql()
'x = 1 OR (y = 1 OR z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition

def xor( *expressions: Union[str, Expression, NoneType], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, wrap: bool = True, **opts) -> Condition:
7653def xor(
7654    *expressions: t.Optional[ExpOrStr],
7655    dialect: DialectType = None,
7656    copy: bool = True,
7657    wrap: bool = True,
7658    **opts,
7659) -> Condition:
7660    """
7661    Combine multiple conditions with an XOR logical operator.
7662
7663    Example:
7664        >>> xor("x=1", xor("y=1", "z=1")).sql()
7665        'x = 1 XOR (y = 1 XOR z = 1)'
7666
7667    Args:
7668        *expressions: the SQL code strings to parse.
7669            If an Expression instance is passed, this is used as-is.
7670        dialect: the dialect used to parse the input expression.
7671        copy: whether to copy `expressions` (only applies to Expressions).
7672        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7673            precedence issues, but can be turned off when the produced AST is too deep and
7674            causes recursion-related issues.
7675        **opts: other options to use to parse the input expressions.
7676
7677    Returns:
7678        The new condition
7679    """
7680    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))

Combine multiple conditions with an XOR logical operator.

Example:
>>> xor("x=1", xor("y=1", "z=1")).sql()
'x = 1 XOR (y = 1 XOR z = 1)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expression instance is passed, this is used as-is.
  • dialect: the dialect used to parse the input expression.
  • copy: whether to copy expressions (only applies to Expressions).
  • wrap: whether to wrap the operands in Parens. This is true by default to avoid precedence issues, but can be turned off when the produced AST is too deep and causes recursion-related issues.
  • **opts: other options to use to parse the input expressions.
Returns:

The new condition

def not_( expression: Union[str, Expression], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> Not:
7683def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7684    """
7685    Wrap a condition with a NOT operator.
7686
7687    Example:
7688        >>> not_("this_suit='black'").sql()
7689        "NOT this_suit = 'black'"
7690
7691    Args:
7692        expression: the SQL code string to parse.
7693            If an Expression instance is passed, this is used as-is.
7694        dialect: the dialect used to parse the input expression.
7695        copy: whether to copy the expression or not.
7696        **opts: other options to use to parse the input expressions.
7697
7698    Returns:
7699        The new condition.
7700    """
7701    this = condition(
7702        expression,
7703        dialect=dialect,
7704        copy=copy,
7705        **opts,
7706    )
7707    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:
7710def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7711    """
7712    Wrap an expression in parentheses.
7713
7714    Example:
7715        >>> paren("5 + 3").sql()
7716        '(5 + 3)'
7717
7718    Args:
7719        expression: the SQL code string to parse.
7720            If an Expression instance is passed, this is used as-is.
7721        copy: whether to copy the expression or not.
7722
7723    Returns:
7724        The wrapped expression.
7725    """
7726    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):
7742def to_identifier(name, quoted=None, copy=True):
7743    """Builds an identifier.
7744
7745    Args:
7746        name: The name to turn into an identifier.
7747        quoted: Whether to force quote the identifier.
7748        copy: Whether to copy name if it's an Identifier.
7749
7750    Returns:
7751        The identifier ast node.
7752    """
7753
7754    if name is None:
7755        return None
7756
7757    if isinstance(name, Identifier):
7758        identifier = maybe_copy(name, copy)
7759    elif isinstance(name, str):
7760        identifier = Identifier(
7761            this=name,
7762            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7763        )
7764    else:
7765        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7766    return identifier

Builds an identifier.

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

The identifier ast node.

def parse_identifier( name: str | Identifier, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Identifier:
7769def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7770    """
7771    Parses a given string into an identifier.
7772
7773    Args:
7774        name: The name to parse into an identifier.
7775        dialect: The dialect to parse against.
7776
7777    Returns:
7778        The identifier ast node.
7779    """
7780    try:
7781        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7782    except (ParseError, TokenError):
7783        expression = to_identifier(name)
7784
7785    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:
7791def to_interval(interval: str | Literal) -> Interval:
7792    """Builds an interval expression from a string like '1 day' or '5 months'."""
7793    if isinstance(interval, Literal):
7794        if not interval.is_string:
7795            raise ValueError("Invalid interval string.")
7796
7797        interval = interval.this
7798
7799    interval = maybe_parse(f"INTERVAL {interval}")
7800    assert isinstance(interval, Interval)
7801    return interval

Builds an interval expression from a string like '1 day' or '5 months'.

def to_table( sql_path: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Table:
7804def to_table(
7805    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7806) -> Table:
7807    """
7808    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7809    If a table is passed in then that table is returned.
7810
7811    Args:
7812        sql_path: a `[catalog].[schema].[table]` string.
7813        dialect: the source dialect according to which the table name will be parsed.
7814        copy: Whether to copy a table if it is passed in.
7815        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7816
7817    Returns:
7818        A table expression.
7819    """
7820    if isinstance(sql_path, Table):
7821        return maybe_copy(sql_path, copy=copy)
7822
7823    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7824
7825    for k, v in kwargs.items():
7826        table.set(k, v)
7827
7828    return table

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

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

A table expression.

def to_column( sql_path: str | Column, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **kwargs) -> Column:
7831def to_column(
7832    sql_path: str | Column,
7833    quoted: t.Optional[bool] = None,
7834    dialect: DialectType = None,
7835    copy: bool = True,
7836    **kwargs,
7837) -> Column:
7838    """
7839    Create a column from a `[table].[column]` sql path. Table is optional.
7840    If a column is passed in then that column is returned.
7841
7842    Args:
7843        sql_path: a `[table].[column]` string.
7844        quoted: Whether or not to force quote identifiers.
7845        dialect: the source dialect according to which the column name will be parsed.
7846        copy: Whether to copy a column if it is passed in.
7847        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7848
7849    Returns:
7850        A column expression.
7851    """
7852    if isinstance(sql_path, Column):
7853        return maybe_copy(sql_path, copy=copy)
7854
7855    try:
7856        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7857    except ParseError:
7858        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7859
7860    for k, v in kwargs.items():
7861        col.set(k, v)
7862
7863    if quoted:
7864        for i in col.find_all(Identifier):
7865            i.set("quoted", True)
7866
7867    return col

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

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

A column expression.

def alias_( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType], table: Union[bool, Sequence[str | Identifier]] = False, quoted: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts):
7870def alias_(
7871    expression: ExpOrStr,
7872    alias: t.Optional[str | Identifier],
7873    table: bool | t.Sequence[str | Identifier] = False,
7874    quoted: t.Optional[bool] = None,
7875    dialect: DialectType = None,
7876    copy: bool = True,
7877    **opts,
7878):
7879    """Create an Alias expression.
7880
7881    Example:
7882        >>> alias_('foo', 'bar').sql()
7883        'foo AS bar'
7884
7885        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7886        '(SELECT 1, 2) AS bar(a, b)'
7887
7888    Args:
7889        expression: the SQL code strings to parse.
7890            If an Expression instance is passed, this is used as-is.
7891        alias: the alias name to use. If the name has
7892            special characters it is quoted.
7893        table: Whether to create a table alias, can also be a list of columns.
7894        quoted: whether to quote the alias
7895        dialect: the dialect used to parse the input expression.
7896        copy: Whether to copy the expression.
7897        **opts: other options to use to parse the input expressions.
7898
7899    Returns:
7900        Alias: the aliased expression
7901    """
7902    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7903    alias = to_identifier(alias, quoted=quoted)
7904
7905    if table:
7906        table_alias = TableAlias(this=alias)
7907        exp.set("alias", table_alias)
7908
7909        if not isinstance(table, bool):
7910            for column in table:
7911                table_alias.append("columns", to_identifier(column, quoted=quoted))
7912
7913        return exp
7914
7915    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7916    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7917    # for the complete Window expression.
7918    #
7919    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7920
7921    if "alias" in exp.arg_types and not isinstance(exp, Window):
7922        exp.set("alias", alias)
7923        return exp
7924    return Alias(this=exp, alias=alias)

Create an Alias expression.

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

Alias: the aliased expression

def subquery( expression: Union[str, Expression], alias: Union[Identifier, str, NoneType] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Select:
7927def subquery(
7928    expression: ExpOrStr,
7929    alias: t.Optional[Identifier | str] = None,
7930    dialect: DialectType = None,
7931    **opts,
7932) -> Select:
7933    """
7934    Build a subquery expression that's selected from.
7935
7936    Example:
7937        >>> subquery('select x from tbl', 'bar').select('x').sql()
7938        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7939
7940    Args:
7941        expression: the SQL code strings to parse.
7942            If an Expression instance is passed, this is used as-is.
7943        alias: the alias name to use.
7944        dialect: the dialect used to parse the input expression.
7945        **opts: other options to use to parse the input expressions.
7946
7947    Returns:
7948        A new Select instance with the subquery expression included.
7949    """
7950
7951    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7952    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):
7983def column(
7984    col,
7985    table=None,
7986    db=None,
7987    catalog=None,
7988    *,
7989    fields=None,
7990    quoted=None,
7991    copy=True,
7992):
7993    """
7994    Build a Column.
7995
7996    Args:
7997        col: Column name.
7998        table: Table name.
7999        db: Database name.
8000        catalog: Catalog name.
8001        fields: Additional fields using dots.
8002        quoted: Whether to force quotes on the column's identifiers.
8003        copy: Whether to copy identifiers if passed in.
8004
8005    Returns:
8006        The new Column instance.
8007    """
8008    this = Column(
8009        this=to_identifier(col, quoted=quoted, copy=copy),
8010        table=to_identifier(table, quoted=quoted, copy=copy),
8011        db=to_identifier(db, quoted=quoted, copy=copy),
8012        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8013    )
8014
8015    if fields:
8016        this = Dot.build(
8017            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8018        )
8019    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, Type[sqlglot.dialects.Dialect], NoneType] = None, **opts) -> Cast:
8022def cast(
8023    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8024) -> Cast:
8025    """Cast an expression to a data type.
8026
8027    Example:
8028        >>> cast('x + 1', 'int').sql()
8029        'CAST(x + 1 AS INT)'
8030
8031    Args:
8032        expression: The expression to cast.
8033        to: The datatype to cast to.
8034        copy: Whether to copy the supplied expressions.
8035        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8036            - The expression to be cast is already a exp.Cast expression
8037            - The existing cast is to a type that is logically equivalent to new type
8038
8039            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8040            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8041            and instead just return the original expression `CAST(x as DATETIME)`.
8042
8043            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8044            mapping is applied in the target dialect generator.
8045
8046    Returns:
8047        The new Cast instance.
8048    """
8049    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8050    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8051
8052    # dont re-cast if the expression is already a cast to the correct type
8053    if isinstance(expr, Cast):
8054        from sqlglot.dialects.dialect import Dialect
8055
8056        target_dialect = Dialect.get_or_raise(dialect)
8057        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8058
8059        existing_cast_type: DataType.Type = expr.to.this
8060        new_cast_type: DataType.Type = data_type.this
8061        types_are_equivalent = type_mapping.get(
8062            existing_cast_type, existing_cast_type.value
8063        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8064
8065        if expr.is_type(data_type) or types_are_equivalent:
8066            return expr
8067
8068    expr = Cast(this=expr, to=data_type)
8069    expr.type = data_type
8070
8071    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:
8074def table_(
8075    table: Identifier | str,
8076    db: t.Optional[Identifier | str] = None,
8077    catalog: t.Optional[Identifier | str] = None,
8078    quoted: t.Optional[bool] = None,
8079    alias: t.Optional[Identifier | str] = None,
8080) -> Table:
8081    """Build a Table.
8082
8083    Args:
8084        table: Table name.
8085        db: Database name.
8086        catalog: Catalog name.
8087        quote: Whether to force quotes on the table's identifiers.
8088        alias: Table's alias.
8089
8090    Returns:
8091        The new Table instance.
8092    """
8093    return Table(
8094        this=to_identifier(table, quoted=quoted) if table else None,
8095        db=to_identifier(db, quoted=quoted) if db else None,
8096        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8097        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8098    )

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:
8101def values(
8102    values: t.Iterable[t.Tuple[t.Any, ...]],
8103    alias: t.Optional[str] = None,
8104    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8105) -> Values:
8106    """Build VALUES statement.
8107
8108    Example:
8109        >>> values([(1, '2')]).sql()
8110        "VALUES (1, '2')"
8111
8112    Args:
8113        values: values statements that will be converted to SQL
8114        alias: optional alias
8115        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8116         If either are provided then an alias is also required.
8117
8118    Returns:
8119        Values: the Values expression object
8120    """
8121    if columns and not alias:
8122        raise ValueError("Alias is required when providing columns")
8123
8124    return Values(
8125        expressions=[convert(tup) for tup in values],
8126        alias=(
8127            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8128            if columns
8129            else (TableAlias(this=to_identifier(alias)) if alias else None)
8130        ),
8131    )

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:
8134def var(name: t.Optional[ExpOrStr]) -> Var:
8135    """Build a SQL variable.
8136
8137    Example:
8138        >>> repr(var('x'))
8139        'Var(this=x)'
8140
8141        >>> repr(var(column('x', table='y')))
8142        'Var(this=x)'
8143
8144    Args:
8145        name: The name of the var or an expression who's name will become the var.
8146
8147    Returns:
8148        The new variable node.
8149    """
8150    if not name:
8151        raise ValueError("Cannot convert empty name into var.")
8152
8153    if isinstance(name, Expression):
8154        name = name.name
8155    return Var(this=name)

Build a SQL variable.

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

The new variable node.

def rename_table( old_name: str | Table, new_name: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
8158def rename_table(
8159    old_name: str | Table,
8160    new_name: str | Table,
8161    dialect: DialectType = None,
8162) -> Alter:
8163    """Build ALTER TABLE... RENAME... expression
8164
8165    Args:
8166        old_name: The old name of the table
8167        new_name: The new name of the table
8168        dialect: The dialect to parse the table.
8169
8170    Returns:
8171        Alter table expression
8172    """
8173    old_table = to_table(old_name, dialect=dialect)
8174    new_table = to_table(new_name, dialect=dialect)
8175    return Alter(
8176        this=old_table,
8177        kind="TABLE",
8178        actions=[
8179            AlterRename(this=new_table),
8180        ],
8181    )

Build ALTER TABLE... RENAME... expression

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

Alter table expression

def rename_column( table_name: str | Table, old_column_name: str | Column, new_column_name: str | Column, exists: Optional[bool] = None, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None) -> Alter:
8184def rename_column(
8185    table_name: str | Table,
8186    old_column_name: str | Column,
8187    new_column_name: str | Column,
8188    exists: t.Optional[bool] = None,
8189    dialect: DialectType = None,
8190) -> Alter:
8191    """Build ALTER TABLE... RENAME COLUMN... expression
8192
8193    Args:
8194        table_name: Name of the table
8195        old_column: The old name of the column
8196        new_column: The new name of the column
8197        exists: Whether to add the `IF EXISTS` clause
8198        dialect: The dialect to parse the table/column.
8199
8200    Returns:
8201        Alter table expression
8202    """
8203    table = to_table(table_name, dialect=dialect)
8204    old_column = to_column(old_column_name, dialect=dialect)
8205    new_column = to_column(new_column_name, dialect=dialect)
8206    return Alter(
8207        this=table,
8208        kind="TABLE",
8209        actions=[
8210            RenameColumn(this=old_column, to=new_column, exists=exists),
8211        ],
8212    )

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:
8215def convert(value: t.Any, copy: bool = False) -> Expression:
8216    """Convert a python value into an expression object.
8217
8218    Raises an error if a conversion is not possible.
8219
8220    Args:
8221        value: A python object.
8222        copy: Whether to copy `value` (only applies to Expressions and collections).
8223
8224    Returns:
8225        The equivalent expression object.
8226    """
8227    if isinstance(value, Expression):
8228        return maybe_copy(value, copy)
8229    if isinstance(value, str):
8230        return Literal.string(value)
8231    if isinstance(value, bool):
8232        return Boolean(this=value)
8233    if value is None or (isinstance(value, float) and math.isnan(value)):
8234        return null()
8235    if isinstance(value, numbers.Number):
8236        return Literal.number(value)
8237    if isinstance(value, bytes):
8238        return HexString(this=value.hex())
8239    if isinstance(value, datetime.datetime):
8240        datetime_literal = Literal.string(value.isoformat(sep=" "))
8241
8242        tz = None
8243        if value.tzinfo:
8244            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8245            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8246            tz = Literal.string(str(value.tzinfo))
8247
8248        return TimeStrToTime(this=datetime_literal, zone=tz)
8249    if isinstance(value, datetime.date):
8250        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8251        return DateStrToDate(this=date_literal)
8252    if isinstance(value, tuple):
8253        if hasattr(value, "_fields"):
8254            return Struct(
8255                expressions=[
8256                    PropertyEQ(
8257                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8258                    )
8259                    for k in value._fields
8260                ]
8261            )
8262        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8263    if isinstance(value, list):
8264        return Array(expressions=[convert(v, copy=copy) for v in value])
8265    if isinstance(value, dict):
8266        return Map(
8267            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8268            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8269        )
8270    if hasattr(value, "__dict__"):
8271        return Struct(
8272            expressions=[
8273                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8274                for k, v in value.__dict__.items()
8275            ]
8276        )
8277    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:
8280def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8281    """
8282    Replace children of an expression with the result of a lambda fun(child) -> exp.
8283    """
8284    for k, v in tuple(expression.args.items()):
8285        is_list_arg = type(v) is list
8286
8287        child_nodes = v if is_list_arg else [v]
8288        new_child_nodes = []
8289
8290        for cn in child_nodes:
8291            if isinstance(cn, Expression):
8292                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8293                    new_child_nodes.append(child_node)
8294            else:
8295                new_child_nodes.append(cn)
8296
8297        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:
8300def replace_tree(
8301    expression: Expression,
8302    fun: t.Callable,
8303    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8304) -> Expression:
8305    """
8306    Replace an entire tree with the result of function calls on each node.
8307
8308    This will be traversed in reverse dfs, so leaves first.
8309    If new nodes are created as a result of function calls, they will also be traversed.
8310    """
8311    stack = list(expression.dfs(prune=prune))
8312
8313    while stack:
8314        node = stack.pop()
8315        new_node = fun(node)
8316
8317        if new_node is not node:
8318            node.replace(new_node)
8319
8320            if isinstance(new_node, Expression):
8321                stack.append(new_node)
8322
8323    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]:
8326def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8327    """
8328    Return all table names referenced through columns in an expression.
8329
8330    Example:
8331        >>> import sqlglot
8332        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8333        ['a', 'c']
8334
8335    Args:
8336        expression: expression to find table names.
8337        exclude: a table name to exclude
8338
8339    Returns:
8340        A list of unique names.
8341    """
8342    return {
8343        table
8344        for table in (column.table for column in expression.find_all(Column))
8345        if table and table != exclude
8346    }

Return all table names referenced through columns in an expression.

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

A list of unique names.

def table_name( table: Table | str, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, identify: bool = False) -> str:
8349def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8350    """Get the full name of a table as a string.
8351
8352    Args:
8353        table: Table expression node or string.
8354        dialect: The dialect to generate the table name for.
8355        identify: Determines when an identifier should be quoted. Possible values are:
8356            False (default): Never quote, except in cases where it's mandatory by the dialect.
8357            True: Always quote.
8358
8359    Examples:
8360        >>> from sqlglot import exp, parse_one
8361        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8362        'a.b.c'
8363
8364    Returns:
8365        The table name.
8366    """
8367
8368    table = maybe_parse(table, into=Table, dialect=dialect)
8369
8370    if not table:
8371        raise ValueError(f"Cannot parse {table}")
8372
8373    return ".".join(
8374        (
8375            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8376            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8377            else part.name
8378        )
8379        for part in table.parts
8380    )

Get the full name of a table as a string.

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

The table name.

def normalize_table_name( table: str | Table, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> str:
8383def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8384    """Returns a case normalized table name without quotes.
8385
8386    Args:
8387        table: the table to normalize
8388        dialect: the dialect to use for normalization rules
8389        copy: whether to copy the expression.
8390
8391    Examples:
8392        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8393        'A-B.c'
8394    """
8395    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8396
8397    return ".".join(
8398        p.name
8399        for p in normalize_identifiers(
8400            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8401        ).parts
8402    )

Returns a case normalized table name without quotes.

Arguments:
  • table: the table to normalize
  • dialect: the dialect to use for normalization rules
  • copy: whether to copy the expression.
Examples:
>>> normalize_table_name("`A-B`.c", dialect="bigquery")
'A-B.c'
def replace_tables( expression: ~E, mapping: Dict[str, str], dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> ~E:
8405def replace_tables(
8406    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8407) -> E:
8408    """Replace all tables in expression according to the mapping.
8409
8410    Args:
8411        expression: expression node to be transformed and replaced.
8412        mapping: mapping of table names.
8413        dialect: the dialect of the mapping table
8414        copy: whether to copy the expression.
8415
8416    Examples:
8417        >>> from sqlglot import exp, parse_one
8418        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8419        'SELECT * FROM c /* a.b */'
8420
8421    Returns:
8422        The mapped expression.
8423    """
8424
8425    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8426
8427    def _replace_tables(node: Expression) -> Expression:
8428        if isinstance(node, Table) and node.meta.get("replace") is not False:
8429            original = normalize_table_name(node, dialect=dialect)
8430            new_name = mapping.get(original)
8431
8432            if new_name:
8433                table = to_table(
8434                    new_name,
8435                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8436                    dialect=dialect,
8437                )
8438                table.add_comments([original])
8439                return table
8440        return node
8441
8442    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:
8445def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8446    """Replace placeholders in an expression.
8447
8448    Args:
8449        expression: expression node to be transformed and replaced.
8450        args: positional names that will substitute unnamed placeholders in the given order.
8451        kwargs: keyword arguments that will substitute named placeholders.
8452
8453    Examples:
8454        >>> from sqlglot import exp, parse_one
8455        >>> replace_placeholders(
8456        ...     parse_one("select * from :tbl where ? = ?"),
8457        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8458        ... ).sql()
8459        "SELECT * FROM foo WHERE str_col = 'b'"
8460
8461    Returns:
8462        The mapped expression.
8463    """
8464
8465    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8466        if isinstance(node, Placeholder):
8467            if node.this:
8468                new_name = kwargs.get(node.this)
8469                if new_name is not None:
8470                    return convert(new_name)
8471            else:
8472                try:
8473                    return convert(next(args))
8474                except StopIteration:
8475                    pass
8476        return node
8477
8478    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, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Expression:
8481def expand(
8482    expression: Expression,
8483    sources: t.Dict[str, Query],
8484    dialect: DialectType = None,
8485    copy: bool = True,
8486) -> Expression:
8487    """Transforms an expression by expanding all referenced sources into subqueries.
8488
8489    Examples:
8490        >>> from sqlglot import parse_one
8491        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8492        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8493
8494        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8495        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8496
8497    Args:
8498        expression: The expression to expand.
8499        sources: A dictionary of name to Queries.
8500        dialect: The dialect of the sources dict.
8501        copy: Whether to copy the expression during transformation. Defaults to True.
8502
8503    Returns:
8504        The transformed expression.
8505    """
8506    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8507
8508    def _expand(node: Expression):
8509        if isinstance(node, Table):
8510            name = normalize_table_name(node, dialect=dialect)
8511            source = sources.get(name)
8512            if source:
8513                subquery = source.subquery(node.alias or name)
8514                subquery.comments = [f"source: {name}"]
8515                return subquery.transform(_expand, copy=False)
8516        return node
8517
8518    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, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Func:
8521def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8522    """
8523    Returns a Func expression.
8524
8525    Examples:
8526        >>> func("abs", 5).sql()
8527        'ABS(5)'
8528
8529        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8530        'CAST(5 AS DOUBLE)'
8531
8532    Args:
8533        name: the name of the function to build.
8534        args: the args used to instantiate the function of interest.
8535        copy: whether to copy the argument expressions.
8536        dialect: the source dialect.
8537        kwargs: the kwargs used to instantiate the function of interest.
8538
8539    Note:
8540        The arguments `args` and `kwargs` are mutually exclusive.
8541
8542    Returns:
8543        An instance of the function of interest, or an anonymous function, if `name` doesn't
8544        correspond to an existing `sqlglot.expressions.Func` class.
8545    """
8546    if args and kwargs:
8547        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8548
8549    from sqlglot.dialects.dialect import Dialect
8550
8551    dialect = Dialect.get_or_raise(dialect)
8552
8553    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8554    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8555
8556    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8557    if constructor:
8558        if converted:
8559            if "dialect" in constructor.__code__.co_varnames:
8560                function = constructor(converted, dialect=dialect)
8561            else:
8562                function = constructor(converted)
8563        elif constructor.__name__ == "from_arg_list":
8564            function = constructor.__self__(**kwargs)  # type: ignore
8565        else:
8566            constructor = FUNCTION_BY_NAME.get(name.upper())
8567            if constructor:
8568                function = constructor(**kwargs)
8569            else:
8570                raise ValueError(
8571                    f"Unable to convert '{name}' into a Func. Either manually construct "
8572                    "the Func expression of interest or parse the function call."
8573                )
8574    else:
8575        kwargs = kwargs or {"expressions": converted}
8576        function = Anonymous(this=name, **kwargs)
8577
8578    for error_message in function.error_messages(converted):
8579        raise ValueError(error_message)
8580
8581    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:
8584def case(
8585    expression: t.Optional[ExpOrStr] = None,
8586    **opts,
8587) -> Case:
8588    """
8589    Initialize a CASE statement.
8590
8591    Example:
8592        case().when("a = 1", "foo").else_("bar")
8593
8594    Args:
8595        expression: Optionally, the input expression (not all dialects support this)
8596        **opts: Extra keyword arguments for parsing `expression`
8597    """
8598    if expression is not None:
8599        this = maybe_parse(expression, **opts)
8600    else:
8601        this = None
8602    return Case(this=this, ifs=[])

Initialize a CASE statement.

Example:

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

Arguments:
  • expression: Optionally, the input expression (not all dialects support this)
  • **opts: Extra keyword arguments for parsing expression
def array( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Array:
8605def array(
8606    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8607) -> Array:
8608    """
8609    Returns an array.
8610
8611    Examples:
8612        >>> array(1, 'x').sql()
8613        'ARRAY(1, x)'
8614
8615    Args:
8616        expressions: the expressions to add to the array.
8617        copy: whether to copy the argument expressions.
8618        dialect: the source dialect.
8619        kwargs: the kwargs used to instantiate the function of interest.
8620
8621    Returns:
8622        An array expression.
8623    """
8624    return Array(
8625        expressions=[
8626            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8627            for expression in expressions
8628        ]
8629    )

Returns an array.

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

An array expression.

def tuple_( *expressions: Union[str, Expression], copy: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, **kwargs) -> Tuple:
8632def tuple_(
8633    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8634) -> Tuple:
8635    """
8636    Returns an tuple.
8637
8638    Examples:
8639        >>> tuple_(1, 'x').sql()
8640        '(1, x)'
8641
8642    Args:
8643        expressions: the expressions to add to the tuple.
8644        copy: whether to copy the argument expressions.
8645        dialect: the source dialect.
8646        kwargs: the kwargs used to instantiate the function of interest.
8647
8648    Returns:
8649        A tuple expression.
8650    """
8651    return Tuple(
8652        expressions=[
8653            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8654            for expression in expressions
8655        ]
8656    )

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:
8659def true() -> Boolean:
8660    """
8661    Returns a true Boolean expression.
8662    """
8663    return Boolean(this=True)

Returns a true Boolean expression.

def false() -> Boolean:
8666def false() -> Boolean:
8667    """
8668    Returns a false Boolean expression.
8669    """
8670    return Boolean(this=False)

Returns a false Boolean expression.

def null() -> Null:
8673def null() -> Null:
8674    """
8675    Returns a Null expression.
8676    """
8677    return Null()

Returns a Null expression.

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