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        "visible": False,
1707    }
1708
1709
1710# https://dev.mysql.com/doc/refman/8.0/en/invisible-indexes.html
1711class AlterIndex(Expression):
1712    arg_types = {"this": True, "visible": True}
1713
1714
1715# https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html
1716class AlterDistStyle(Expression):
1717    pass
1718
1719
1720class AlterSortKey(Expression):
1721    arg_types = {"this": False, "expressions": False, "compound": False}
1722
1723
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    }
1736
1737
1738class RenameColumn(Expression):
1739    arg_types = {"this": True, "to": True, "exists": False}
1740
1741
1742class AlterRename(Expression):
1743    pass
1744
1745
1746class SwapTable(Expression):
1747    pass
1748
1749
1750class Comment(Expression):
1751    arg_types = {
1752        "this": True,
1753        "kind": True,
1754        "expression": True,
1755        "exists": False,
1756        "materialized": False,
1757    }
1758
1759
1760class Comprehension(Expression):
1761    arg_types = {"this": True, "expression": True, "iterator": True, "condition": False}
1762
1763
1764# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1765class MergeTreeTTLAction(Expression):
1766    arg_types = {
1767        "this": True,
1768        "delete": False,
1769        "recompress": False,
1770        "to_disk": False,
1771        "to_volume": False,
1772    }
1773
1774
1775# https://clickhouse.com/docs/en/engines/table-engines/mergetree-family/mergetree#mergetree-table-ttl
1776class MergeTreeTTL(Expression):
1777    arg_types = {
1778        "expressions": True,
1779        "where": False,
1780        "group": False,
1781        "aggregates": False,
1782    }
1783
1784
1785# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
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    }
1796
1797
1798class ColumnConstraint(Expression):
1799    arg_types = {"this": False, "kind": True}
1800
1801    @property
1802    def kind(self) -> ColumnConstraintKind:
1803        return self.args["kind"]
1804
1805
1806class ColumnConstraintKind(Expression):
1807    pass
1808
1809
1810class AutoIncrementColumnConstraint(ColumnConstraintKind):
1811    pass
1812
1813
1814class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1815    arg_types = {"this": True, "expression": True}
1816
1817
1818class CaseSpecificColumnConstraint(ColumnConstraintKind):
1819    arg_types = {"not_": True}
1820
1821
1822class CharacterSetColumnConstraint(ColumnConstraintKind):
1823    arg_types = {"this": True}
1824
1825
1826class CheckColumnConstraint(ColumnConstraintKind):
1827    arg_types = {"this": True, "enforced": False}
1828
1829
1830class ClusteredColumnConstraint(ColumnConstraintKind):
1831    pass
1832
1833
1834class CollateColumnConstraint(ColumnConstraintKind):
1835    pass
1836
1837
1838class CommentColumnConstraint(ColumnConstraintKind):
1839    pass
1840
1841
1842class CompressColumnConstraint(ColumnConstraintKind):
1843    arg_types = {"this": False}
1844
1845
1846class DateFormatColumnConstraint(ColumnConstraintKind):
1847    arg_types = {"this": True}
1848
1849
1850class DefaultColumnConstraint(ColumnConstraintKind):
1851    pass
1852
1853
1854class EncodeColumnConstraint(ColumnConstraintKind):
1855    pass
1856
1857
1858# https://www.postgresql.org/docs/current/sql-createtable.html#SQL-CREATETABLE-EXCLUDE
1859class ExcludeColumnConstraint(ColumnConstraintKind):
1860    pass
1861
1862
1863class EphemeralColumnConstraint(ColumnConstraintKind):
1864    arg_types = {"this": False}
1865
1866
1867class WithOperator(Expression):
1868    arg_types = {"this": True, "op": True}
1869
1870
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    }
1883
1884
1885class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1886    arg_types = {"start": False, "hidden": False}
1887
1888
1889# https://dev.mysql.com/doc/refman/8.0/en/create-table.html
1890# https://github.com/ClickHouse/ClickHouse/blob/master/src/Parsers/ParserCreateQuery.h#L646
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    }
1901
1902
1903class InlineLengthColumnConstraint(ColumnConstraintKind):
1904    pass
1905
1906
1907class NonClusteredColumnConstraint(ColumnConstraintKind):
1908    pass
1909
1910
1911class NotForReplicationColumnConstraint(ColumnConstraintKind):
1912    arg_types = {}
1913
1914
1915# https://docs.snowflake.com/en/sql-reference/sql/create-table
1916class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1917    arg_types = {"this": True, "expressions": False}
1918
1919
1920class NotNullColumnConstraint(ColumnConstraintKind):
1921    arg_types = {"allow_null": False}
1922
1923
1924# https://dev.mysql.com/doc/refman/5.7/en/timestamp-initialization.html
1925class OnUpdateColumnConstraint(ColumnConstraintKind):
1926    pass
1927
1928
1929# https://docs.snowflake.com/en/sql-reference/sql/create-external-table#optional-parameters
1930class TransformColumnConstraint(ColumnConstraintKind):
1931    pass
1932
1933
1934class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1935    arg_types = {"desc": False}
1936
1937
1938class TitleColumnConstraint(ColumnConstraintKind):
1939    pass
1940
1941
1942class UniqueColumnConstraint(ColumnConstraintKind):
1943    arg_types = {"this": False, "index_type": False, "on_conflict": False, "nulls": False}
1944
1945
1946class UppercaseColumnConstraint(ColumnConstraintKind):
1947    arg_types: t.Dict[str, t.Any] = {}
1948
1949
1950# https://docs.risingwave.com/processing/watermarks#syntax
1951class WatermarkColumnConstraint(Expression):
1952    arg_types = {"this": True, "expression": True}
1953
1954
1955class PathColumnConstraint(ColumnConstraintKind):
1956    pass
1957
1958
1959# https://docs.snowflake.com/en/sql-reference/sql/create-table
1960class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1961    pass
1962
1963
1964# computed column expression
1965# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-table-transact-sql?view=sql-server-ver16
1966class ComputedColumnConstraint(ColumnConstraintKind):
1967    arg_types = {"this": True, "persisted": False, "not_null": False}
1968
1969
1970class Constraint(Expression):
1971    arg_types = {"this": True, "expressions": True}
1972
1973
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        )
2057
2058
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()
2078
2079
2080# https://cloud.google.com/bigquery/docs/reference/standard-sql/export-statements
2081class Export(Expression):
2082    arg_types = {"this": True, "connection": False, "options": True}
2083
2084
2085class Filter(Expression):
2086    arg_types = {"this": True, "expression": True}
2087
2088
2089class Check(Expression):
2090    pass
2091
2092
2093class Changes(Expression):
2094    arg_types = {"information": True, "at_before": False, "end": False}
2095
2096
2097# https://docs.snowflake.com/en/sql-reference/constructs/connect-by
2098class Connect(Expression):
2099    arg_types = {"start": False, "connect": True, "nocycle": False}
2100
2101
2102class CopyParameter(Expression):
2103    arg_types = {"this": True, "expression": False, "expressions": False}
2104
2105
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    }
2115
2116
2117class Credentials(Expression):
2118    arg_types = {
2119        "credentials": False,
2120        "encryption": False,
2121        "storage": False,
2122        "iam_role": False,
2123        "region": False,
2124    }
2125
2126
2127class Prior(Expression):
2128    pass
2129
2130
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}
2134
2135
2136class ForeignKey(Expression):
2137    arg_types = {
2138        "expressions": False,
2139        "reference": False,
2140        "delete": False,
2141        "update": False,
2142    }
2143
2144
2145class ColumnPrefix(Expression):
2146    arg_types = {"this": True, "expression": True}
2147
2148
2149class PrimaryKey(Expression):
2150    arg_types = {"expressions": True, "options": False}
2151
2152
2153# https://www.postgresql.org/docs/9.1/sql-selectinto.html
2154# https://docs.aws.amazon.com/redshift/latest/dg/r_SELECT_INTO.html#r_SELECT_INTO-examples
2155class Into(Expression):
2156    arg_types = {
2157        "this": False,
2158        "temporary": False,
2159        "unlogged": False,
2160        "bulk_collect": False,
2161        "expressions": False,
2162    }
2163
2164
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
2173
2174
2175class Having(Expression):
2176    pass
2177
2178
2179class Hint(Expression):
2180    arg_types = {"expressions": True}
2181
2182
2183class JoinHint(Expression):
2184    arg_types = {"this": True, "expressions": True}
2185
2186
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
2201
2202
2203# https://www.postgresql.org/docs/current/indexes-opclass.html
2204class Opclass(Expression):
2205    arg_types = {"this": True, "expression": True}
2206
2207
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    }
2217
2218
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    }
2230
2231
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        )
2298
2299
2300class ConditionalInsert(Expression):
2301    arg_types = {"this": True, "expression": False, "else_": False}
2302
2303
2304class MultitableInserts(Expression):
2305    arg_types = {"expressions": True, "kind": True, "source": True}
2306
2307
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    }
2317
2318
2319class OnCondition(Expression):
2320    arg_types = {"error": False, "empty": False, "null": False}
2321
2322
2323class Returning(Expression):
2324    arg_types = {"expressions": True, "into": False}
2325
2326
2327# https://dev.mysql.com/doc/refman/8.0/en/charset-introducer.html
2328class Introducer(Expression):
2329    arg_types = {"this": True, "expression": True}
2330
2331
2332# national char, like n'utf8'
2333class National(Expression):
2334    pass
2335
2336
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    }
2347
2348
2349class Partition(Expression):
2350    arg_types = {"expressions": True, "subpartition": False}
2351
2352
2353class PartitionRange(Expression):
2354    arg_types = {"this": True, "expression": True}
2355
2356
2357# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#how-to-set-partition-expression
2358class PartitionId(Expression):
2359    pass
2360
2361
2362class Fetch(Expression):
2363    arg_types = {
2364        "direction": False,
2365        "count": False,
2366        "limit_options": False,
2367    }
2368
2369
2370class Grant(Expression):
2371    arg_types = {
2372        "privileges": True,
2373        "kind": False,
2374        "securable": True,
2375        "principals": True,
2376        "grant_option": False,
2377    }
2378
2379
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    }
2389
2390
2391class Cube(Expression):
2392    arg_types = {"expressions": False}
2393
2394
2395class Rollup(Expression):
2396    arg_types = {"expressions": False}
2397
2398
2399class GroupingSets(Expression):
2400    arg_types = {"expressions": True}
2401
2402
2403class Lambda(Expression):
2404    arg_types = {"this": True, "expressions": True}
2405
2406
2407class Limit(Expression):
2408    arg_types = {
2409        "this": False,
2410        "expression": True,
2411        "offset": False,
2412        "limit_options": False,
2413        "expressions": False,
2414    }
2415
2416
2417class LimitOptions(Expression):
2418    arg_types = {
2419        "percent": False,
2420        "rows": False,
2421        "with_ties": False,
2422    }
2423
2424
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
2451
2452
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
2577
2578
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    }
2587
2588
2589class MatchRecognizeMeasure(Expression):
2590    arg_types = {
2591        "this": True,
2592        "window_frame": False,
2593    }
2594
2595
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    }
2607
2608
2609# Clickhouse FROM FINAL modifier
2610# https://clickhouse.com/docs/en/sql-reference/statements/select/from/#final-modifier
2611class Final(Expression):
2612    pass
2613
2614
2615class Offset(Expression):
2616    arg_types = {"this": False, "expression": True, "expressions": False}
2617
2618
2619class Order(Expression):
2620    arg_types = {"this": False, "expressions": True, "siblings": False}
2621
2622
2623# https://clickhouse.com/docs/en/sql-reference/statements/select/order-by#order-by-expr-with-fill-modifier
2624class WithFill(Expression):
2625    arg_types = {
2626        "from": False,
2627        "to": False,
2628        "step": False,
2629        "interpolate": False,
2630    }
2631
2632
2633# hive specific sorts
2634# https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy
2635class Cluster(Order):
2636    pass
2637
2638
2639class Distribute(Order):
2640    pass
2641
2642
2643class Sort(Order):
2644    pass
2645
2646
2647class Ordered(Expression):
2648    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2649
2650
2651class Property(Expression):
2652    arg_types = {"this": True, "value": True}
2653
2654
2655class GrantPrivilege(Expression):
2656    arg_types = {"this": True, "expressions": False}
2657
2658
2659class GrantPrincipal(Expression):
2660    arg_types = {"this": True, "kind": False}
2661
2662
2663class AllowedValuesProperty(Expression):
2664    arg_types = {"expressions": True}
2665
2666
2667class AlgorithmProperty(Property):
2668    arg_types = {"this": True}
2669
2670
2671class AutoIncrementProperty(Property):
2672    arg_types = {"this": True}
2673
2674
2675# https://docs.aws.amazon.com/prescriptive-guidance/latest/materialized-views-redshift/refreshing-materialized-views.html
2676class AutoRefreshProperty(Property):
2677    arg_types = {"this": True}
2678
2679
2680class BackupProperty(Property):
2681    arg_types = {"this": True}
2682
2683
2684class BlockCompressionProperty(Property):
2685    arg_types = {
2686        "autotemp": False,
2687        "always": False,
2688        "default": False,
2689        "manual": False,
2690        "never": False,
2691    }
2692
2693
2694class CharacterSetProperty(Property):
2695    arg_types = {"this": True, "default": True}
2696
2697
2698class ChecksumProperty(Property):
2699    arg_types = {"on": False, "default": False}
2700
2701
2702class CollateProperty(Property):
2703    arg_types = {"this": True, "default": False}
2704
2705
2706class CopyGrantsProperty(Property):
2707    arg_types = {}
2708
2709
2710class DataBlocksizeProperty(Property):
2711    arg_types = {
2712        "size": False,
2713        "units": False,
2714        "minimum": False,
2715        "maximum": False,
2716        "default": False,
2717    }
2718
2719
2720class DataDeletionProperty(Property):
2721    arg_types = {"on": True, "filter_col": False, "retention_period": False}
2722
2723
2724class DefinerProperty(Property):
2725    arg_types = {"this": True}
2726
2727
2728class DistKeyProperty(Property):
2729    arg_types = {"this": True}
2730
2731
2732# https://docs.starrocks.io/docs/sql-reference/sql-statements/data-definition/CREATE_TABLE/#distribution_desc
2733# https://doris.apache.org/docs/sql-manual/sql-statements/Data-Definition-Statements/Create/CREATE-TABLE?_highlight=create&_highlight=table#distribution_desc
2734class DistributedByProperty(Property):
2735    arg_types = {"expressions": False, "kind": True, "buckets": False, "order": False}
2736
2737
2738class DistStyleProperty(Property):
2739    arg_types = {"this": True}
2740
2741
2742class DuplicateKeyProperty(Property):
2743    arg_types = {"expressions": True}
2744
2745
2746class EngineProperty(Property):
2747    arg_types = {"this": True}
2748
2749
2750class HeapProperty(Property):
2751    arg_types = {}
2752
2753
2754class ToTableProperty(Property):
2755    arg_types = {"this": True}
2756
2757
2758class ExecuteAsProperty(Property):
2759    arg_types = {"this": True}
2760
2761
2762class ExternalProperty(Property):
2763    arg_types = {"this": False}
2764
2765
2766class FallbackProperty(Property):
2767    arg_types = {"no": True, "protection": False}
2768
2769
2770class FileFormatProperty(Property):
2771    arg_types = {"this": True}
2772
2773
2774class FreespaceProperty(Property):
2775    arg_types = {"this": True, "percent": False}
2776
2777
2778class GlobalProperty(Property):
2779    arg_types = {}
2780
2781
2782class IcebergProperty(Property):
2783    arg_types = {}
2784
2785
2786class InheritsProperty(Property):
2787    arg_types = {"expressions": True}
2788
2789
2790class InputModelProperty(Property):
2791    arg_types = {"this": True}
2792
2793
2794class OutputModelProperty(Property):
2795    arg_types = {"this": True}
2796
2797
2798class IsolatedLoadingProperty(Property):
2799    arg_types = {"no": False, "concurrent": False, "target": False}
2800
2801
2802class JournalProperty(Property):
2803    arg_types = {
2804        "no": False,
2805        "dual": False,
2806        "before": False,
2807        "local": False,
2808        "after": False,
2809    }
2810
2811
2812class LanguageProperty(Property):
2813    arg_types = {"this": True}
2814
2815
2816# spark ddl
2817class ClusteredByProperty(Property):
2818    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
2819
2820
2821class DictProperty(Property):
2822    arg_types = {"this": True, "kind": True, "settings": False}
2823
2824
2825class DictSubProperty(Property):
2826    pass
2827
2828
2829class DictRange(Property):
2830    arg_types = {"this": True, "min": True, "max": True}
2831
2832
2833class DynamicProperty(Property):
2834    arg_types = {}
2835
2836
2837# Clickhouse CREATE ... ON CLUSTER modifier
2838# https://clickhouse.com/docs/en/sql-reference/distributed-ddl
2839class OnCluster(Property):
2840    arg_types = {"this": True}
2841
2842
2843# Clickhouse EMPTY table "property"
2844class EmptyProperty(Property):
2845    arg_types = {}
2846
2847
2848class LikeProperty(Property):
2849    arg_types = {"this": True, "expressions": False}
2850
2851
2852class LocationProperty(Property):
2853    arg_types = {"this": True}
2854
2855
2856class LockProperty(Property):
2857    arg_types = {"this": True}
2858
2859
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    }
2868
2869
2870class LogProperty(Property):
2871    arg_types = {"no": True}
2872
2873
2874class MaterializedProperty(Property):
2875    arg_types = {"this": False}
2876
2877
2878class MergeBlockRatioProperty(Property):
2879    arg_types = {"this": False, "no": False, "default": False, "percent": False}
2880
2881
2882class NoPrimaryIndexProperty(Property):
2883    arg_types = {}
2884
2885
2886class OnProperty(Property):
2887    arg_types = {"this": True}
2888
2889
2890class OnCommitProperty(Property):
2891    arg_types = {"delete": False}
2892
2893
2894class PartitionedByProperty(Property):
2895    arg_types = {"this": True}
2896
2897
2898# https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE/
2899class PartitionByRangeProperty(Property):
2900    arg_types = {"partition_expressions": True, "create_expressions": True}
2901
2902
2903# https://docs.starrocks.io/docs/table_design/data_distribution/#range-partitioning
2904class PartitionByRangePropertyDynamic(Expression):
2905    arg_types = {"this": False, "start": True, "end": True, "every": True}
2906
2907
2908# https://docs.starrocks.io/docs/sql-reference/sql-statements/table_bucket_part_index/CREATE_TABLE/
2909class UniqueKeyProperty(Property):
2910    arg_types = {"expressions": True}
2911
2912
2913# https://www.postgresql.org/docs/current/sql-createtable.html
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    }
2922
2923
2924class PartitionedOfProperty(Property):
2925    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2926    arg_types = {"this": True, "expression": True}
2927
2928
2929class StreamingTableProperty(Property):
2930    arg_types = {}
2931
2932
2933class RemoteWithConnectionModelProperty(Property):
2934    arg_types = {"this": True}
2935
2936
2937class ReturnsProperty(Property):
2938    arg_types = {"this": False, "is_table": False, "table": False, "null": False}
2939
2940
2941class StrictProperty(Property):
2942    arg_types = {}
2943
2944
2945class RowFormatProperty(Property):
2946    arg_types = {"this": True}
2947
2948
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    }
2960
2961
2962class RowFormatSerdeProperty(Property):
2963    arg_types = {"this": True, "serde_properties": False}
2964
2965
2966# https://spark.apache.org/docs/3.1.2/sql-ref-syntax-qry-select-transform.html
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    }
2977
2978
2979class SampleProperty(Property):
2980    arg_types = {"this": True}
2981
2982
2983# https://prestodb.io/docs/current/sql/create-view.html#synopsis
2984class SecurityProperty(Property):
2985    arg_types = {"this": True}
2986
2987
2988class SchemaCommentProperty(Property):
2989    arg_types = {"this": True}
2990
2991
2992class SerdeProperties(Property):
2993    arg_types = {"expressions": True, "with": False}
2994
2995
2996class SetProperty(Property):
2997    arg_types = {"multi": True}
2998
2999
3000class SharingProperty(Property):
3001    arg_types = {"this": False}
3002
3003
3004class SetConfigProperty(Property):
3005    arg_types = {"this": True}
3006
3007
3008class SettingsProperty(Property):
3009    arg_types = {"expressions": True}
3010
3011
3012class SortKeyProperty(Property):
3013    arg_types = {"this": True, "compound": False}
3014
3015
3016class SqlReadWriteProperty(Property):
3017    arg_types = {"this": True}
3018
3019
3020class SqlSecurityProperty(Property):
3021    arg_types = {"definer": True}
3022
3023
3024class StabilityProperty(Property):
3025    arg_types = {"this": True}
3026
3027
3028class TemporaryProperty(Property):
3029    arg_types = {"this": False}
3030
3031
3032class SecureProperty(Property):
3033    arg_types = {}
3034
3035
3036# https://docs.snowflake.com/en/sql-reference/sql/create-table
3037class Tags(ColumnConstraintKind, Property):
3038    arg_types = {"expressions": True}
3039
3040
3041class TransformModelProperty(Property):
3042    arg_types = {"expressions": True}
3043
3044
3045class TransientProperty(Property):
3046    arg_types = {"this": False}
3047
3048
3049class UnloggedProperty(Property):
3050    arg_types = {}
3051
3052
3053# https://learn.microsoft.com/en-us/sql/t-sql/statements/create-view-transact-sql?view=sql-server-ver16
3054class ViewAttributeProperty(Property):
3055    arg_types = {"this": True}
3056
3057
3058class VolatileProperty(Property):
3059    arg_types = {"this": False}
3060
3061
3062class WithDataProperty(Property):
3063    arg_types = {"no": True, "statistics": False}
3064
3065
3066class WithJournalTableProperty(Property):
3067    arg_types = {"this": True}
3068
3069
3070class WithSchemaBindingProperty(Property):
3071    arg_types = {"this": True}
3072
3073
3074class WithSystemVersioningProperty(Property):
3075    arg_types = {
3076        "on": False,
3077        "this": False,
3078        "data_consistency": False,
3079        "retention_period": False,
3080        "with": True,
3081    }
3082
3083
3084class WithProcedureOptions(Property):
3085    arg_types = {"expressions": True}
3086
3087
3088class EncodeProperty(Property):
3089    arg_types = {"this": True, "properties": False, "key": False}
3090
3091
3092class IncludeProperty(Property):
3093    arg_types = {"this": True, "alias": False, "column_def": False}
3094
3095
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)
3160
3161
3162class Qualify(Expression):
3163    pass
3164
3165
3166class InputOutputFormat(Expression):
3167    arg_types = {"input_format": False, "output_format": False}
3168
3169
3170# https://www.ibm.com/docs/en/ias?topic=procedures-return-statement-in-sql
3171class Return(Expression):
3172    pass
3173
3174
3175class Reference(Expression):
3176    arg_types = {"this": True, "expressions": False, "options": False}
3177
3178
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        )
3205
3206
3207QUERY_MODIFIERS = {
3208    "match": False,
3209    "laterals": False,
3210    "joins": False,
3211    "connect": False,
3212    "pivots": False,
3213    "prewhere": False,
3214    "where": False,
3215    "group": False,
3216    "having": False,
3217    "qualify": False,
3218    "windows": False,
3219    "distribute": False,
3220    "sort": False,
3221    "cluster": False,
3222    "order": False,
3223    "limit": False,
3224    "offset": False,
3225    "locks": False,
3226    "sample": False,
3227    "settings": False,
3228    "format": False,
3229    "options": False,
3230}
3231
3232
3233# https://learn.microsoft.com/en-us/sql/t-sql/queries/option-clause-transact-sql?view=sql-server-ver16
3234# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-query?view=sql-server-ver16
3235class QueryOption(Expression):
3236    arg_types = {"this": True, "expression": False}
3237
3238
3239# https://learn.microsoft.com/en-us/sql/t-sql/queries/hints-transact-sql-table?view=sql-server-ver16
3240class WithTableHint(Expression):
3241    arg_types = {"expressions": True}
3242
3243
3244# https://dev.mysql.com/doc/refman/8.0/en/index-hints.html
3245class IndexTableHint(Expression):
3246    arg_types = {"this": True, "expressions": False, "target": False}
3247
3248
3249# https://docs.snowflake.com/en/sql-reference/constructs/at-before
3250class HistoricalData(Expression):
3251    arg_types = {"this": True, "kind": True, "expression": True}
3252
3253
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
3329
3330
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
3375
3376
3377class Union(SetOperation):
3378    pass
3379
3380
3381class Except(SetOperation):
3382    pass
3383
3384
3385class Intersect(SetOperation):
3386    pass
3387
3388
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        )
3594
3595
3596class Values(UDTF):
3597    arg_types = {"expressions": True, "alias": False}
3598
3599
3600class Var(Expression):
3601    pass
3602
3603
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}
3616
3617
3618class Schema(Expression):
3619    arg_types = {"this": False, "expressions": False}
3620
3621
3622# https://dev.mysql.com/doc/refman/8.0/en/select.html
3623# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html
3624class Lock(Expression):
3625    arg_types = {"update": True, "expressions": False, "wait": False}
3626
3627
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
4190
4191
4192UNWRAPPED_QUERIES = (Select, SetOperation)
4193
4194
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
4246
4247
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    }
4260
4261
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    }
4270
4271
4272# Represents both the standard SQL PIVOT operator and DuckDB's "simplified" PIVOT syntax
4273# https://duckdb.org/docs/sql/statements/pivot
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"))
4292
4293
4294# https://duckdb.org/docs/sql/statements/unpivot#simplified-unpivot-syntax
4295# UNPIVOT ... INTO [NAME <col_name> VALUE <col_value>][...,]
4296class UnpivotColumns(Expression):
4297    arg_types = {"this": True, "expressions": True}
4298
4299
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    }
4310
4311
4312class WindowSpec(Expression):
4313    arg_types = {
4314        "kind": False,
4315        "start": False,
4316        "start_side": False,
4317        "end": False,
4318        "end_side": False,
4319    }
4320
4321
4322class PreWhere(Expression):
4323    pass
4324
4325
4326class Where(Expression):
4327    pass
4328
4329
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
4340
4341
4342class Parameter(Condition):
4343    arg_types = {"this": True, "expression": False}
4344
4345
4346class SessionParameter(Condition):
4347    arg_types = {"this": True, "kind": False}
4348
4349
4350class Placeholder(Condition):
4351    arg_types = {"this": False, "kind": False}
4352
4353    @property
4354    def name(self) -> str:
4355        return self.this or "?"
4356
4357
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
4367
4368
4369class Boolean(Condition):
4370    def to_py(self) -> bool:
4371        return self.this
4372
4373
4374class DataTypeParam(Expression):
4375    arg_types = {"this": True, "expression": False}
4376
4377    @property
4378    def name(self) -> str:
4379        return self.this.name
4380
4381
4382# The `nullable` arg is helpful when transpiling types from other dialects to ClickHouse, which
4383# assumes non-nullable types by default. Values `None` and `True` mean the type is nullable.
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
4688
4689
4690DATA_TYPE = t.Union[str, DataType, DataType.Type]
4691
4692
4693# https://www.postgresql.org/docs/15/datatype-pseudo.html
4694class PseudoType(DataType):
4695    arg_types = {"this": True}
4696
4697
4698# https://www.postgresql.org/docs/15/datatype-oid.html
4699class ObjectIdentifier(DataType):
4700    arg_types = {"this": True}
4701
4702
4703# WHERE x <OP> EXISTS|ALL|ANY|SOME(SELECT ...)
4704class SubqueryPredicate(Predicate):
4705    pass
4706
4707
4708class All(SubqueryPredicate):
4709    pass
4710
4711
4712class Any(SubqueryPredicate):
4713    pass
4714
4715
4716# Commands to interact with the databases or engines. For most of the command
4717# expressions we parse whatever comes after the command's name as a string.
4718class Command(Expression):
4719    arg_types = {"this": True, "expression": False}
4720
4721
4722class Transaction(Expression):
4723    arg_types = {"this": False, "modes": False, "mark": False}
4724
4725
4726class Commit(Expression):
4727    arg_types = {"chain": False, "this": False, "durability": False}
4728
4729
4730class Rollback(Expression):
4731    arg_types = {"savepoint": False, "this": False}
4732
4733
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 []
4754
4755
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    }
4766
4767
4768class AnalyzeStatistics(Expression):
4769    arg_types = {
4770        "kind": True,
4771        "option": False,
4772        "this": False,
4773        "expressions": False,
4774    }
4775
4776
4777class AnalyzeHistogram(Expression):
4778    arg_types = {
4779        "this": True,
4780        "expressions": True,
4781        "expression": False,
4782        "update_options": False,
4783    }
4784
4785
4786class AnalyzeSample(Expression):
4787    arg_types = {"kind": True, "sample": True}
4788
4789
4790class AnalyzeListChainedRows(Expression):
4791    arg_types = {"expression": False}
4792
4793
4794class AnalyzeDelete(Expression):
4795    arg_types = {"kind": False}
4796
4797
4798class AnalyzeWith(Expression):
4799    arg_types = {"expressions": True}
4800
4801
4802class AnalyzeValidate(Expression):
4803    arg_types = {
4804        "kind": True,
4805        "this": False,
4806        "expression": False,
4807    }
4808
4809
4810class AnalyzeColumns(Expression):
4811    pass
4812
4813
4814class UsingData(Expression):
4815    pass
4816
4817
4818class AddConstraint(Expression):
4819    arg_types = {"expressions": True}
4820
4821
4822class AttachOption(Expression):
4823    arg_types = {"this": True, "expression": False}
4824
4825
4826class DropPartition(Expression):
4827    arg_types = {"expressions": True, "exists": False}
4828
4829
4830# https://clickhouse.com/docs/en/sql-reference/statements/alter/partition#replace-partition
4831class ReplacePartition(Expression):
4832    arg_types = {"expression": True, "source": True}
4833
4834
4835# Binary expressions like (ADD a b)
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
4846
4847
4848class Add(Binary):
4849    pass
4850
4851
4852class Connector(Binary):
4853    pass
4854
4855
4856class BitwiseAnd(Binary):
4857    pass
4858
4859
4860class BitwiseLeftShift(Binary):
4861    pass
4862
4863
4864class BitwiseOr(Binary):
4865    pass
4866
4867
4868class BitwiseRightShift(Binary):
4869    pass
4870
4871
4872class BitwiseXor(Binary):
4873    pass
4874
4875
4876class Div(Binary):
4877    arg_types = {"this": True, "expression": True, "typed": False, "safe": False}
4878
4879
4880class Overlaps(Binary):
4881    pass
4882
4883
4884class Dot(Binary):
4885    @property
4886    def is_star(self) -> bool:
4887        return self.expression.is_star
4888
4889    @property
4890    def name(self) -> str:
4891        return self.expression.name
4892
4893    @property
4894    def output_name(self) -> str:
4895        return self.name
4896
4897    @classmethod
4898    def build(self, expressions: t.Sequence[Expression]) -> Dot:
4899        """Build a Dot object with a sequence of expressions."""
4900        if len(expressions) < 2:
4901            raise ValueError("Dot requires >= 2 expressions.")
4902
4903        return t.cast(Dot, reduce(lambda x, y: Dot(this=x, expression=y), expressions))
4904
4905    @property
4906    def parts(self) -> t.List[Expression]:
4907        """Return the parts of a table / column in order catalog, db, table."""
4908        this, *parts = self.flatten()
4909
4910        parts.reverse()
4911
4912        for arg in COLUMN_PARTS:
4913            part = this.args.get(arg)
4914
4915            if isinstance(part, Expression):
4916                parts.append(part)
4917
4918        parts.reverse()
4919        return parts
4920
4921
4922class DPipe(Binary):
4923    arg_types = {"this": True, "expression": True, "safe": False}
4924
4925
4926class EQ(Binary, Predicate):
4927    pass
4928
4929
4930class NullSafeEQ(Binary, Predicate):
4931    pass
4932
4933
4934class NullSafeNEQ(Binary, Predicate):
4935    pass
4936
4937
4938# Represents e.g. := in DuckDB which is mostly used for setting parameters
4939class PropertyEQ(Binary):
4940    pass
4941
4942
4943class Distance(Binary):
4944    pass
4945
4946
4947class Escape(Binary):
4948    pass
4949
4950
4951class Glob(Binary, Predicate):
4952    pass
4953
4954
4955class GT(Binary, Predicate):
4956    pass
4957
4958
4959class GTE(Binary, Predicate):
4960    pass
4961
4962
4963class ILike(Binary, Predicate):
4964    pass
4965
4966
4967class ILikeAny(Binary, Predicate):
4968    pass
4969
4970
4971class IntDiv(Binary):
4972    pass
4973
4974
4975class Is(Binary, Predicate):
4976    pass
4977
4978
4979class Kwarg(Binary):
4980    """Kwarg in special functions like func(kwarg => y)."""
4981
4982
4983class Like(Binary, Predicate):
4984    pass
4985
4986
4987class LikeAny(Binary, Predicate):
4988    pass
4989
4990
4991class LT(Binary, Predicate):
4992    pass
4993
4994
4995class LTE(Binary, Predicate):
4996    pass
4997
4998
4999class Mod(Binary):
5000    pass
5001
5002
5003class Mul(Binary):
5004    pass
5005
5006
5007class NEQ(Binary, Predicate):
5008    pass
5009
5010
5011# https://www.postgresql.org/docs/current/ddl-schemas.html#DDL-SCHEMAS-PATH
5012class Operator(Binary):
5013    arg_types = {"this": True, "operator": True, "expression": True}
5014
5015
5016class SimilarTo(Binary, Predicate):
5017    pass
5018
5019
5020class Slice(Binary):
5021    arg_types = {"this": False, "expression": False}
5022
5023
5024class Sub(Binary):
5025    pass
5026
5027
5028# Unary Expressions
5029# (NOT a)
5030class Unary(Condition):
5031    pass
5032
5033
5034class BitwiseNot(Unary):
5035    pass
5036
5037
5038class Not(Unary):
5039    pass
5040
5041
5042class Paren(Unary):
5043    @property
5044    def output_name(self) -> str:
5045        return self.this.name
5046
5047
5048class Neg(Unary):
5049    def to_py(self) -> int | Decimal:
5050        if self.is_number:
5051            return self.this.to_py() * -1
5052        return super().to_py()
5053
5054
5055class Alias(Expression):
5056    arg_types = {"this": True, "alias": False}
5057
5058    @property
5059    def output_name(self) -> str:
5060        return self.alias
5061
5062
5063# BigQuery requires the UNPIVOT column list aliases to be either strings or ints, but
5064# other dialects require identifiers. This enables us to transpile between them easily.
5065class PivotAlias(Alias):
5066    pass
5067
5068
5069# Represents Snowflake's ANY [ ORDER BY ... ] syntax
5070# https://docs.snowflake.com/en/sql-reference/constructs/pivot
5071class PivotAny(Expression):
5072    arg_types = {"this": False}
5073
5074
5075class Aliases(Expression):
5076    arg_types = {"this": True, "expressions": True}
5077
5078    @property
5079    def aliases(self):
5080        return self.expressions
5081
5082
5083# https://docs.aws.amazon.com/redshift/latest/dg/query-super.html
5084class AtIndex(Expression):
5085    arg_types = {"this": True, "expression": True}
5086
5087
5088class AtTimeZone(Expression):
5089    arg_types = {"this": True, "zone": True}
5090
5091
5092class FromTimeZone(Expression):
5093    arg_types = {"this": True, "zone": True}
5094
5095
5096class Between(Predicate):
5097    arg_types = {"this": True, "low": True, "high": True}
5098
5099
5100class Bracket(Condition):
5101    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5102    arg_types = {
5103        "this": True,
5104        "expressions": True,
5105        "offset": False,
5106        "safe": False,
5107        "returns_list_for_maps": False,
5108    }
5109
5110    @property
5111    def output_name(self) -> str:
5112        if len(self.expressions) == 1:
5113            return self.expressions[0].output_name
5114
5115        return super().output_name
5116
5117
5118class Distinct(Expression):
5119    arg_types = {"expressions": False, "on": False}
5120
5121
5122class In(Predicate):
5123    arg_types = {
5124        "this": True,
5125        "expressions": False,
5126        "query": False,
5127        "unnest": False,
5128        "field": False,
5129        "is_global": False,
5130    }
5131
5132
5133# https://cloud.google.com/bigquery/docs/reference/standard-sql/procedural-language#for-in
5134class ForIn(Expression):
5135    arg_types = {"this": True, "expression": True}
5136
5137
5138class TimeUnit(Expression):
5139    """Automatically converts unit arg into a var."""
5140
5141    arg_types = {"unit": False}
5142
5143    UNABBREVIATED_UNIT_NAME = {
5144        "D": "DAY",
5145        "H": "HOUR",
5146        "M": "MINUTE",
5147        "MS": "MILLISECOND",
5148        "NS": "NANOSECOND",
5149        "Q": "QUARTER",
5150        "S": "SECOND",
5151        "US": "MICROSECOND",
5152        "W": "WEEK",
5153        "Y": "YEAR",
5154    }
5155
5156    VAR_LIKE = (Column, Literal, Var)
5157
5158    def __init__(self, **args):
5159        unit = args.get("unit")
5160        if isinstance(unit, self.VAR_LIKE):
5161            args["unit"] = Var(
5162                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5163            )
5164        elif isinstance(unit, Week):
5165            unit.set("this", Var(this=unit.this.name.upper()))
5166
5167        super().__init__(**args)
5168
5169    @property
5170    def unit(self) -> t.Optional[Var | IntervalSpan]:
5171        return self.args.get("unit")
5172
5173
5174class IntervalOp(TimeUnit):
5175    arg_types = {"unit": False, "expression": True}
5176
5177    def interval(self):
5178        return Interval(
5179            this=self.expression.copy(),
5180            unit=self.unit.copy() if self.unit else None,
5181        )
5182
5183
5184# https://www.oracletutorial.com/oracle-basics/oracle-interval/
5185# https://trino.io/docs/current/language/types.html#interval-day-to-second
5186# https://docs.databricks.com/en/sql/language-manual/data-types/interval-type.html
5187class IntervalSpan(DataType):
5188    arg_types = {"this": True, "expression": True}
5189
5190
5191class Interval(TimeUnit):
5192    arg_types = {"this": False, "unit": False}
5193
5194
5195class IgnoreNulls(Expression):
5196    pass
5197
5198
5199class RespectNulls(Expression):
5200    pass
5201
5202
5203# https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate-function-calls#max_min_clause
5204class HavingMax(Expression):
5205    arg_types = {"this": True, "expression": True, "max": True}
5206
5207
5208# Functions
5209class Func(Condition):
5210    """
5211    The base class for all function expressions.
5212
5213    Attributes:
5214        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5215            treated as a variable length argument and the argument's value will be stored as a list.
5216        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5217            function expression. These values are used to map this node to a name during parsing as
5218            well as to provide the function's name during SQL string generation. By default the SQL
5219            name is set to the expression's class name transformed to snake case.
5220    """
5221
5222    is_var_len_args = False
5223
5224    @classmethod
5225    def from_arg_list(cls, args):
5226        if cls.is_var_len_args:
5227            all_arg_keys = list(cls.arg_types)
5228            # If this function supports variable length argument treat the last argument as such.
5229            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5230            num_non_var = len(non_var_len_arg_keys)
5231
5232            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5233            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5234        else:
5235            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5236
5237        return cls(**args_dict)
5238
5239    @classmethod
5240    def sql_names(cls):
5241        if cls is Func:
5242            raise NotImplementedError(
5243                "SQL name is only supported by concrete function implementations"
5244            )
5245        if "_sql_names" not in cls.__dict__:
5246            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5247        return cls._sql_names
5248
5249    @classmethod
5250    def sql_name(cls):
5251        return cls.sql_names()[0]
5252
5253    @classmethod
5254    def default_parser_mappings(cls):
5255        return {name: cls.from_arg_list for name in cls.sql_names()}
5256
5257
5258class AggFunc(Func):
5259    pass
5260
5261
5262class ParameterizedAgg(AggFunc):
5263    arg_types = {"this": True, "expressions": True, "params": True}
5264
5265
5266class Abs(Func):
5267    pass
5268
5269
5270class ArgMax(AggFunc):
5271    arg_types = {"this": True, "expression": True, "count": False}
5272    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
5273
5274
5275class ArgMin(AggFunc):
5276    arg_types = {"this": True, "expression": True, "count": False}
5277    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
5278
5279
5280class ApproxTopK(AggFunc):
5281    arg_types = {"this": True, "expression": False, "counters": False}
5282
5283
5284class Flatten(Func):
5285    pass
5286
5287
5288# https://spark.apache.org/docs/latest/api/sql/index.html#transform
5289class Transform(Func):
5290    arg_types = {"this": True, "expression": True}
5291
5292
5293class Anonymous(Func):
5294    arg_types = {"this": True, "expressions": False}
5295    is_var_len_args = True
5296
5297    @property
5298    def name(self) -> str:
5299        return self.this if isinstance(self.this, str) else self.this.name
5300
5301
5302class AnonymousAggFunc(AggFunc):
5303    arg_types = {"this": True, "expressions": False}
5304    is_var_len_args = True
5305
5306
5307# https://clickhouse.com/docs/en/sql-reference/aggregate-functions/combinators
5308class CombinedAggFunc(AnonymousAggFunc):
5309    arg_types = {"this": True, "expressions": False}
5310
5311
5312class CombinedParameterizedAgg(ParameterizedAgg):
5313    arg_types = {"this": True, "expressions": True, "params": True}
5314
5315
5316# https://docs.snowflake.com/en/sql-reference/functions/hll
5317# https://docs.aws.amazon.com/redshift/latest/dg/r_HLL_function.html
5318class Hll(AggFunc):
5319    arg_types = {"this": True, "expressions": False}
5320    is_var_len_args = True
5321
5322
5323class ApproxDistinct(AggFunc):
5324    arg_types = {"this": True, "accuracy": False}
5325    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
5326
5327
5328class Apply(Func):
5329    arg_types = {"this": True, "expression": True}
5330
5331
5332class Array(Func):
5333    arg_types = {"expressions": False, "bracket_notation": False}
5334    is_var_len_args = True
5335
5336
5337# https://docs.snowflake.com/en/sql-reference/functions/to_array
5338class ToArray(Func):
5339    pass
5340
5341
5342# https://materialize.com/docs/sql/types/list/
5343class List(Func):
5344    arg_types = {"expressions": False}
5345    is_var_len_args = True
5346
5347
5348# String pad, kind True -> LPAD, False -> RPAD
5349class Pad(Func):
5350    arg_types = {"this": True, "expression": True, "fill_pattern": False, "is_left": True}
5351
5352
5353# https://docs.snowflake.com/en/sql-reference/functions/to_char
5354# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_CHAR-number.html
5355class ToChar(Func):
5356    arg_types = {"this": True, "format": False, "nlsparam": False}
5357
5358
5359# https://docs.snowflake.com/en/sql-reference/functions/to_decimal
5360# https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/TO_NUMBER.html
5361class ToNumber(Func):
5362    arg_types = {
5363        "this": True,
5364        "format": False,
5365        "nlsparam": False,
5366        "precision": False,
5367        "scale": False,
5368    }
5369
5370
5371# https://docs.snowflake.com/en/sql-reference/functions/to_double
5372class ToDouble(Func):
5373    arg_types = {
5374        "this": True,
5375        "format": False,
5376    }
5377
5378
5379class Columns(Func):
5380    arg_types = {"this": True, "unpack": False}
5381
5382
5383# https://learn.microsoft.com/en-us/sql/t-sql/functions/cast-and-convert-transact-sql?view=sql-server-ver16#syntax
5384class Convert(Func):
5385    arg_types = {"this": True, "expression": True, "style": False}
5386
5387
5388class ConvertTimezone(Func):
5389    arg_types = {"source_tz": False, "target_tz": True, "timestamp": True}
5390
5391
5392class GenerateSeries(Func):
5393    arg_types = {"start": True, "end": True, "step": False, "is_end_exclusive": False}
5394
5395
5396# Postgres' GENERATE_SERIES function returns a row set, i.e. it implicitly explodes when it's
5397# used in a projection, so this expression is a helper that facilitates transpilation to other
5398# dialects. For example, we'd generate UNNEST(GENERATE_SERIES(...)) in DuckDB
5399class ExplodingGenerateSeries(GenerateSeries):
5400    pass
5401
5402
5403class ArrayAgg(AggFunc):
5404    arg_types = {"this": True, "nulls_excluded": False}
5405
5406
5407class ArrayUniqueAgg(AggFunc):
5408    pass
5409
5410
5411class ArrayAll(Func):
5412    arg_types = {"this": True, "expression": True}
5413
5414
5415# Represents Python's `any(f(x) for x in array)`, where `array` is `this` and `f` is `expression`
5416class ArrayAny(Func):
5417    arg_types = {"this": True, "expression": True}
5418
5419
5420class ArrayConcat(Func):
5421    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5422    arg_types = {"this": True, "expressions": False}
5423    is_var_len_args = True
5424
5425
5426class ArrayConstructCompact(Func):
5427    arg_types = {"expressions": True}
5428    is_var_len_args = True
5429
5430
5431class ArrayContains(Binary, Func):
5432    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
5433
5434
5435class ArrayContainsAll(Binary, Func):
5436    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
5437
5438
5439class ArrayFilter(Func):
5440    arg_types = {"this": True, "expression": True}
5441    _sql_names = ["FILTER", "ARRAY_FILTER"]
5442
5443
5444class ArrayToString(Func):
5445    arg_types = {"this": True, "expression": True, "null": False}
5446    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
5447
5448
5449# https://cloud.google.com/bigquery/docs/reference/standard-sql/timestamp_functions#string
5450class String(Func):
5451    arg_types = {"this": True, "zone": False}
5452
5453
5454class StringToArray(Func):
5455    arg_types = {"this": True, "expression": True, "null": False}
5456    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
5457
5458
5459class ArrayOverlaps(Binary, Func):
5460    pass
5461
5462
5463class ArraySize(Func):
5464    arg_types = {"this": True, "expression": False}
5465    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
5466
5467
5468class ArraySort(Func):
5469    arg_types = {"this": True, "expression": False}
5470
5471
5472class ArraySum(Func):
5473    arg_types = {"this": True, "expression": False}
5474
5475
5476class ArrayUnionAgg(AggFunc):
5477    pass
5478
5479
5480class Avg(AggFunc):
5481    pass
5482
5483
5484class AnyValue(AggFunc):
5485    pass
5486
5487
5488class Lag(AggFunc):
5489    arg_types = {"this": True, "offset": False, "default": False}
5490
5491
5492class Lead(AggFunc):
5493    arg_types = {"this": True, "offset": False, "default": False}
5494
5495
5496# some dialects have a distinction between first and first_value, usually first is an aggregate func
5497# and first_value is a window func
5498class First(AggFunc):
5499    pass
5500
5501
5502class Last(AggFunc):
5503    pass
5504
5505
5506class FirstValue(AggFunc):
5507    pass
5508
5509
5510class LastValue(AggFunc):
5511    pass
5512
5513
5514class NthValue(AggFunc):
5515    arg_types = {"this": True, "offset": True}
5516
5517
5518class Case(Func):
5519    arg_types = {"this": False, "ifs": True, "default": False}
5520
5521    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5522        instance = maybe_copy(self, copy)
5523        instance.append(
5524            "ifs",
5525            If(
5526                this=maybe_parse(condition, copy=copy, **opts),
5527                true=maybe_parse(then, copy=copy, **opts),
5528            ),
5529        )
5530        return instance
5531
5532    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5533        instance = maybe_copy(self, copy)
5534        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5535        return instance
5536
5537
5538class Cast(Func):
5539    arg_types = {
5540        "this": True,
5541        "to": True,
5542        "format": False,
5543        "safe": False,
5544        "action": False,
5545        "default": False,
5546    }
5547
5548    @property
5549    def name(self) -> str:
5550        return self.this.name
5551
5552    @property
5553    def to(self) -> DataType:
5554        return self.args["to"]
5555
5556    @property
5557    def output_name(self) -> str:
5558        return self.name
5559
5560    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5561        """
5562        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5563        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5564        array<int> != array<float>.
5565
5566        Args:
5567            dtypes: the data types to compare this Cast's DataType to.
5568
5569        Returns:
5570            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5571        """
5572        return self.to.is_type(*dtypes)
5573
5574
5575class TryCast(Cast):
5576    pass
5577
5578
5579# https://clickhouse.com/docs/sql-reference/data-types/newjson#reading-json-paths-as-sub-columns
5580class JSONCast(Cast):
5581    pass
5582
5583
5584class Try(Func):
5585    pass
5586
5587
5588class CastToStrType(Func):
5589    arg_types = {"this": True, "to": True}
5590
5591
5592class Collate(Binary, Func):
5593    pass
5594
5595
5596class Ceil(Func):
5597    arg_types = {"this": True, "decimals": False, "to": False}
5598    _sql_names = ["CEIL", "CEILING"]
5599
5600
5601class Coalesce(Func):
5602    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5603    is_var_len_args = True
5604    _sql_names = ["COALESCE", "IFNULL", "NVL"]
5605
5606
5607class Chr(Func):
5608    arg_types = {"expressions": True, "charset": False}
5609    is_var_len_args = True
5610    _sql_names = ["CHR", "CHAR"]
5611
5612
5613class Concat(Func):
5614    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5615    is_var_len_args = True
5616
5617
5618class ConcatWs(Concat):
5619    _sql_names = ["CONCAT_WS"]
5620
5621
5622class Contains(Func):
5623    arg_types = {"this": True, "expression": True}
5624
5625
5626# https://docs.oracle.com/cd/B13789_01/server.101/b10759/operators004.htm#i1035022
5627class ConnectByRoot(Func):
5628    pass
5629
5630
5631class Count(AggFunc):
5632    arg_types = {"this": False, "expressions": False, "big_int": False}
5633    is_var_len_args = True
5634
5635
5636class CountIf(AggFunc):
5637    _sql_names = ["COUNT_IF", "COUNTIF"]
5638
5639
5640# cube root
5641class Cbrt(Func):
5642    pass
5643
5644
5645class CurrentDate(Func):
5646    arg_types = {"this": False}
5647
5648
5649class CurrentDatetime(Func):
5650    arg_types = {"this": False}
5651
5652
5653class CurrentTime(Func):
5654    arg_types = {"this": False}
5655
5656
5657class CurrentTimestamp(Func):
5658    arg_types = {"this": False, "sysdate": False}
5659
5660
5661class CurrentSchema(Func):
5662    arg_types = {"this": False}
5663
5664
5665class CurrentUser(Func):
5666    arg_types = {"this": False}
5667
5668
5669class DateAdd(Func, IntervalOp):
5670    arg_types = {"this": True, "expression": True, "unit": False}
5671
5672
5673class DateBin(Func, IntervalOp):
5674    arg_types = {"this": True, "expression": True, "unit": False, "zone": False}
5675
5676
5677class DateSub(Func, IntervalOp):
5678    arg_types = {"this": True, "expression": True, "unit": False}
5679
5680
5681class DateDiff(Func, TimeUnit):
5682    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5683    arg_types = {"this": True, "expression": True, "unit": False}
5684
5685
5686class DateTrunc(Func):
5687    arg_types = {"unit": True, "this": True, "zone": False}
5688
5689    def __init__(self, **args):
5690        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5691        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5692        unabbreviate = args.pop("unabbreviate", True)
5693
5694        unit = args.get("unit")
5695        if isinstance(unit, TimeUnit.VAR_LIKE):
5696            unit_name = unit.name.upper()
5697            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5698                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5699
5700            args["unit"] = Literal.string(unit_name)
5701        elif isinstance(unit, Week):
5702            unit.set("this", Literal.string(unit.this.name.upper()))
5703
5704        super().__init__(**args)
5705
5706    @property
5707    def unit(self) -> Expression:
5708        return self.args["unit"]
5709
5710
5711# https://cloud.google.com/bigquery/docs/reference/standard-sql/datetime_functions#datetime
5712# expression can either be time_expr or time_zone
5713class Datetime(Func):
5714    arg_types = {"this": True, "expression": False}
5715
5716
5717class DatetimeAdd(Func, IntervalOp):
5718    arg_types = {"this": True, "expression": True, "unit": False}
5719
5720
5721class DatetimeSub(Func, IntervalOp):
5722    arg_types = {"this": True, "expression": True, "unit": False}
5723
5724
5725class DatetimeDiff(Func, TimeUnit):
5726    arg_types = {"this": True, "expression": True, "unit": False}
5727
5728
5729class DatetimeTrunc(Func, TimeUnit):
5730    arg_types = {"this": True, "unit": True, "zone": False}
5731
5732
5733class DayOfWeek(Func):
5734    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
5735
5736
5737# https://duckdb.org/docs/sql/functions/datepart.html#part-specifiers-only-usable-as-date-part-specifiers
5738# ISO day of week function in duckdb is ISODOW
5739class DayOfWeekIso(Func):
5740    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
5741
5742
5743class DayOfMonth(Func):
5744    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
5745
5746
5747class DayOfYear(Func):
5748    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
5749
5750
5751class ToDays(Func):
5752    pass
5753
5754
5755class WeekOfYear(Func):
5756    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
5757
5758
5759class MonthsBetween(Func):
5760    arg_types = {"this": True, "expression": True, "roundoff": False}
5761
5762
5763class MakeInterval(Func):
5764    arg_types = {
5765        "year": False,
5766        "month": False,
5767        "day": False,
5768        "hour": False,
5769        "minute": False,
5770        "second": False,
5771    }
5772
5773
5774class LastDay(Func, TimeUnit):
5775    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5776    arg_types = {"this": True, "unit": False}
5777
5778
5779class Extract(Func):
5780    arg_types = {"this": True, "expression": True}
5781
5782
5783class Exists(Func, SubqueryPredicate):
5784    arg_types = {"this": True, "expression": False}
5785
5786
5787class Timestamp(Func):
5788    arg_types = {"this": False, "zone": False, "with_tz": False}
5789
5790
5791class TimestampAdd(Func, TimeUnit):
5792    arg_types = {"this": True, "expression": True, "unit": False}
5793
5794
5795class TimestampSub(Func, TimeUnit):
5796    arg_types = {"this": True, "expression": True, "unit": False}
5797
5798
5799class TimestampDiff(Func, TimeUnit):
5800    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5801    arg_types = {"this": True, "expression": True, "unit": False}
5802
5803
5804class TimestampTrunc(Func, TimeUnit):
5805    arg_types = {"this": True, "unit": True, "zone": False}
5806
5807
5808class TimeAdd(Func, TimeUnit):
5809    arg_types = {"this": True, "expression": True, "unit": False}
5810
5811
5812class TimeSub(Func, TimeUnit):
5813    arg_types = {"this": True, "expression": True, "unit": False}
5814
5815
5816class TimeDiff(Func, TimeUnit):
5817    arg_types = {"this": True, "expression": True, "unit": False}
5818
5819
5820class TimeTrunc(Func, TimeUnit):
5821    arg_types = {"this": True, "unit": True, "zone": False}
5822
5823
5824class DateFromParts(Func):
5825    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5826    arg_types = {"year": True, "month": True, "day": True}
5827
5828
5829class TimeFromParts(Func):
5830    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5831    arg_types = {
5832        "hour": True,
5833        "min": True,
5834        "sec": True,
5835        "nano": False,
5836        "fractions": False,
5837        "precision": False,
5838    }
5839
5840
5841class DateStrToDate(Func):
5842    pass
5843
5844
5845class DateToDateStr(Func):
5846    pass
5847
5848
5849class DateToDi(Func):
5850    pass
5851
5852
5853# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#date
5854class Date(Func):
5855    arg_types = {"this": False, "zone": False, "expressions": False}
5856    is_var_len_args = True
5857
5858
5859class Day(Func):
5860    pass
5861
5862
5863class Decode(Func):
5864    arg_types = {"this": True, "charset": True, "replace": False}
5865
5866
5867class DiToDate(Func):
5868    pass
5869
5870
5871class Encode(Func):
5872    arg_types = {"this": True, "charset": True}
5873
5874
5875class Exp(Func):
5876    pass
5877
5878
5879# https://docs.snowflake.com/en/sql-reference/functions/flatten
5880class Explode(Func, UDTF):
5881    arg_types = {"this": True, "expressions": False}
5882    is_var_len_args = True
5883
5884
5885# https://spark.apache.org/docs/latest/api/sql/#inline
5886class Inline(Func):
5887    pass
5888
5889
5890class ExplodeOuter(Explode):
5891    pass
5892
5893
5894class Posexplode(Explode):
5895    pass
5896
5897
5898class PosexplodeOuter(Posexplode, ExplodeOuter):
5899    pass
5900
5901
5902class Unnest(Func, UDTF):
5903    arg_types = {
5904        "expressions": True,
5905        "alias": False,
5906        "offset": False,
5907        "explode_array": False,
5908    }
5909
5910    @property
5911    def selects(self) -> t.List[Expression]:
5912        columns = super().selects
5913        offset = self.args.get("offset")
5914        if offset:
5915            columns = columns + [to_identifier("offset") if offset is True else offset]
5916        return columns
5917
5918
5919class Floor(Func):
5920    arg_types = {"this": True, "decimals": False, "to": False}
5921
5922
5923class FromBase64(Func):
5924    pass
5925
5926
5927class FeaturesAtTime(Func):
5928    arg_types = {"this": True, "time": False, "num_rows": False, "ignore_feature_nulls": False}
5929
5930
5931class ToBase64(Func):
5932    pass
5933
5934
5935# https://trino.io/docs/current/functions/datetime.html#from_iso8601_timestamp
5936class FromISO8601Timestamp(Func):
5937    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
5938
5939
5940class GapFill(Func):
5941    arg_types = {
5942        "this": True,
5943        "ts_column": True,
5944        "bucket_width": True,
5945        "partitioning_columns": False,
5946        "value_columns": False,
5947        "origin": False,
5948        "ignore_nulls": False,
5949    }
5950
5951
5952# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_date_array
5953class GenerateDateArray(Func):
5954    arg_types = {"start": True, "end": True, "step": False}
5955
5956
5957# https://cloud.google.com/bigquery/docs/reference/standard-sql/array_functions#generate_timestamp_array
5958class GenerateTimestampArray(Func):
5959    arg_types = {"start": True, "end": True, "step": True}
5960
5961
5962class Greatest(Func):
5963    arg_types = {"this": True, "expressions": False}
5964    is_var_len_args = True
5965
5966
5967# Trino's `ON OVERFLOW TRUNCATE [filler_string] {WITH | WITHOUT} COUNT`
5968# https://trino.io/docs/current/functions/aggregate.html#listagg
5969class OverflowTruncateBehavior(Expression):
5970    arg_types = {"this": False, "with_count": True}
5971
5972
5973class GroupConcat(AggFunc):
5974    arg_types = {"this": True, "separator": False, "on_overflow": False}
5975
5976
5977class Hex(Func):
5978    pass
5979
5980
5981class LowerHex(Hex):
5982    pass
5983
5984
5985class And(Connector, Func):
5986    pass
5987
5988
5989class Or(Connector, Func):
5990    pass
5991
5992
5993class Xor(Connector, Func):
5994    arg_types = {"this": False, "expression": False, "expressions": False}
5995
5996
5997class If(Func):
5998    arg_types = {"this": True, "true": True, "false": False}
5999    _sql_names = ["IF", "IIF"]
6000
6001
6002class Nullif(Func):
6003    arg_types = {"this": True, "expression": True}
6004
6005
6006class Initcap(Func):
6007    arg_types = {"this": True, "expression": False}
6008
6009
6010class IsAscii(Func):
6011    pass
6012
6013
6014class IsNan(Func):
6015    _sql_names = ["IS_NAN", "ISNAN"]
6016
6017
6018# https://cloud.google.com/bigquery/docs/reference/standard-sql/json_functions#int64_for_json
6019class Int64(Func):
6020    pass
6021
6022
6023class IsInf(Func):
6024    _sql_names = ["IS_INF", "ISINF"]
6025
6026
6027# https://www.postgresql.org/docs/current/functions-json.html
6028class JSON(Expression):
6029    arg_types = {"this": False, "with": False, "unique": False}
6030
6031
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 ""
6039
6040
6041class JSONPathPart(Expression):
6042    arg_types = {}
6043
6044
6045class JSONPathFilter(JSONPathPart):
6046    arg_types = {"this": True}
6047
6048
6049class JSONPathKey(JSONPathPart):
6050    arg_types = {"this": True}
6051
6052
6053class JSONPathRecursive(JSONPathPart):
6054    arg_types = {"this": False}
6055
6056
6057class JSONPathRoot(JSONPathPart):
6058    pass
6059
6060
6061class JSONPathScript(JSONPathPart):
6062    arg_types = {"this": True}
6063
6064
6065class JSONPathSlice(JSONPathPart):
6066    arg_types = {"start": False, "end": False, "step": False}
6067
6068
6069class JSONPathSelector(JSONPathPart):
6070    arg_types = {"this": True}
6071
6072
6073class JSONPathSubscript(JSONPathPart):
6074    arg_types = {"this": True}
6075
6076
6077class JSONPathUnion(JSONPathPart):
6078    arg_types = {"expressions": True}
6079
6080
6081class JSONPathWildcard(JSONPathPart):
6082    pass
6083
6084
6085class FormatJson(Expression):
6086    pass
6087
6088
6089class JSONKeyValue(Expression):
6090    arg_types = {"this": True, "expression": True}
6091
6092
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    }
6101
6102
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    }
6111
6112
6113# https://www.postgresql.org/docs/9.5/functions-aggregate.html
6114class JSONBObjectAgg(AggFunc):
6115    arg_types = {"this": True, "expression": True}
6116
6117
6118# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAY.html
6119class JSONArray(Func):
6120    arg_types = {
6121        "expressions": True,
6122        "null_handling": False,
6123        "return_type": False,
6124        "strict": False,
6125    }
6126
6127
6128# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_ARRAYAGG.html
6129class JSONArrayAgg(Func):
6130    arg_types = {
6131        "this": True,
6132        "order": False,
6133        "null_handling": False,
6134        "return_type": False,
6135        "strict": False,
6136    }
6137
6138
6139class JSONExists(Func):
6140    arg_types = {"this": True, "path": True, "passing": False, "on_condition": False}
6141
6142
6143# https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6144# Note: parsing of JSON column definitions is currently incomplete.
6145class JSONColumnDef(Expression):
6146    arg_types = {"this": False, "kind": False, "path": False, "nested_schema": False}
6147
6148
6149class JSONSchema(Expression):
6150    arg_types = {"expressions": True}
6151
6152
6153# https://dev.mysql.com/doc/refman/8.4/en/json-search-functions.html#function_json-value
6154class JSONValue(Expression):
6155    arg_types = {
6156        "this": True,
6157        "path": True,
6158        "returning": False,
6159        "on_condition": False,
6160    }
6161
6162
6163class JSONValueArray(Func):
6164    arg_types = {"this": True, "expression": False}
6165
6166
6167# # https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/JSON_TABLE.html
6168class JSONTable(Func):
6169    arg_types = {
6170        "this": True,
6171        "schema": True,
6172        "path": False,
6173        "error_handling": False,
6174        "empty_handling": False,
6175    }
6176
6177
6178# https://docs.snowflake.com/en/sql-reference/functions/object_insert
6179class ObjectInsert(Func):
6180    arg_types = {
6181        "this": True,
6182        "key": True,
6183        "value": True,
6184        "update_flag": False,
6185    }
6186
6187
6188class OpenJSONColumnDef(Expression):
6189    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
6190
6191
6192class OpenJSON(Func):
6193    arg_types = {"this": True, "path": False, "expressions": False}
6194
6195
6196class JSONBContains(Binary, Func):
6197    _sql_names = ["JSONB_CONTAINS"]
6198
6199
6200class JSONBExists(Func):
6201    arg_types = {"this": True, "path": True}
6202    _sql_names = ["JSONB_EXISTS"]
6203
6204
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        "on_condition": False,
6216    }
6217    _sql_names = ["JSON_EXTRACT"]
6218    is_var_len_args = True
6219
6220    @property
6221    def output_name(self) -> str:
6222        return self.expression.output_name if not self.expressions else ""
6223
6224
6225# https://trino.io/docs/current/functions/json.html#json-query
6226class JSONExtractQuote(Expression):
6227    arg_types = {
6228        "option": True,
6229        "scalar": False,
6230    }
6231
6232
6233class JSONExtractArray(Func):
6234    arg_types = {"this": True, "expression": False}
6235    _sql_names = ["JSON_EXTRACT_ARRAY"]
6236
6237
6238class JSONExtractScalar(Binary, Func):
6239    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6240    _sql_names = ["JSON_EXTRACT_SCALAR"]
6241    is_var_len_args = True
6242
6243    @property
6244    def output_name(self) -> str:
6245        return self.expression.output_name
6246
6247
6248class JSONBExtract(Binary, Func):
6249    _sql_names = ["JSONB_EXTRACT"]
6250
6251
6252class JSONBExtractScalar(Binary, Func):
6253    _sql_names = ["JSONB_EXTRACT_SCALAR"]
6254
6255
6256class JSONFormat(Func):
6257    arg_types = {"this": False, "options": False}
6258    _sql_names = ["JSON_FORMAT"]
6259
6260
6261# https://dev.mysql.com/doc/refman/8.0/en/json-search-functions.html#operator_member-of
6262class JSONArrayContains(Binary, Predicate, Func):
6263    _sql_names = ["JSON_ARRAY_CONTAINS"]
6264
6265
6266class ParseJSON(Func):
6267    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6268    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6269    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6270    arg_types = {"this": True, "expression": False, "safe": False}
6271
6272
6273class Least(Func):
6274    arg_types = {"this": True, "expressions": False}
6275    is_var_len_args = True
6276
6277
6278class Left(Func):
6279    arg_types = {"this": True, "expression": True}
6280
6281
6282class Right(Func):
6283    arg_types = {"this": True, "expression": True}
6284
6285
6286class Length(Func):
6287    arg_types = {"this": True, "binary": False, "encoding": False}
6288    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
6289
6290
6291class Levenshtein(Func):
6292    arg_types = {
6293        "this": True,
6294        "expression": False,
6295        "ins_cost": False,
6296        "del_cost": False,
6297        "sub_cost": False,
6298        "max_dist": False,
6299    }
6300
6301
6302class Ln(Func):
6303    pass
6304
6305
6306class Log(Func):
6307    arg_types = {"this": True, "expression": False}
6308
6309
6310class LogicalOr(AggFunc):
6311    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
6312
6313
6314class LogicalAnd(AggFunc):
6315    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
6316
6317
6318class Lower(Func):
6319    _sql_names = ["LOWER", "LCASE"]
6320
6321
6322class Map(Func):
6323    arg_types = {"keys": False, "values": False}
6324
6325    @property
6326    def keys(self) -> t.List[Expression]:
6327        keys = self.args.get("keys")
6328        return keys.expressions if keys else []
6329
6330    @property
6331    def values(self) -> t.List[Expression]:
6332        values = self.args.get("values")
6333        return values.expressions if values else []
6334
6335
6336# Represents the MAP {...} syntax in DuckDB - basically convert a struct to a MAP
6337class ToMap(Func):
6338    pass
6339
6340
6341class MapFromEntries(Func):
6342    pass
6343
6344
6345# https://learn.microsoft.com/en-us/sql/t-sql/language-elements/scope-resolution-operator-transact-sql?view=sql-server-ver16
6346class ScopeResolution(Expression):
6347    arg_types = {"this": False, "expression": True}
6348
6349
6350class Stream(Expression):
6351    pass
6352
6353
6354class StarMap(Func):
6355    pass
6356
6357
6358class VarMap(Func):
6359    arg_types = {"keys": True, "values": True}
6360    is_var_len_args = True
6361
6362    @property
6363    def keys(self) -> t.List[Expression]:
6364        return self.args["keys"].expressions
6365
6366    @property
6367    def values(self) -> t.List[Expression]:
6368        return self.args["values"].expressions
6369
6370
6371# https://dev.mysql.com/doc/refman/8.0/en/fulltext-search.html
6372class MatchAgainst(Func):
6373    arg_types = {"this": True, "expressions": True, "modifier": False}
6374
6375
6376class Max(AggFunc):
6377    arg_types = {"this": True, "expressions": False}
6378    is_var_len_args = True
6379
6380
6381class MD5(Func):
6382    _sql_names = ["MD5"]
6383
6384
6385# Represents the variant of the MD5 function that returns a binary value
6386class MD5Digest(Func):
6387    _sql_names = ["MD5_DIGEST"]
6388
6389
6390class Median(AggFunc):
6391    pass
6392
6393
6394class Min(AggFunc):
6395    arg_types = {"this": True, "expressions": False}
6396    is_var_len_args = True
6397
6398
6399class Month(Func):
6400    pass
6401
6402
6403class AddMonths(Func):
6404    arg_types = {"this": True, "expression": True}
6405
6406
6407class Nvl2(Func):
6408    arg_types = {"this": True, "true": True, "false": False}
6409
6410
6411class Normalize(Func):
6412    arg_types = {"this": True, "form": False}
6413
6414
6415class Overlay(Func):
6416    arg_types = {"this": True, "expression": True, "from": True, "for": False}
6417
6418
6419# https://cloud.google.com/bigquery/docs/reference/standard-sql/bigqueryml-syntax-predict#mlpredict_function
6420class Predict(Func):
6421    arg_types = {"this": True, "expression": True, "params_struct": False}
6422
6423
6424class Pow(Binary, Func):
6425    _sql_names = ["POWER", "POW"]
6426
6427
6428class PercentileCont(AggFunc):
6429    arg_types = {"this": True, "expression": False}
6430
6431
6432class PercentileDisc(AggFunc):
6433    arg_types = {"this": True, "expression": False}
6434
6435
6436class Quantile(AggFunc):
6437    arg_types = {"this": True, "quantile": True}
6438
6439
6440class ApproxQuantile(Quantile):
6441    arg_types = {"this": True, "quantile": True, "accuracy": False, "weight": False}
6442
6443
6444class Quarter(Func):
6445    pass
6446
6447
6448# https://docs.teradata.com/r/Enterprise_IntelliFlex_VMware/SQL-Functions-Expressions-and-Predicates/Arithmetic-Trigonometric-Hyperbolic-Operators/Functions/RANDOM/RANDOM-Function-Syntax
6449# teradata lower and upper bounds
6450class Rand(Func):
6451    _sql_names = ["RAND", "RANDOM"]
6452    arg_types = {"this": False, "lower": False, "upper": False}
6453
6454
6455class Randn(Func):
6456    arg_types = {"this": False}
6457
6458
6459class RangeN(Func):
6460    arg_types = {"this": True, "expressions": True, "each": False}
6461
6462
6463class ReadCSV(Func):
6464    _sql_names = ["READ_CSV"]
6465    is_var_len_args = True
6466    arg_types = {"this": True, "expressions": False}
6467
6468
6469class Reduce(Func):
6470    arg_types = {"this": True, "initial": True, "merge": True, "finish": False}
6471
6472
6473class RegexpExtract(Func):
6474    arg_types = {
6475        "this": True,
6476        "expression": True,
6477        "position": False,
6478        "occurrence": False,
6479        "parameters": False,
6480        "group": False,
6481    }
6482
6483
6484class RegexpExtractAll(Func):
6485    arg_types = {
6486        "this": True,
6487        "expression": True,
6488        "position": False,
6489        "occurrence": False,
6490        "parameters": False,
6491        "group": False,
6492    }
6493
6494
6495class RegexpReplace(Func):
6496    arg_types = {
6497        "this": True,
6498        "expression": True,
6499        "replacement": False,
6500        "position": False,
6501        "occurrence": False,
6502        "modifiers": False,
6503    }
6504
6505
6506class RegexpLike(Binary, Func):
6507    arg_types = {"this": True, "expression": True, "flag": False}
6508
6509
6510class RegexpILike(Binary, Func):
6511    arg_types = {"this": True, "expression": True, "flag": False}
6512
6513
6514# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split.html
6515# limit is the number of times a pattern is applied
6516class RegexpSplit(Func):
6517    arg_types = {"this": True, "expression": True, "limit": False}
6518
6519
6520class Repeat(Func):
6521    arg_types = {"this": True, "times": True}
6522
6523
6524# https://learn.microsoft.com/en-us/sql/t-sql/functions/round-transact-sql?view=sql-server-ver16
6525# tsql third argument function == trunctaion if not 0
6526class Round(Func):
6527    arg_types = {"this": True, "decimals": False, "truncate": False}
6528
6529
6530class RowNumber(Func):
6531    arg_types = {"this": False}
6532
6533
6534class SafeDivide(Func):
6535    arg_types = {"this": True, "expression": True}
6536
6537
6538class SHA(Func):
6539    _sql_names = ["SHA", "SHA1"]
6540
6541
6542class SHA2(Func):
6543    _sql_names = ["SHA2"]
6544    arg_types = {"this": True, "length": False}
6545
6546
6547class Sign(Func):
6548    _sql_names = ["SIGN", "SIGNUM"]
6549
6550
6551class SortArray(Func):
6552    arg_types = {"this": True, "asc": False}
6553
6554
6555class Split(Func):
6556    arg_types = {"this": True, "expression": True, "limit": False}
6557
6558
6559# https://spark.apache.org/docs/latest/api/python/reference/pyspark.sql/api/pyspark.sql.functions.split_part.html
6560class SplitPart(Func):
6561    arg_types = {"this": True, "delimiter": True, "part_index": True}
6562
6563
6564# Start may be omitted in the case of postgres
6565# https://www.postgresql.org/docs/9.1/functions-string.html @ Table 9-6
6566class Substring(Func):
6567    _sql_names = ["SUBSTRING", "SUBSTR"]
6568    arg_types = {"this": True, "start": False, "length": False}
6569
6570
6571class StandardHash(Func):
6572    arg_types = {"this": True, "expression": False}
6573
6574
6575class StartsWith(Func):
6576    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6577    arg_types = {"this": True, "expression": True}
6578
6579
6580class StrPosition(Func):
6581    arg_types = {
6582        "this": True,
6583        "substr": True,
6584        "position": False,
6585        "occurrence": False,
6586    }
6587
6588
6589class StrToDate(Func):
6590    arg_types = {"this": True, "format": False, "safe": False}
6591
6592
6593class StrToTime(Func):
6594    arg_types = {"this": True, "format": True, "zone": False, "safe": False}
6595
6596
6597# Spark allows unix_timestamp()
6598# https://spark.apache.org/docs/3.1.3/api/python/reference/api/pyspark.sql.functions.unix_timestamp.html
6599class StrToUnix(Func):
6600    arg_types = {"this": False, "format": False}
6601
6602
6603# https://prestodb.io/docs/current/functions/string.html
6604# https://spark.apache.org/docs/latest/api/sql/index.html#str_to_map
6605class StrToMap(Func):
6606    arg_types = {
6607        "this": True,
6608        "pair_delim": False,
6609        "key_value_delim": False,
6610        "duplicate_resolution_callback": False,
6611    }
6612
6613
6614class NumberToStr(Func):
6615    arg_types = {"this": True, "format": True, "culture": False}
6616
6617
6618class FromBase(Func):
6619    arg_types = {"this": True, "expression": True}
6620
6621
6622class Struct(Func):
6623    arg_types = {"expressions": False}
6624    is_var_len_args = True
6625
6626
6627class StructExtract(Func):
6628    arg_types = {"this": True, "expression": True}
6629
6630
6631# https://learn.microsoft.com/en-us/sql/t-sql/functions/stuff-transact-sql?view=sql-server-ver16
6632# https://docs.snowflake.com/en/sql-reference/functions/insert
6633class Stuff(Func):
6634    _sql_names = ["STUFF", "INSERT"]
6635    arg_types = {"this": True, "start": True, "length": True, "expression": True}
6636
6637
6638class Sum(AggFunc):
6639    pass
6640
6641
6642class Sqrt(Func):
6643    pass
6644
6645
6646class Stddev(AggFunc):
6647    _sql_names = ["STDDEV", "STDEV"]
6648
6649
6650class StddevPop(AggFunc):
6651    pass
6652
6653
6654class StddevSamp(AggFunc):
6655    pass
6656
6657
6658# https://cloud.google.com/bigquery/docs/reference/standard-sql/time_functions#time
6659class Time(Func):
6660    arg_types = {"this": False, "zone": False}
6661
6662
6663class TimeToStr(Func):
6664    arg_types = {"this": True, "format": True, "culture": False, "zone": False}
6665
6666
6667class TimeToTimeStr(Func):
6668    pass
6669
6670
6671class TimeToUnix(Func):
6672    pass
6673
6674
6675class TimeStrToDate(Func):
6676    pass
6677
6678
6679class TimeStrToTime(Func):
6680    arg_types = {"this": True, "zone": False}
6681
6682
6683class TimeStrToUnix(Func):
6684    pass
6685
6686
6687class Trim(Func):
6688    arg_types = {
6689        "this": True,
6690        "expression": False,
6691        "position": False,
6692        "collation": False,
6693    }
6694
6695
6696class TsOrDsAdd(Func, TimeUnit):
6697    # return_type is used to correctly cast the arguments of this expression when transpiling it
6698    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6699
6700    @property
6701    def return_type(self) -> DataType:
6702        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
6703
6704
6705class TsOrDsDiff(Func, TimeUnit):
6706    arg_types = {"this": True, "expression": True, "unit": False}
6707
6708
6709class TsOrDsToDateStr(Func):
6710    pass
6711
6712
6713class TsOrDsToDate(Func):
6714    arg_types = {"this": True, "format": False, "safe": False}
6715
6716
6717class TsOrDsToDatetime(Func):
6718    pass
6719
6720
6721class TsOrDsToTime(Func):
6722    arg_types = {"this": True, "format": False, "safe": False}
6723
6724
6725class TsOrDsToTimestamp(Func):
6726    pass
6727
6728
6729class TsOrDiToDi(Func):
6730    pass
6731
6732
6733class Unhex(Func):
6734    arg_types = {"this": True, "expression": False}
6735
6736
6737class Unicode(Func):
6738    pass
6739
6740
6741# https://cloud.google.com/bigquery/docs/reference/standard-sql/date_functions#unix_date
6742class UnixDate(Func):
6743    pass
6744
6745
6746class UnixToStr(Func):
6747    arg_types = {"this": True, "format": False}
6748
6749
6750# https://prestodb.io/docs/current/functions/datetime.html
6751# presto has weird zone/hours/minutes
6752class UnixToTime(Func):
6753    arg_types = {
6754        "this": True,
6755        "scale": False,
6756        "zone": False,
6757        "hours": False,
6758        "minutes": False,
6759        "format": False,
6760    }
6761
6762    SECONDS = Literal.number(0)
6763    DECIS = Literal.number(1)
6764    CENTIS = Literal.number(2)
6765    MILLIS = Literal.number(3)
6766    DECIMILLIS = Literal.number(4)
6767    CENTIMILLIS = Literal.number(5)
6768    MICROS = Literal.number(6)
6769    DECIMICROS = Literal.number(7)
6770    CENTIMICROS = Literal.number(8)
6771    NANOS = Literal.number(9)
6772
6773
6774class UnixToTimeStr(Func):
6775    pass
6776
6777
6778class UnixSeconds(Func):
6779    pass
6780
6781
6782class Uuid(Func):
6783    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6784
6785    arg_types = {"this": False, "name": False}
6786
6787
6788class TimestampFromParts(Func):
6789    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6790    arg_types = {
6791        "year": True,
6792        "month": True,
6793        "day": True,
6794        "hour": True,
6795        "min": True,
6796        "sec": True,
6797        "nano": False,
6798        "zone": False,
6799        "milli": False,
6800    }
6801
6802
6803class Upper(Func):
6804    _sql_names = ["UPPER", "UCASE"]
6805
6806
6807class Corr(Binary, AggFunc):
6808    pass
6809
6810
6811class Variance(AggFunc):
6812    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
6813
6814
6815class VariancePop(AggFunc):
6816    _sql_names = ["VARIANCE_POP", "VAR_POP"]
6817
6818
6819class CovarSamp(Binary, AggFunc):
6820    pass
6821
6822
6823class CovarPop(Binary, AggFunc):
6824    pass
6825
6826
6827class Week(Func):
6828    arg_types = {"this": True, "mode": False}
6829
6830
6831class XMLElement(Func):
6832    _sql_names = ["XMLELEMENT"]
6833    arg_types = {"this": True, "expressions": False}
6834
6835
6836class XMLTable(Func):
6837    arg_types = {
6838        "this": True,
6839        "namespaces": False,
6840        "passing": False,
6841        "columns": False,
6842        "by_ref": False,
6843    }
6844
6845
6846class XMLNamespace(Expression):
6847    pass
6848
6849
6850class Year(Func):
6851    pass
6852
6853
6854class Use(Expression):
6855    arg_types = {"this": False, "expressions": False, "kind": False}
6856
6857
6858class Merge(DML):
6859    arg_types = {
6860        "this": True,
6861        "using": True,
6862        "on": True,
6863        "whens": True,
6864        "with": False,
6865        "returning": False,
6866    }
6867
6868
6869class When(Expression):
6870    arg_types = {"matched": True, "source": False, "condition": False, "then": True}
6871
6872
6873class Whens(Expression):
6874    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6875
6876    arg_types = {"expressions": True}
6877
6878
6879# https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljnextvaluefor.html
6880# https://learn.microsoft.com/en-us/sql/t-sql/functions/next-value-for-transact-sql?view=sql-server-ver16
6881class NextValueFor(Func):
6882    arg_types = {"this": True, "order": False}
6883
6884
6885# Refers to a trailing semi-colon. This is only used to preserve trailing comments
6886# select 1; -- my comment
6887class Semicolon(Expression):
6888    arg_types = {}
6889
6890
6891def _norm_arg(arg):
6892    return arg.lower() if type(arg) is str else arg
6893
6894
6895ALL_FUNCTIONS = subclasses(__name__, Func, (AggFunc, Anonymous, Func))
6896FUNCTION_BY_NAME = {name: func for func in ALL_FUNCTIONS for name in func.sql_names()}
6897
6898JSON_PATH_PARTS = subclasses(__name__, JSONPathPart, (JSONPathPart,))
6899
6900PERCENTILES = (PercentileCont, PercentileDisc)
6901
6902
6903# Helpers
6904@t.overload
6905def maybe_parse(
6906    sql_or_expression: ExpOrStr,
6907    *,
6908    into: t.Type[E],
6909    dialect: DialectType = None,
6910    prefix: t.Optional[str] = None,
6911    copy: bool = False,
6912    **opts,
6913) -> E: ...
6914
6915
6916@t.overload
6917def maybe_parse(
6918    sql_or_expression: str | E,
6919    *,
6920    into: t.Optional[IntoType] = None,
6921    dialect: DialectType = None,
6922    prefix: t.Optional[str] = None,
6923    copy: bool = False,
6924    **opts,
6925) -> E: ...
6926
6927
6928def maybe_parse(
6929    sql_or_expression: ExpOrStr,
6930    *,
6931    into: t.Optional[IntoType] = None,
6932    dialect: DialectType = None,
6933    prefix: t.Optional[str] = None,
6934    copy: bool = False,
6935    **opts,
6936) -> Expression:
6937    """Gracefully handle a possible string or expression.
6938
6939    Example:
6940        >>> maybe_parse("1")
6941        Literal(this=1, is_string=False)
6942        >>> maybe_parse(to_identifier("x"))
6943        Identifier(this=x, quoted=False)
6944
6945    Args:
6946        sql_or_expression: the SQL code string or an expression
6947        into: the SQLGlot Expression to parse into
6948        dialect: the dialect used to parse the input expressions (in the case that an
6949            input expression is a SQL string).
6950        prefix: a string to prefix the sql with before it gets parsed
6951            (automatically includes a space)
6952        copy: whether to copy the expression.
6953        **opts: other options to use to parse the input expressions (again, in the case
6954            that an input expression is a SQL string).
6955
6956    Returns:
6957        Expression: the parsed or given expression.
6958    """
6959    if isinstance(sql_or_expression, Expression):
6960        if copy:
6961            return sql_or_expression.copy()
6962        return sql_or_expression
6963
6964    if sql_or_expression is None:
6965        raise ParseError("SQL cannot be None")
6966
6967    import sqlglot
6968
6969    sql = str(sql_or_expression)
6970    if prefix:
6971        sql = f"{prefix} {sql}"
6972
6973    return sqlglot.parse_one(sql, read=dialect, into=into, **opts)
6974
6975
6976@t.overload
6977def maybe_copy(instance: None, copy: bool = True) -> None: ...
6978
6979
6980@t.overload
6981def maybe_copy(instance: E, copy: bool = True) -> E: ...
6982
6983
6984def maybe_copy(instance, copy=True):
6985    return instance.copy() if copy and instance else instance
6986
6987
6988def _to_s(node: t.Any, verbose: bool = False, level: int = 0) -> str:
6989    """Generate a textual representation of an Expression tree"""
6990    indent = "\n" + ("  " * (level + 1))
6991    delim = f",{indent}"
6992
6993    if isinstance(node, Expression):
6994        args = {k: v for k, v in node.args.items() if (v is not None and v != []) or verbose}
6995
6996        if (node.type or verbose) and not isinstance(node, DataType):
6997            args["_type"] = node.type
6998        if node.comments or verbose:
6999            args["_comments"] = node.comments
7000
7001        if verbose:
7002            args["_id"] = id(node)
7003
7004        # Inline leaves for a more compact representation
7005        if node.is_leaf():
7006            indent = ""
7007            delim = ", "
7008
7009        items = delim.join([f"{k}={_to_s(v, verbose, level + 1)}" for k, v in args.items()])
7010        return f"{node.__class__.__name__}({indent}{items})"
7011
7012    if isinstance(node, list):
7013        items = delim.join(_to_s(i, verbose, level + 1) for i in node)
7014        items = f"{indent}{items}" if items else ""
7015        return f"[{items}]"
7016
7017    # Indent multiline strings to match the current level
7018    return indent.join(textwrap.dedent(str(node).strip("\n")).splitlines())
7019
7020
7021def _is_wrong_expression(expression, into):
7022    return isinstance(expression, Expression) and not isinstance(expression, into)
7023
7024
7025def _apply_builder(
7026    expression,
7027    instance,
7028    arg,
7029    copy=True,
7030    prefix=None,
7031    into=None,
7032    dialect=None,
7033    into_arg="this",
7034    **opts,
7035):
7036    if _is_wrong_expression(expression, into):
7037        expression = into(**{into_arg: expression})
7038    instance = maybe_copy(instance, copy)
7039    expression = maybe_parse(
7040        sql_or_expression=expression,
7041        prefix=prefix,
7042        into=into,
7043        dialect=dialect,
7044        **opts,
7045    )
7046    instance.set(arg, expression)
7047    return instance
7048
7049
7050def _apply_child_list_builder(
7051    *expressions,
7052    instance,
7053    arg,
7054    append=True,
7055    copy=True,
7056    prefix=None,
7057    into=None,
7058    dialect=None,
7059    properties=None,
7060    **opts,
7061):
7062    instance = maybe_copy(instance, copy)
7063    parsed = []
7064    properties = {} if properties is None else properties
7065
7066    for expression in expressions:
7067        if expression is not None:
7068            if _is_wrong_expression(expression, into):
7069                expression = into(expressions=[expression])
7070
7071            expression = maybe_parse(
7072                expression,
7073                into=into,
7074                dialect=dialect,
7075                prefix=prefix,
7076                **opts,
7077            )
7078            for k, v in expression.args.items():
7079                if k == "expressions":
7080                    parsed.extend(v)
7081                else:
7082                    properties[k] = v
7083
7084    existing = instance.args.get(arg)
7085    if append and existing:
7086        parsed = existing.expressions + parsed
7087
7088    child = into(expressions=parsed)
7089    for k, v in properties.items():
7090        child.set(k, v)
7091    instance.set(arg, child)
7092
7093    return instance
7094
7095
7096def _apply_list_builder(
7097    *expressions,
7098    instance,
7099    arg,
7100    append=True,
7101    copy=True,
7102    prefix=None,
7103    into=None,
7104    dialect=None,
7105    **opts,
7106):
7107    inst = maybe_copy(instance, copy)
7108
7109    expressions = [
7110        maybe_parse(
7111            sql_or_expression=expression,
7112            into=into,
7113            prefix=prefix,
7114            dialect=dialect,
7115            **opts,
7116        )
7117        for expression in expressions
7118        if expression is not None
7119    ]
7120
7121    existing_expressions = inst.args.get(arg)
7122    if append and existing_expressions:
7123        expressions = existing_expressions + expressions
7124
7125    inst.set(arg, expressions)
7126    return inst
7127
7128
7129def _apply_conjunction_builder(
7130    *expressions,
7131    instance,
7132    arg,
7133    into=None,
7134    append=True,
7135    copy=True,
7136    dialect=None,
7137    **opts,
7138):
7139    expressions = [exp for exp in expressions if exp is not None and exp != ""]
7140    if not expressions:
7141        return instance
7142
7143    inst = maybe_copy(instance, copy)
7144
7145    existing = inst.args.get(arg)
7146    if append and existing is not None:
7147        expressions = [existing.this if into else existing] + list(expressions)
7148
7149    node = and_(*expressions, dialect=dialect, copy=copy, **opts)
7150
7151    inst.set(arg, into(this=node) if into else node)
7152    return inst
7153
7154
7155def _apply_cte_builder(
7156    instance: E,
7157    alias: ExpOrStr,
7158    as_: ExpOrStr,
7159    recursive: t.Optional[bool] = None,
7160    materialized: t.Optional[bool] = None,
7161    append: bool = True,
7162    dialect: DialectType = None,
7163    copy: bool = True,
7164    scalar: bool = False,
7165    **opts,
7166) -> E:
7167    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
7168    as_expression = maybe_parse(as_, dialect=dialect, copy=copy, **opts)
7169    if scalar and not isinstance(as_expression, Subquery):
7170        # scalar CTE must be wrapped in a subquery
7171        as_expression = Subquery(this=as_expression)
7172    cte = CTE(this=as_expression, alias=alias_expression, materialized=materialized, scalar=scalar)
7173    return _apply_child_list_builder(
7174        cte,
7175        instance=instance,
7176        arg="with",
7177        append=append,
7178        copy=copy,
7179        into=With,
7180        properties={"recursive": recursive or False},
7181    )
7182
7183
7184def _combine(
7185    expressions: t.Sequence[t.Optional[ExpOrStr]],
7186    operator: t.Type[Connector],
7187    dialect: DialectType = None,
7188    copy: bool = True,
7189    wrap: bool = True,
7190    **opts,
7191) -> Expression:
7192    conditions = [
7193        condition(expression, dialect=dialect, copy=copy, **opts)
7194        for expression in expressions
7195        if expression is not None
7196    ]
7197
7198    this, *rest = conditions
7199    if rest and wrap:
7200        this = _wrap(this, Connector)
7201    for expression in rest:
7202        this = operator(this=this, expression=_wrap(expression, Connector) if wrap else expression)
7203
7204    return this
7205
7206
7207@t.overload
7208def _wrap(expression: None, kind: t.Type[Expression]) -> None: ...
7209
7210
7211@t.overload
7212def _wrap(expression: E, kind: t.Type[Expression]) -> E | Paren: ...
7213
7214
7215def _wrap(expression: t.Optional[E], kind: t.Type[Expression]) -> t.Optional[E] | Paren:
7216    return Paren(this=expression) if isinstance(expression, kind) else expression
7217
7218
7219def _apply_set_operation(
7220    *expressions: ExpOrStr,
7221    set_operation: t.Type[S],
7222    distinct: bool = True,
7223    dialect: DialectType = None,
7224    copy: bool = True,
7225    **opts,
7226) -> S:
7227    return reduce(
7228        lambda x, y: set_operation(this=x, expression=y, distinct=distinct),
7229        (maybe_parse(e, dialect=dialect, copy=copy, **opts) for e in expressions),
7230    )
7231
7232
7233def union(
7234    *expressions: ExpOrStr,
7235    distinct: bool = True,
7236    dialect: DialectType = None,
7237    copy: bool = True,
7238    **opts,
7239) -> Union:
7240    """
7241    Initializes a syntax tree for the `UNION` operation.
7242
7243    Example:
7244        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7245        'SELECT * FROM foo UNION SELECT * FROM bla'
7246
7247    Args:
7248        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7249            If `Expression` instances are passed, they will be used as-is.
7250        distinct: set the DISTINCT flag if and only if this is true.
7251        dialect: the dialect used to parse the input expression.
7252        copy: whether to copy the expression.
7253        opts: other options to use to parse the input expressions.
7254
7255    Returns:
7256        The new Union instance.
7257    """
7258    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7259    return _apply_set_operation(
7260        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7261    )
7262
7263
7264def intersect(
7265    *expressions: ExpOrStr,
7266    distinct: bool = True,
7267    dialect: DialectType = None,
7268    copy: bool = True,
7269    **opts,
7270) -> Intersect:
7271    """
7272    Initializes a syntax tree for the `INTERSECT` operation.
7273
7274    Example:
7275        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
7276        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
7277
7278    Args:
7279        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
7280            If `Expression` instances are passed, they will be used as-is.
7281        distinct: set the DISTINCT flag if and only if this is true.
7282        dialect: the dialect used to parse the input expression.
7283        copy: whether to copy the expression.
7284        opts: other options to use to parse the input expressions.
7285
7286    Returns:
7287        The new Intersect instance.
7288    """
7289    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
7290    return _apply_set_operation(
7291        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
7292    )
7293
7294
7295def except_(
7296    *expressions: ExpOrStr,
7297    distinct: bool = True,
7298    dialect: DialectType = None,
7299    copy: bool = True,
7300    **opts,
7301) -> Except:
7302    """
7303    Initializes a syntax tree for the `EXCEPT` operation.
7304
7305    Example:
7306        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
7307        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
7308
7309    Args:
7310        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
7311            If `Expression` instances are passed, they will be used as-is.
7312        distinct: set the DISTINCT flag if and only if this is true.
7313        dialect: the dialect used to parse the input expression.
7314        copy: whether to copy the expression.
7315        opts: other options to use to parse the input expressions.
7316
7317    Returns:
7318        The new Except instance.
7319    """
7320    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
7321    return _apply_set_operation(
7322        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
7323    )
7324
7325
7326def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7327    """
7328    Initializes a syntax tree from one or multiple SELECT expressions.
7329
7330    Example:
7331        >>> select("col1", "col2").from_("tbl").sql()
7332        'SELECT col1, col2 FROM tbl'
7333
7334    Args:
7335        *expressions: the SQL code string to parse as the expressions of a
7336            SELECT statement. If an Expression instance is passed, this is used as-is.
7337        dialect: the dialect used to parse the input expressions (in the case that an
7338            input expression is a SQL string).
7339        **opts: other options to use to parse the input expressions (again, in the case
7340            that an input expression is a SQL string).
7341
7342    Returns:
7343        Select: the syntax tree for the SELECT statement.
7344    """
7345    return Select().select(*expressions, dialect=dialect, **opts)
7346
7347
7348def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7349    """
7350    Initializes a syntax tree from a FROM expression.
7351
7352    Example:
7353        >>> from_("tbl").select("col1", "col2").sql()
7354        'SELECT col1, col2 FROM tbl'
7355
7356    Args:
7357        *expression: the SQL code string to parse as the FROM expressions of a
7358            SELECT statement. If an Expression instance is passed, this is used as-is.
7359        dialect: the dialect used to parse the input expression (in the case that the
7360            input expression is a SQL string).
7361        **opts: other options to use to parse the input expressions (again, in the case
7362            that the input expression is a SQL string).
7363
7364    Returns:
7365        Select: the syntax tree for the SELECT statement.
7366    """
7367    return Select().from_(expression, dialect=dialect, **opts)
7368
7369
7370def update(
7371    table: str | Table,
7372    properties: t.Optional[dict] = None,
7373    where: t.Optional[ExpOrStr] = None,
7374    from_: t.Optional[ExpOrStr] = None,
7375    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7376    dialect: DialectType = None,
7377    **opts,
7378) -> Update:
7379    """
7380    Creates an update statement.
7381
7382    Example:
7383        >>> 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()
7384        "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"
7385
7386    Args:
7387        properties: dictionary of properties to SET which are
7388            auto converted to sql objects eg None -> NULL
7389        where: sql conditional parsed into a WHERE statement
7390        from_: sql statement parsed into a FROM statement
7391        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7392        dialect: the dialect used to parse the input expressions.
7393        **opts: other options to use to parse the input expressions.
7394
7395    Returns:
7396        Update: the syntax tree for the UPDATE statement.
7397    """
7398    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7399    if properties:
7400        update_expr.set(
7401            "expressions",
7402            [
7403                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7404                for k, v in properties.items()
7405            ],
7406        )
7407    if from_:
7408        update_expr.set(
7409            "from",
7410            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7411        )
7412    if isinstance(where, Condition):
7413        where = Where(this=where)
7414    if where:
7415        update_expr.set(
7416            "where",
7417            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7418        )
7419    if with_:
7420        cte_list = [
7421            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7422            for alias, qry in with_.items()
7423        ]
7424        update_expr.set(
7425            "with",
7426            With(expressions=cte_list),
7427        )
7428    return update_expr
7429
7430
7431def delete(
7432    table: ExpOrStr,
7433    where: t.Optional[ExpOrStr] = None,
7434    returning: t.Optional[ExpOrStr] = None,
7435    dialect: DialectType = None,
7436    **opts,
7437) -> Delete:
7438    """
7439    Builds a delete statement.
7440
7441    Example:
7442        >>> delete("my_table", where="id > 1").sql()
7443        'DELETE FROM my_table WHERE id > 1'
7444
7445    Args:
7446        where: sql conditional parsed into a WHERE statement
7447        returning: sql conditional parsed into a RETURNING statement
7448        dialect: the dialect used to parse the input expressions.
7449        **opts: other options to use to parse the input expressions.
7450
7451    Returns:
7452        Delete: the syntax tree for the DELETE statement.
7453    """
7454    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7455    if where:
7456        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7457    if returning:
7458        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7459    return delete_expr
7460
7461
7462def insert(
7463    expression: ExpOrStr,
7464    into: ExpOrStr,
7465    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7466    overwrite: t.Optional[bool] = None,
7467    returning: t.Optional[ExpOrStr] = None,
7468    dialect: DialectType = None,
7469    copy: bool = True,
7470    **opts,
7471) -> Insert:
7472    """
7473    Builds an INSERT statement.
7474
7475    Example:
7476        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7477        'INSERT INTO tbl VALUES (1, 2, 3)'
7478
7479    Args:
7480        expression: the sql string or expression of the INSERT statement
7481        into: the tbl to insert data to.
7482        columns: optionally the table's column names.
7483        overwrite: whether to INSERT OVERWRITE or not.
7484        returning: sql conditional parsed into a RETURNING statement
7485        dialect: the dialect used to parse the input expressions.
7486        copy: whether to copy the expression.
7487        **opts: other options to use to parse the input expressions.
7488
7489    Returns:
7490        Insert: the syntax tree for the INSERT statement.
7491    """
7492    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7493    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7494
7495    if columns:
7496        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7497
7498    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7499
7500    if returning:
7501        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7502
7503    return insert
7504
7505
7506def merge(
7507    *when_exprs: ExpOrStr,
7508    into: ExpOrStr,
7509    using: ExpOrStr,
7510    on: ExpOrStr,
7511    returning: t.Optional[ExpOrStr] = None,
7512    dialect: DialectType = None,
7513    copy: bool = True,
7514    **opts,
7515) -> Merge:
7516    """
7517    Builds a MERGE statement.
7518
7519    Example:
7520        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7521        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7522        ...       into="my_table",
7523        ...       using="source_table",
7524        ...       on="my_table.id = source_table.id").sql()
7525        '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)'
7526
7527    Args:
7528        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7529        into: The target table to merge data into.
7530        using: The source table to merge data from.
7531        on: The join condition for the merge.
7532        returning: The columns to return from the merge.
7533        dialect: The dialect used to parse the input expressions.
7534        copy: Whether to copy the expression.
7535        **opts: Other options to use to parse the input expressions.
7536
7537    Returns:
7538        Merge: The syntax tree for the MERGE statement.
7539    """
7540    expressions: t.List[Expression] = []
7541    for when_expr in when_exprs:
7542        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7543        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7544
7545    merge = Merge(
7546        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7547        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7548        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7549        whens=Whens(expressions=expressions),
7550    )
7551    if returning:
7552        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7553
7554    return merge
7555
7556
7557def condition(
7558    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7559) -> Condition:
7560    """
7561    Initialize a logical condition expression.
7562
7563    Example:
7564        >>> condition("x=1").sql()
7565        'x = 1'
7566
7567        This is helpful for composing larger logical syntax trees:
7568        >>> where = condition("x=1")
7569        >>> where = where.and_("y=1")
7570        >>> Select().from_("tbl").select("*").where(where).sql()
7571        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7572
7573    Args:
7574        *expression: the SQL code string to parse.
7575            If an Expression instance is passed, this is used as-is.
7576        dialect: the dialect used to parse the input expression (in the case that the
7577            input expression is a SQL string).
7578        copy: Whether to copy `expression` (only applies to expressions).
7579        **opts: other options to use to parse the input expressions (again, in the case
7580            that the input expression is a SQL string).
7581
7582    Returns:
7583        The new Condition instance
7584    """
7585    return maybe_parse(
7586        expression,
7587        into=Condition,
7588        dialect=dialect,
7589        copy=copy,
7590        **opts,
7591    )
7592
7593
7594def and_(
7595    *expressions: t.Optional[ExpOrStr],
7596    dialect: DialectType = None,
7597    copy: bool = True,
7598    wrap: bool = True,
7599    **opts,
7600) -> Condition:
7601    """
7602    Combine multiple conditions with an AND logical operator.
7603
7604    Example:
7605        >>> and_("x=1", and_("y=1", "z=1")).sql()
7606        'x = 1 AND (y = 1 AND z = 1)'
7607
7608    Args:
7609        *expressions: the SQL code strings to parse.
7610            If an Expression instance is passed, this is used as-is.
7611        dialect: the dialect used to parse the input expression.
7612        copy: whether to copy `expressions` (only applies to Expressions).
7613        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7614            precedence issues, but can be turned off when the produced AST is too deep and
7615            causes recursion-related issues.
7616        **opts: other options to use to parse the input expressions.
7617
7618    Returns:
7619        The new condition
7620    """
7621    return t.cast(Condition, _combine(expressions, And, dialect, copy=copy, wrap=wrap, **opts))
7622
7623
7624def or_(
7625    *expressions: t.Optional[ExpOrStr],
7626    dialect: DialectType = None,
7627    copy: bool = True,
7628    wrap: bool = True,
7629    **opts,
7630) -> Condition:
7631    """
7632    Combine multiple conditions with an OR logical operator.
7633
7634    Example:
7635        >>> or_("x=1", or_("y=1", "z=1")).sql()
7636        'x = 1 OR (y = 1 OR z = 1)'
7637
7638    Args:
7639        *expressions: the SQL code strings to parse.
7640            If an Expression instance is passed, this is used as-is.
7641        dialect: the dialect used to parse the input expression.
7642        copy: whether to copy `expressions` (only applies to Expressions).
7643        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7644            precedence issues, but can be turned off when the produced AST is too deep and
7645            causes recursion-related issues.
7646        **opts: other options to use to parse the input expressions.
7647
7648    Returns:
7649        The new condition
7650    """
7651    return t.cast(Condition, _combine(expressions, Or, dialect, copy=copy, wrap=wrap, **opts))
7652
7653
7654def xor(
7655    *expressions: t.Optional[ExpOrStr],
7656    dialect: DialectType = None,
7657    copy: bool = True,
7658    wrap: bool = True,
7659    **opts,
7660) -> Condition:
7661    """
7662    Combine multiple conditions with an XOR logical operator.
7663
7664    Example:
7665        >>> xor("x=1", xor("y=1", "z=1")).sql()
7666        'x = 1 XOR (y = 1 XOR z = 1)'
7667
7668    Args:
7669        *expressions: the SQL code strings to parse.
7670            If an Expression instance is passed, this is used as-is.
7671        dialect: the dialect used to parse the input expression.
7672        copy: whether to copy `expressions` (only applies to Expressions).
7673        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7674            precedence issues, but can be turned off when the produced AST is too deep and
7675            causes recursion-related issues.
7676        **opts: other options to use to parse the input expressions.
7677
7678    Returns:
7679        The new condition
7680    """
7681    return t.cast(Condition, _combine(expressions, Xor, dialect, copy=copy, wrap=wrap, **opts))
7682
7683
7684def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7685    """
7686    Wrap a condition with a NOT operator.
7687
7688    Example:
7689        >>> not_("this_suit='black'").sql()
7690        "NOT this_suit = 'black'"
7691
7692    Args:
7693        expression: the SQL code string to parse.
7694            If an Expression instance is passed, this is used as-is.
7695        dialect: the dialect used to parse the input expression.
7696        copy: whether to copy the expression or not.
7697        **opts: other options to use to parse the input expressions.
7698
7699    Returns:
7700        The new condition.
7701    """
7702    this = condition(
7703        expression,
7704        dialect=dialect,
7705        copy=copy,
7706        **opts,
7707    )
7708    return Not(this=_wrap(this, Connector))
7709
7710
7711def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7712    """
7713    Wrap an expression in parentheses.
7714
7715    Example:
7716        >>> paren("5 + 3").sql()
7717        '(5 + 3)'
7718
7719    Args:
7720        expression: the SQL code string to parse.
7721            If an Expression instance is passed, this is used as-is.
7722        copy: whether to copy the expression or not.
7723
7724    Returns:
7725        The wrapped expression.
7726    """
7727    return Paren(this=maybe_parse(expression, copy=copy))
7728
7729
7730SAFE_IDENTIFIER_RE: t.Pattern[str] = re.compile(r"^[_a-zA-Z][\w]*$")
7731
7732
7733@t.overload
7734def to_identifier(name: None, quoted: t.Optional[bool] = None, copy: bool = True) -> None: ...
7735
7736
7737@t.overload
7738def to_identifier(
7739    name: str | Identifier, quoted: t.Optional[bool] = None, copy: bool = True
7740) -> Identifier: ...
7741
7742
7743def to_identifier(name, quoted=None, copy=True):
7744    """Builds an identifier.
7745
7746    Args:
7747        name: The name to turn into an identifier.
7748        quoted: Whether to force quote the identifier.
7749        copy: Whether to copy name if it's an Identifier.
7750
7751    Returns:
7752        The identifier ast node.
7753    """
7754
7755    if name is None:
7756        return None
7757
7758    if isinstance(name, Identifier):
7759        identifier = maybe_copy(name, copy)
7760    elif isinstance(name, str):
7761        identifier = Identifier(
7762            this=name,
7763            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7764        )
7765    else:
7766        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7767    return identifier
7768
7769
7770def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7771    """
7772    Parses a given string into an identifier.
7773
7774    Args:
7775        name: The name to parse into an identifier.
7776        dialect: The dialect to parse against.
7777
7778    Returns:
7779        The identifier ast node.
7780    """
7781    try:
7782        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7783    except (ParseError, TokenError):
7784        expression = to_identifier(name)
7785
7786    return expression
7787
7788
7789INTERVAL_STRING_RE = re.compile(r"\s*([0-9]+)\s*([a-zA-Z]+)\s*")
7790
7791
7792def to_interval(interval: str | Literal) -> Interval:
7793    """Builds an interval expression from a string like '1 day' or '5 months'."""
7794    if isinstance(interval, Literal):
7795        if not interval.is_string:
7796            raise ValueError("Invalid interval string.")
7797
7798        interval = interval.this
7799
7800    interval = maybe_parse(f"INTERVAL {interval}")
7801    assert isinstance(interval, Interval)
7802    return interval
7803
7804
7805def to_table(
7806    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7807) -> Table:
7808    """
7809    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7810    If a table is passed in then that table is returned.
7811
7812    Args:
7813        sql_path: a `[catalog].[schema].[table]` string.
7814        dialect: the source dialect according to which the table name will be parsed.
7815        copy: Whether to copy a table if it is passed in.
7816        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7817
7818    Returns:
7819        A table expression.
7820    """
7821    if isinstance(sql_path, Table):
7822        return maybe_copy(sql_path, copy=copy)
7823
7824    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7825
7826    for k, v in kwargs.items():
7827        table.set(k, v)
7828
7829    return table
7830
7831
7832def to_column(
7833    sql_path: str | Column,
7834    quoted: t.Optional[bool] = None,
7835    dialect: DialectType = None,
7836    copy: bool = True,
7837    **kwargs,
7838) -> Column:
7839    """
7840    Create a column from a `[table].[column]` sql path. Table is optional.
7841    If a column is passed in then that column is returned.
7842
7843    Args:
7844        sql_path: a `[table].[column]` string.
7845        quoted: Whether or not to force quote identifiers.
7846        dialect: the source dialect according to which the column name will be parsed.
7847        copy: Whether to copy a column if it is passed in.
7848        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7849
7850    Returns:
7851        A column expression.
7852    """
7853    if isinstance(sql_path, Column):
7854        return maybe_copy(sql_path, copy=copy)
7855
7856    try:
7857        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7858    except ParseError:
7859        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7860
7861    for k, v in kwargs.items():
7862        col.set(k, v)
7863
7864    if quoted:
7865        for i in col.find_all(Identifier):
7866            i.set("quoted", True)
7867
7868    return col
7869
7870
7871def alias_(
7872    expression: ExpOrStr,
7873    alias: t.Optional[str | Identifier],
7874    table: bool | t.Sequence[str | Identifier] = False,
7875    quoted: t.Optional[bool] = None,
7876    dialect: DialectType = None,
7877    copy: bool = True,
7878    **opts,
7879):
7880    """Create an Alias expression.
7881
7882    Example:
7883        >>> alias_('foo', 'bar').sql()
7884        'foo AS bar'
7885
7886        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7887        '(SELECT 1, 2) AS bar(a, b)'
7888
7889    Args:
7890        expression: the SQL code strings to parse.
7891            If an Expression instance is passed, this is used as-is.
7892        alias: the alias name to use. If the name has
7893            special characters it is quoted.
7894        table: Whether to create a table alias, can also be a list of columns.
7895        quoted: whether to quote the alias
7896        dialect: the dialect used to parse the input expression.
7897        copy: Whether to copy the expression.
7898        **opts: other options to use to parse the input expressions.
7899
7900    Returns:
7901        Alias: the aliased expression
7902    """
7903    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7904    alias = to_identifier(alias, quoted=quoted)
7905
7906    if table:
7907        table_alias = TableAlias(this=alias)
7908        exp.set("alias", table_alias)
7909
7910        if not isinstance(table, bool):
7911            for column in table:
7912                table_alias.append("columns", to_identifier(column, quoted=quoted))
7913
7914        return exp
7915
7916    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7917    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7918    # for the complete Window expression.
7919    #
7920    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7921
7922    if "alias" in exp.arg_types and not isinstance(exp, Window):
7923        exp.set("alias", alias)
7924        return exp
7925    return Alias(this=exp, alias=alias)
7926
7927
7928def subquery(
7929    expression: ExpOrStr,
7930    alias: t.Optional[Identifier | str] = None,
7931    dialect: DialectType = None,
7932    **opts,
7933) -> Select:
7934    """
7935    Build a subquery expression that's selected from.
7936
7937    Example:
7938        >>> subquery('select x from tbl', 'bar').select('x').sql()
7939        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7940
7941    Args:
7942        expression: the SQL code strings to parse.
7943            If an Expression instance is passed, this is used as-is.
7944        alias: the alias name to use.
7945        dialect: the dialect used to parse the input expression.
7946        **opts: other options to use to parse the input expressions.
7947
7948    Returns:
7949        A new Select instance with the subquery expression included.
7950    """
7951
7952    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7953    return Select().from_(expression, dialect=dialect, **opts)
7954
7955
7956@t.overload
7957def column(
7958    col: str | Identifier,
7959    table: t.Optional[str | Identifier] = None,
7960    db: t.Optional[str | Identifier] = None,
7961    catalog: t.Optional[str | Identifier] = None,
7962    *,
7963    fields: t.Collection[t.Union[str, Identifier]],
7964    quoted: t.Optional[bool] = None,
7965    copy: bool = True,
7966) -> Dot:
7967    pass
7968
7969
7970@t.overload
7971def column(
7972    col: str | Identifier,
7973    table: t.Optional[str | Identifier] = None,
7974    db: t.Optional[str | Identifier] = None,
7975    catalog: t.Optional[str | Identifier] = None,
7976    *,
7977    fields: Lit[None] = None,
7978    quoted: t.Optional[bool] = None,
7979    copy: bool = True,
7980) -> Column:
7981    pass
7982
7983
7984def column(
7985    col,
7986    table=None,
7987    db=None,
7988    catalog=None,
7989    *,
7990    fields=None,
7991    quoted=None,
7992    copy=True,
7993):
7994    """
7995    Build a Column.
7996
7997    Args:
7998        col: Column name.
7999        table: Table name.
8000        db: Database name.
8001        catalog: Catalog name.
8002        fields: Additional fields using dots.
8003        quoted: Whether to force quotes on the column's identifiers.
8004        copy: Whether to copy identifiers if passed in.
8005
8006    Returns:
8007        The new Column instance.
8008    """
8009    this = Column(
8010        this=to_identifier(col, quoted=quoted, copy=copy),
8011        table=to_identifier(table, quoted=quoted, copy=copy),
8012        db=to_identifier(db, quoted=quoted, copy=copy),
8013        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8014    )
8015
8016    if fields:
8017        this = Dot.build(
8018            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8019        )
8020    return this
8021
8022
8023def cast(
8024    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8025) -> Cast:
8026    """Cast an expression to a data type.
8027
8028    Example:
8029        >>> cast('x + 1', 'int').sql()
8030        'CAST(x + 1 AS INT)'
8031
8032    Args:
8033        expression: The expression to cast.
8034        to: The datatype to cast to.
8035        copy: Whether to copy the supplied expressions.
8036        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8037            - The expression to be cast is already a exp.Cast expression
8038            - The existing cast is to a type that is logically equivalent to new type
8039
8040            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8041            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8042            and instead just return the original expression `CAST(x as DATETIME)`.
8043
8044            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8045            mapping is applied in the target dialect generator.
8046
8047    Returns:
8048        The new Cast instance.
8049    """
8050    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8051    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8052
8053    # dont re-cast if the expression is already a cast to the correct type
8054    if isinstance(expr, Cast):
8055        from sqlglot.dialects.dialect import Dialect
8056
8057        target_dialect = Dialect.get_or_raise(dialect)
8058        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8059
8060        existing_cast_type: DataType.Type = expr.to.this
8061        new_cast_type: DataType.Type = data_type.this
8062        types_are_equivalent = type_mapping.get(
8063            existing_cast_type, existing_cast_type.value
8064        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8065
8066        if expr.is_type(data_type) or types_are_equivalent:
8067            return expr
8068
8069    expr = Cast(this=expr, to=data_type)
8070    expr.type = data_type
8071
8072    return expr
8073
8074
8075def table_(
8076    table: Identifier | str,
8077    db: t.Optional[Identifier | str] = None,
8078    catalog: t.Optional[Identifier | str] = None,
8079    quoted: t.Optional[bool] = None,
8080    alias: t.Optional[Identifier | str] = None,
8081) -> Table:
8082    """Build a Table.
8083
8084    Args:
8085        table: Table name.
8086        db: Database name.
8087        catalog: Catalog name.
8088        quote: Whether to force quotes on the table's identifiers.
8089        alias: Table's alias.
8090
8091    Returns:
8092        The new Table instance.
8093    """
8094    return Table(
8095        this=to_identifier(table, quoted=quoted) if table else None,
8096        db=to_identifier(db, quoted=quoted) if db else None,
8097        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8098        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8099    )
8100
8101
8102def values(
8103    values: t.Iterable[t.Tuple[t.Any, ...]],
8104    alias: t.Optional[str] = None,
8105    columns: t.Optional[t.Iterable[str] | t.Dict[str, DataType]] = None,
8106) -> Values:
8107    """Build VALUES statement.
8108
8109    Example:
8110        >>> values([(1, '2')]).sql()
8111        "VALUES (1, '2')"
8112
8113    Args:
8114        values: values statements that will be converted to SQL
8115        alias: optional alias
8116        columns: Optional list of ordered column names or ordered dictionary of column names to types.
8117         If either are provided then an alias is also required.
8118
8119    Returns:
8120        Values: the Values expression object
8121    """
8122    if columns and not alias:
8123        raise ValueError("Alias is required when providing columns")
8124
8125    return Values(
8126        expressions=[convert(tup) for tup in values],
8127        alias=(
8128            TableAlias(this=to_identifier(alias), columns=[to_identifier(x) for x in columns])
8129            if columns
8130            else (TableAlias(this=to_identifier(alias)) if alias else None)
8131        ),
8132    )
8133
8134
8135def var(name: t.Optional[ExpOrStr]) -> Var:
8136    """Build a SQL variable.
8137
8138    Example:
8139        >>> repr(var('x'))
8140        'Var(this=x)'
8141
8142        >>> repr(var(column('x', table='y')))
8143        'Var(this=x)'
8144
8145    Args:
8146        name: The name of the var or an expression who's name will become the var.
8147
8148    Returns:
8149        The new variable node.
8150    """
8151    if not name:
8152        raise ValueError("Cannot convert empty name into var.")
8153
8154    if isinstance(name, Expression):
8155        name = name.name
8156    return Var(this=name)
8157
8158
8159def rename_table(
8160    old_name: str | Table,
8161    new_name: str | Table,
8162    dialect: DialectType = None,
8163) -> Alter:
8164    """Build ALTER TABLE... RENAME... expression
8165
8166    Args:
8167        old_name: The old name of the table
8168        new_name: The new name of the table
8169        dialect: The dialect to parse the table.
8170
8171    Returns:
8172        Alter table expression
8173    """
8174    old_table = to_table(old_name, dialect=dialect)
8175    new_table = to_table(new_name, dialect=dialect)
8176    return Alter(
8177        this=old_table,
8178        kind="TABLE",
8179        actions=[
8180            AlterRename(this=new_table),
8181        ],
8182    )
8183
8184
8185def rename_column(
8186    table_name: str | Table,
8187    old_column_name: str | Column,
8188    new_column_name: str | Column,
8189    exists: t.Optional[bool] = None,
8190    dialect: DialectType = None,
8191) -> Alter:
8192    """Build ALTER TABLE... RENAME COLUMN... expression
8193
8194    Args:
8195        table_name: Name of the table
8196        old_column: The old name of the column
8197        new_column: The new name of the column
8198        exists: Whether to add the `IF EXISTS` clause
8199        dialect: The dialect to parse the table/column.
8200
8201    Returns:
8202        Alter table expression
8203    """
8204    table = to_table(table_name, dialect=dialect)
8205    old_column = to_column(old_column_name, dialect=dialect)
8206    new_column = to_column(new_column_name, dialect=dialect)
8207    return Alter(
8208        this=table,
8209        kind="TABLE",
8210        actions=[
8211            RenameColumn(this=old_column, to=new_column, exists=exists),
8212        ],
8213    )
8214
8215
8216def convert(value: t.Any, copy: bool = False) -> Expression:
8217    """Convert a python value into an expression object.
8218
8219    Raises an error if a conversion is not possible.
8220
8221    Args:
8222        value: A python object.
8223        copy: Whether to copy `value` (only applies to Expressions and collections).
8224
8225    Returns:
8226        The equivalent expression object.
8227    """
8228    if isinstance(value, Expression):
8229        return maybe_copy(value, copy)
8230    if isinstance(value, str):
8231        return Literal.string(value)
8232    if isinstance(value, bool):
8233        return Boolean(this=value)
8234    if value is None or (isinstance(value, float) and math.isnan(value)):
8235        return null()
8236    if isinstance(value, numbers.Number):
8237        return Literal.number(value)
8238    if isinstance(value, bytes):
8239        return HexString(this=value.hex())
8240    if isinstance(value, datetime.datetime):
8241        datetime_literal = Literal.string(value.isoformat(sep=" "))
8242
8243        tz = None
8244        if value.tzinfo:
8245            # this works for zoneinfo.ZoneInfo, pytz.timezone and datetime.datetime.utc to return IANA timezone names like "America/Los_Angeles"
8246            # instead of abbreviations like "PDT". This is for consistency with other timezone handling functions in SQLGlot
8247            tz = Literal.string(str(value.tzinfo))
8248
8249        return TimeStrToTime(this=datetime_literal, zone=tz)
8250    if isinstance(value, datetime.date):
8251        date_literal = Literal.string(value.strftime("%Y-%m-%d"))
8252        return DateStrToDate(this=date_literal)
8253    if isinstance(value, tuple):
8254        if hasattr(value, "_fields"):
8255            return Struct(
8256                expressions=[
8257                    PropertyEQ(
8258                        this=to_identifier(k), expression=convert(getattr(value, k), copy=copy)
8259                    )
8260                    for k in value._fields
8261                ]
8262            )
8263        return Tuple(expressions=[convert(v, copy=copy) for v in value])
8264    if isinstance(value, list):
8265        return Array(expressions=[convert(v, copy=copy) for v in value])
8266    if isinstance(value, dict):
8267        return Map(
8268            keys=Array(expressions=[convert(k, copy=copy) for k in value]),
8269            values=Array(expressions=[convert(v, copy=copy) for v in value.values()]),
8270        )
8271    if hasattr(value, "__dict__"):
8272        return Struct(
8273            expressions=[
8274                PropertyEQ(this=to_identifier(k), expression=convert(v, copy=copy))
8275                for k, v in value.__dict__.items()
8276            ]
8277        )
8278    raise ValueError(f"Cannot convert {value}")
8279
8280
8281def replace_children(expression: Expression, fun: t.Callable, *args, **kwargs) -> None:
8282    """
8283    Replace children of an expression with the result of a lambda fun(child) -> exp.
8284    """
8285    for k, v in tuple(expression.args.items()):
8286        is_list_arg = type(v) is list
8287
8288        child_nodes = v if is_list_arg else [v]
8289        new_child_nodes = []
8290
8291        for cn in child_nodes:
8292            if isinstance(cn, Expression):
8293                for child_node in ensure_collection(fun(cn, *args, **kwargs)):
8294                    new_child_nodes.append(child_node)
8295            else:
8296                new_child_nodes.append(cn)
8297
8298        expression.set(k, new_child_nodes if is_list_arg else seq_get(new_child_nodes, 0))
8299
8300
8301def replace_tree(
8302    expression: Expression,
8303    fun: t.Callable,
8304    prune: t.Optional[t.Callable[[Expression], bool]] = None,
8305) -> Expression:
8306    """
8307    Replace an entire tree with the result of function calls on each node.
8308
8309    This will be traversed in reverse dfs, so leaves first.
8310    If new nodes are created as a result of function calls, they will also be traversed.
8311    """
8312    stack = list(expression.dfs(prune=prune))
8313
8314    while stack:
8315        node = stack.pop()
8316        new_node = fun(node)
8317
8318        if new_node is not node:
8319            node.replace(new_node)
8320
8321            if isinstance(new_node, Expression):
8322                stack.append(new_node)
8323
8324    return new_node
8325
8326
8327def column_table_names(expression: Expression, exclude: str = "") -> t.Set[str]:
8328    """
8329    Return all table names referenced through columns in an expression.
8330
8331    Example:
8332        >>> import sqlglot
8333        >>> sorted(column_table_names(sqlglot.parse_one("a.b AND c.d AND c.e")))
8334        ['a', 'c']
8335
8336    Args:
8337        expression: expression to find table names.
8338        exclude: a table name to exclude
8339
8340    Returns:
8341        A list of unique names.
8342    """
8343    return {
8344        table
8345        for table in (column.table for column in expression.find_all(Column))
8346        if table and table != exclude
8347    }
8348
8349
8350def table_name(table: Table | str, dialect: DialectType = None, identify: bool = False) -> str:
8351    """Get the full name of a table as a string.
8352
8353    Args:
8354        table: Table expression node or string.
8355        dialect: The dialect to generate the table name for.
8356        identify: Determines when an identifier should be quoted. Possible values are:
8357            False (default): Never quote, except in cases where it's mandatory by the dialect.
8358            True: Always quote.
8359
8360    Examples:
8361        >>> from sqlglot import exp, parse_one
8362        >>> table_name(parse_one("select * from a.b.c").find(exp.Table))
8363        'a.b.c'
8364
8365    Returns:
8366        The table name.
8367    """
8368
8369    table = maybe_parse(table, into=Table, dialect=dialect)
8370
8371    if not table:
8372        raise ValueError(f"Cannot parse {table}")
8373
8374    return ".".join(
8375        (
8376            part.sql(dialect=dialect, identify=True, copy=False, comments=False)
8377            if identify or not SAFE_IDENTIFIER_RE.match(part.name)
8378            else part.name
8379        )
8380        for part in table.parts
8381    )
8382
8383
8384def normalize_table_name(table: str | Table, dialect: DialectType = None, copy: bool = True) -> str:
8385    """Returns a case normalized table name without quotes.
8386
8387    Args:
8388        table: the table to normalize
8389        dialect: the dialect to use for normalization rules
8390        copy: whether to copy the expression.
8391
8392    Examples:
8393        >>> normalize_table_name("`A-B`.c", dialect="bigquery")
8394        'A-B.c'
8395    """
8396    from sqlglot.optimizer.normalize_identifiers import normalize_identifiers
8397
8398    return ".".join(
8399        p.name
8400        for p in normalize_identifiers(
8401            to_table(table, dialect=dialect, copy=copy), dialect=dialect
8402        ).parts
8403    )
8404
8405
8406def replace_tables(
8407    expression: E, mapping: t.Dict[str, str], dialect: DialectType = None, copy: bool = True
8408) -> E:
8409    """Replace all tables in expression according to the mapping.
8410
8411    Args:
8412        expression: expression node to be transformed and replaced.
8413        mapping: mapping of table names.
8414        dialect: the dialect of the mapping table
8415        copy: whether to copy the expression.
8416
8417    Examples:
8418        >>> from sqlglot import exp, parse_one
8419        >>> replace_tables(parse_one("select * from a.b"), {"a.b": "c"}).sql()
8420        'SELECT * FROM c /* a.b */'
8421
8422    Returns:
8423        The mapped expression.
8424    """
8425
8426    mapping = {normalize_table_name(k, dialect=dialect): v for k, v in mapping.items()}
8427
8428    def _replace_tables(node: Expression) -> Expression:
8429        if isinstance(node, Table) and node.meta.get("replace") is not False:
8430            original = normalize_table_name(node, dialect=dialect)
8431            new_name = mapping.get(original)
8432
8433            if new_name:
8434                table = to_table(
8435                    new_name,
8436                    **{k: v for k, v in node.args.items() if k not in TABLE_PARTS},
8437                    dialect=dialect,
8438                )
8439                table.add_comments([original])
8440                return table
8441        return node
8442
8443    return expression.transform(_replace_tables, copy=copy)  # type: ignore
8444
8445
8446def replace_placeholders(expression: Expression, *args, **kwargs) -> Expression:
8447    """Replace placeholders in an expression.
8448
8449    Args:
8450        expression: expression node to be transformed and replaced.
8451        args: positional names that will substitute unnamed placeholders in the given order.
8452        kwargs: keyword arguments that will substitute named placeholders.
8453
8454    Examples:
8455        >>> from sqlglot import exp, parse_one
8456        >>> replace_placeholders(
8457        ...     parse_one("select * from :tbl where ? = ?"),
8458        ...     exp.to_identifier("str_col"), "b", tbl=exp.to_identifier("foo")
8459        ... ).sql()
8460        "SELECT * FROM foo WHERE str_col = 'b'"
8461
8462    Returns:
8463        The mapped expression.
8464    """
8465
8466    def _replace_placeholders(node: Expression, args, **kwargs) -> Expression:
8467        if isinstance(node, Placeholder):
8468            if node.this:
8469                new_name = kwargs.get(node.this)
8470                if new_name is not None:
8471                    return convert(new_name)
8472            else:
8473                try:
8474                    return convert(next(args))
8475                except StopIteration:
8476                    pass
8477        return node
8478
8479    return expression.transform(_replace_placeholders, iter(args), **kwargs)
8480
8481
8482def expand(
8483    expression: Expression,
8484    sources: t.Dict[str, Query],
8485    dialect: DialectType = None,
8486    copy: bool = True,
8487) -> Expression:
8488    """Transforms an expression by expanding all referenced sources into subqueries.
8489
8490    Examples:
8491        >>> from sqlglot import parse_one
8492        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y")}).sql()
8493        'SELECT * FROM (SELECT * FROM y) AS z /* source: x */'
8494
8495        >>> expand(parse_one("select * from x AS z"), {"x": parse_one("select * from y"), "y": parse_one("select * from z")}).sql()
8496        'SELECT * FROM (SELECT * FROM (SELECT * FROM z) AS y /* source: y */) AS z /* source: x */'
8497
8498    Args:
8499        expression: The expression to expand.
8500        sources: A dictionary of name to Queries.
8501        dialect: The dialect of the sources dict.
8502        copy: Whether to copy the expression during transformation. Defaults to True.
8503
8504    Returns:
8505        The transformed expression.
8506    """
8507    sources = {normalize_table_name(k, dialect=dialect): v for k, v in sources.items()}
8508
8509    def _expand(node: Expression):
8510        if isinstance(node, Table):
8511            name = normalize_table_name(node, dialect=dialect)
8512            source = sources.get(name)
8513            if source:
8514                subquery = source.subquery(node.alias or name)
8515                subquery.comments = [f"source: {name}"]
8516                return subquery.transform(_expand, copy=False)
8517        return node
8518
8519    return expression.transform(_expand, copy=copy)
8520
8521
8522def func(name: str, *args, copy: bool = True, dialect: DialectType = None, **kwargs) -> Func:
8523    """
8524    Returns a Func expression.
8525
8526    Examples:
8527        >>> func("abs", 5).sql()
8528        'ABS(5)'
8529
8530        >>> func("cast", this=5, to=DataType.build("DOUBLE")).sql()
8531        'CAST(5 AS DOUBLE)'
8532
8533    Args:
8534        name: the name of the function to build.
8535        args: the args used to instantiate the function of interest.
8536        copy: whether to copy the argument expressions.
8537        dialect: the source dialect.
8538        kwargs: the kwargs used to instantiate the function of interest.
8539
8540    Note:
8541        The arguments `args` and `kwargs` are mutually exclusive.
8542
8543    Returns:
8544        An instance of the function of interest, or an anonymous function, if `name` doesn't
8545        correspond to an existing `sqlglot.expressions.Func` class.
8546    """
8547    if args and kwargs:
8548        raise ValueError("Can't use both args and kwargs to instantiate a function.")
8549
8550    from sqlglot.dialects.dialect import Dialect
8551
8552    dialect = Dialect.get_or_raise(dialect)
8553
8554    converted: t.List[Expression] = [maybe_parse(arg, dialect=dialect, copy=copy) for arg in args]
8555    kwargs = {key: maybe_parse(value, dialect=dialect, copy=copy) for key, value in kwargs.items()}
8556
8557    constructor = dialect.parser_class.FUNCTIONS.get(name.upper())
8558    if constructor:
8559        if converted:
8560            if "dialect" in constructor.__code__.co_varnames:
8561                function = constructor(converted, dialect=dialect)
8562            else:
8563                function = constructor(converted)
8564        elif constructor.__name__ == "from_arg_list":
8565            function = constructor.__self__(**kwargs)  # type: ignore
8566        else:
8567            constructor = FUNCTION_BY_NAME.get(name.upper())
8568            if constructor:
8569                function = constructor(**kwargs)
8570            else:
8571                raise ValueError(
8572                    f"Unable to convert '{name}' into a Func. Either manually construct "
8573                    "the Func expression of interest or parse the function call."
8574                )
8575    else:
8576        kwargs = kwargs or {"expressions": converted}
8577        function = Anonymous(this=name, **kwargs)
8578
8579    for error_message in function.error_messages(converted):
8580        raise ValueError(error_message)
8581
8582    return function
8583
8584
8585def case(
8586    expression: t.Optional[ExpOrStr] = None,
8587    **opts,
8588) -> Case:
8589    """
8590    Initialize a CASE statement.
8591
8592    Example:
8593        case().when("a = 1", "foo").else_("bar")
8594
8595    Args:
8596        expression: Optionally, the input expression (not all dialects support this)
8597        **opts: Extra keyword arguments for parsing `expression`
8598    """
8599    if expression is not None:
8600        this = maybe_parse(expression, **opts)
8601    else:
8602        this = None
8603    return Case(this=this, ifs=[])
8604
8605
8606def array(
8607    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8608) -> Array:
8609    """
8610    Returns an array.
8611
8612    Examples:
8613        >>> array(1, 'x').sql()
8614        'ARRAY(1, x)'
8615
8616    Args:
8617        expressions: the expressions to add to the array.
8618        copy: whether to copy the argument expressions.
8619        dialect: the source dialect.
8620        kwargs: the kwargs used to instantiate the function of interest.
8621
8622    Returns:
8623        An array expression.
8624    """
8625    return Array(
8626        expressions=[
8627            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8628            for expression in expressions
8629        ]
8630    )
8631
8632
8633def tuple_(
8634    *expressions: ExpOrStr, copy: bool = True, dialect: DialectType = None, **kwargs
8635) -> Tuple:
8636    """
8637    Returns an tuple.
8638
8639    Examples:
8640        >>> tuple_(1, 'x').sql()
8641        '(1, x)'
8642
8643    Args:
8644        expressions: the expressions to add to the tuple.
8645        copy: whether to copy the argument expressions.
8646        dialect: the source dialect.
8647        kwargs: the kwargs used to instantiate the function of interest.
8648
8649    Returns:
8650        A tuple expression.
8651    """
8652    return Tuple(
8653        expressions=[
8654            maybe_parse(expression, copy=copy, dialect=dialect, **kwargs)
8655            for expression in expressions
8656        ]
8657    )
8658
8659
8660def true() -> Boolean:
8661    """
8662    Returns a true Boolean expression.
8663    """
8664    return Boolean(this=True)
8665
8666
8667def false() -> Boolean:
8668    """
8669    Returns a false Boolean expression.
8670    """
8671    return Boolean(this=False)
8672
8673
8674def null() -> Null:
8675    """
8676    Returns a Null expression.
8677    """
8678    return Null()
8679
8680
8681NONNULL_CONSTANTS = (
8682    Literal,
8683    Boolean,
8684)
8685
8686CONSTANTS = (
8687    Literal,
8688    Boolean,
8689    Null,
8690)
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        "visible": False,
1708    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False, 'visible': False}
key = 'altercolumn'
class AlterIndex(Expression):
1712class AlterIndex(Expression):
1713    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
class AlterDistStyle(Expression):
1717class AlterDistStyle(Expression):
1718    pass
key = 'alterdiststyle'
class AlterSortKey(Expression):
1721class AlterSortKey(Expression):
1722    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
class AlterSet(Expression):
1725class AlterSet(Expression):
1726    arg_types = {
1727        "expressions": False,
1728        "option": False,
1729        "tablespace": False,
1730        "access_method": False,
1731        "file_format": False,
1732        "copy_options": False,
1733        "tag": False,
1734        "location": False,
1735        "serde": False,
1736    }
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):
1739class RenameColumn(Expression):
1740    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
class AlterRename(Expression):
1743class AlterRename(Expression):
1744    pass
key = 'alterrename'
class SwapTable(Expression):
1747class SwapTable(Expression):
1748    pass
key = 'swaptable'
class Comment(Expression):
1751class Comment(Expression):
1752    arg_types = {
1753        "this": True,
1754        "kind": True,
1755        "expression": True,
1756        "exists": False,
1757        "materialized": False,
1758    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
class Comprehension(Expression):
1761class Comprehension(Expression):
1762    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):
1766class MergeTreeTTLAction(Expression):
1767    arg_types = {
1768        "this": True,
1769        "delete": False,
1770        "recompress": False,
1771        "to_disk": False,
1772        "to_volume": False,
1773    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
class MergeTreeTTL(Expression):
1777class MergeTreeTTL(Expression):
1778    arg_types = {
1779        "expressions": True,
1780        "where": False,
1781        "group": False,
1782        "aggregates": False,
1783    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
class IndexConstraintOption(Expression):
1787class IndexConstraintOption(Expression):
1788    arg_types = {
1789        "key_block_size": False,
1790        "using": False,
1791        "parser": False,
1792        "comment": False,
1793        "visible": False,
1794        "engine_attr": False,
1795        "secondary_engine_attr": False,
1796    }
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):
1799class ColumnConstraint(Expression):
1800    arg_types = {"this": False, "kind": True}
1801
1802    @property
1803    def kind(self) -> ColumnConstraintKind:
1804        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1802    @property
1803    def kind(self) -> ColumnConstraintKind:
1804        return self.args["kind"]
key = 'columnconstraint'
class ColumnConstraintKind(Expression):
1807class ColumnConstraintKind(Expression):
1808    pass
key = 'columnconstraintkind'
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1811class AutoIncrementColumnConstraint(ColumnConstraintKind):
1812    pass
key = 'autoincrementcolumnconstraint'
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1815class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1816    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1819class CaseSpecificColumnConstraint(ColumnConstraintKind):
1820    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
class CharacterSetColumnConstraint(ColumnConstraintKind):
1823class CharacterSetColumnConstraint(ColumnConstraintKind):
1824    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
class CheckColumnConstraint(ColumnConstraintKind):
1827class CheckColumnConstraint(ColumnConstraintKind):
1828    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
class ClusteredColumnConstraint(ColumnConstraintKind):
1831class ClusteredColumnConstraint(ColumnConstraintKind):
1832    pass
key = 'clusteredcolumnconstraint'
class CollateColumnConstraint(ColumnConstraintKind):
1835class CollateColumnConstraint(ColumnConstraintKind):
1836    pass
key = 'collatecolumnconstraint'
class CommentColumnConstraint(ColumnConstraintKind):
1839class CommentColumnConstraint(ColumnConstraintKind):
1840    pass
key = 'commentcolumnconstraint'
class CompressColumnConstraint(ColumnConstraintKind):
1843class CompressColumnConstraint(ColumnConstraintKind):
1844    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
class DateFormatColumnConstraint(ColumnConstraintKind):
1847class DateFormatColumnConstraint(ColumnConstraintKind):
1848    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
class DefaultColumnConstraint(ColumnConstraintKind):
1851class DefaultColumnConstraint(ColumnConstraintKind):
1852    pass
key = 'defaultcolumnconstraint'
class EncodeColumnConstraint(ColumnConstraintKind):
1855class EncodeColumnConstraint(ColumnConstraintKind):
1856    pass
key = 'encodecolumnconstraint'
class ExcludeColumnConstraint(ColumnConstraintKind):
1860class ExcludeColumnConstraint(ColumnConstraintKind):
1861    pass
key = 'excludecolumnconstraint'
class EphemeralColumnConstraint(ColumnConstraintKind):
1864class EphemeralColumnConstraint(ColumnConstraintKind):
1865    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
class WithOperator(Expression):
1868class WithOperator(Expression):
1869    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1872class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1873    # this: True -> ALWAYS, this: False -> BY DEFAULT
1874    arg_types = {
1875        "this": False,
1876        "expression": False,
1877        "on_null": False,
1878        "start": False,
1879        "increment": False,
1880        "minvalue": False,
1881        "maxvalue": False,
1882        "cycle": False,
1883    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False}
key = 'generatedasidentitycolumnconstraint'
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1886class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1887    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
class IndexColumnConstraint(ColumnConstraintKind):
1892class IndexColumnConstraint(ColumnConstraintKind):
1893    arg_types = {
1894        "this": False,
1895        "expressions": False,
1896        "kind": False,
1897        "index_type": False,
1898        "options": False,
1899        "expression": False,  # Clickhouse
1900        "granularity": False,
1901    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
class InlineLengthColumnConstraint(ColumnConstraintKind):
1904class InlineLengthColumnConstraint(ColumnConstraintKind):
1905    pass
key = 'inlinelengthcolumnconstraint'
class NonClusteredColumnConstraint(ColumnConstraintKind):
1908class NonClusteredColumnConstraint(ColumnConstraintKind):
1909    pass
key = 'nonclusteredcolumnconstraint'
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1912class NotForReplicationColumnConstraint(ColumnConstraintKind):
1913    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1917class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1918    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
class NotNullColumnConstraint(ColumnConstraintKind):
1921class NotNullColumnConstraint(ColumnConstraintKind):
1922    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
class OnUpdateColumnConstraint(ColumnConstraintKind):
1926class OnUpdateColumnConstraint(ColumnConstraintKind):
1927    pass
key = 'onupdatecolumnconstraint'
class TransformColumnConstraint(ColumnConstraintKind):
1931class TransformColumnConstraint(ColumnConstraintKind):
1932    pass
key = 'transformcolumnconstraint'
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1935class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1936    arg_types = {"desc": False}
arg_types = {'desc': False}
key = 'primarykeycolumnconstraint'
class TitleColumnConstraint(ColumnConstraintKind):
1939class TitleColumnConstraint(ColumnConstraintKind):
1940    pass
key = 'titlecolumnconstraint'
class UniqueColumnConstraint(ColumnConstraintKind):
1943class UniqueColumnConstraint(ColumnConstraintKind):
1944    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):
1947class UppercaseColumnConstraint(ColumnConstraintKind):
1948    arg_types: t.Dict[str, t.Any] = {}
arg_types: Dict[str, Any] = {}
key = 'uppercasecolumnconstraint'
class WatermarkColumnConstraint(Expression):
1952class WatermarkColumnConstraint(Expression):
1953    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
class PathColumnConstraint(ColumnConstraintKind):
1956class PathColumnConstraint(ColumnConstraintKind):
1957    pass
key = 'pathcolumnconstraint'
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1961class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1962    pass
key = 'projectionpolicycolumnconstraint'
class ComputedColumnConstraint(ColumnConstraintKind):
1967class ComputedColumnConstraint(ColumnConstraintKind):
1968    arg_types = {"this": True, "persisted": False, "not_null": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False}
key = 'computedcolumnconstraint'
class Constraint(Expression):
1971class Constraint(Expression):
1972    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
class Delete(DML):
1975class Delete(DML):
1976    arg_types = {
1977        "with": False,
1978        "this": False,
1979        "using": False,
1980        "where": False,
1981        "returning": False,
1982        "limit": False,
1983        "tables": False,  # Multiple-Table Syntax (MySQL)
1984        "cluster": False,  # Clickhouse
1985    }
1986
1987    def delete(
1988        self,
1989        table: ExpOrStr,
1990        dialect: DialectType = None,
1991        copy: bool = True,
1992        **opts,
1993    ) -> Delete:
1994        """
1995        Create a DELETE expression or replace the table on an existing DELETE expression.
1996
1997        Example:
1998            >>> delete("tbl").sql()
1999            'DELETE FROM tbl'
2000
2001        Args:
2002            table: the table from which to delete.
2003            dialect: the dialect used to parse the input expression.
2004            copy: if `False`, modify this expression instance in-place.
2005            opts: other options to use to parse the input expressions.
2006
2007        Returns:
2008            Delete: the modified expression.
2009        """
2010        return _apply_builder(
2011            expression=table,
2012            instance=self,
2013            arg="this",
2014            dialect=dialect,
2015            into=Table,
2016            copy=copy,
2017            **opts,
2018        )
2019
2020    def where(
2021        self,
2022        *expressions: t.Optional[ExpOrStr],
2023        append: bool = True,
2024        dialect: DialectType = None,
2025        copy: bool = True,
2026        **opts,
2027    ) -> Delete:
2028        """
2029        Append to or set the WHERE expressions.
2030
2031        Example:
2032            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
2033            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
2034
2035        Args:
2036            *expressions: the SQL code strings to parse.
2037                If an `Expression` instance is passed, it will be used as-is.
2038                Multiple expressions are combined with an AND operator.
2039            append: if `True`, AND the new expressions to any existing expression.
2040                Otherwise, this resets the expression.
2041            dialect: the dialect used to parse the input expressions.
2042            copy: if `False`, modify this expression instance in-place.
2043            opts: other options to use to parse the input expressions.
2044
2045        Returns:
2046            Delete: the modified expression.
2047        """
2048        return _apply_conjunction_builder(
2049            *expressions,
2050            instance=self,
2051            arg="where",
2052            append=append,
2053            into=Where,
2054            dialect=dialect,
2055            copy=copy,
2056            **opts,
2057        )
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:
1987    def delete(
1988        self,
1989        table: ExpOrStr,
1990        dialect: DialectType = None,
1991        copy: bool = True,
1992        **opts,
1993    ) -> Delete:
1994        """
1995        Create a DELETE expression or replace the table on an existing DELETE expression.
1996
1997        Example:
1998            >>> delete("tbl").sql()
1999            'DELETE FROM tbl'
2000
2001        Args:
2002            table: the table from which to delete.
2003            dialect: the dialect used to parse the input expression.
2004            copy: if `False`, modify this expression instance in-place.
2005            opts: other options to use to parse the input expressions.
2006
2007        Returns:
2008            Delete: the modified expression.
2009        """
2010        return _apply_builder(
2011            expression=table,
2012            instance=self,
2013            arg="this",
2014            dialect=dialect,
2015            into=Table,
2016            copy=copy,
2017            **opts,
2018        )

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

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

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

Returns a Python object equivalent of the SQL node.

key = 'literal'
class Join(Expression):
2454class Join(Expression):
2455    arg_types = {
2456        "this": True,
2457        "on": False,
2458        "side": False,
2459        "kind": False,
2460        "using": False,
2461        "method": False,
2462        "global": False,
2463        "hint": False,
2464        "match_condition": False,  # Snowflake
2465        "expressions": False,
2466    }
2467
2468    @property
2469    def method(self) -> str:
2470        return self.text("method").upper()
2471
2472    @property
2473    def kind(self) -> str:
2474        return self.text("kind").upper()
2475
2476    @property
2477    def side(self) -> str:
2478        return self.text("side").upper()
2479
2480    @property
2481    def hint(self) -> str:
2482        return self.text("hint").upper()
2483
2484    @property
2485    def alias_or_name(self) -> str:
2486        return self.this.alias_or_name
2487
2488    @property
2489    def is_semi_or_anti_join(self) -> bool:
2490        return self.kind in ("SEMI", "ANTI")
2491
2492    def on(
2493        self,
2494        *expressions: t.Optional[ExpOrStr],
2495        append: bool = True,
2496        dialect: DialectType = None,
2497        copy: bool = True,
2498        **opts,
2499    ) -> Join:
2500        """
2501        Append to or set the ON expressions.
2502
2503        Example:
2504            >>> import sqlglot
2505            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2506            'JOIN x ON y = 1'
2507
2508        Args:
2509            *expressions: the SQL code strings to parse.
2510                If an `Expression` instance is passed, it will be used as-is.
2511                Multiple expressions are combined with an AND operator.
2512            append: if `True`, AND the new expressions to any existing expression.
2513                Otherwise, this resets the expression.
2514            dialect: the dialect used to parse the input expressions.
2515            copy: if `False`, modify this expression instance in-place.
2516            opts: other options to use to parse the input expressions.
2517
2518        Returns:
2519            The modified Join expression.
2520        """
2521        join = _apply_conjunction_builder(
2522            *expressions,
2523            instance=self,
2524            arg="on",
2525            append=append,
2526            dialect=dialect,
2527            copy=copy,
2528            **opts,
2529        )
2530
2531        if join.kind == "CROSS":
2532            join.set("kind", None)
2533
2534        return join
2535
2536    def using(
2537        self,
2538        *expressions: t.Optional[ExpOrStr],
2539        append: bool = True,
2540        dialect: DialectType = None,
2541        copy: bool = True,
2542        **opts,
2543    ) -> Join:
2544        """
2545        Append to or set the USING expressions.
2546
2547        Example:
2548            >>> import sqlglot
2549            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2550            'JOIN x USING (foo, bla)'
2551
2552        Args:
2553            *expressions: the SQL code strings to parse.
2554                If an `Expression` instance is passed, it will be used as-is.
2555            append: if `True`, concatenate the new expressions to the existing "using" list.
2556                Otherwise, this resets the expression.
2557            dialect: the dialect used to parse the input expressions.
2558            copy: if `False`, modify this expression instance in-place.
2559            opts: other options to use to parse the input expressions.
2560
2561        Returns:
2562            The modified Join expression.
2563        """
2564        join = _apply_list_builder(
2565            *expressions,
2566            instance=self,
2567            arg="using",
2568            append=append,
2569            dialect=dialect,
2570            copy=copy,
2571            **opts,
2572        )
2573
2574        if join.kind == "CROSS":
2575            join.set("kind", None)
2576
2577        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
2468    @property
2469    def method(self) -> str:
2470        return self.text("method").upper()
kind: str
2472    @property
2473    def kind(self) -> str:
2474        return self.text("kind").upper()
side: str
2476    @property
2477    def side(self) -> str:
2478        return self.text("side").upper()
hint: str
2480    @property
2481    def hint(self) -> str:
2482        return self.text("hint").upper()
alias_or_name: str
2484    @property
2485    def alias_or_name(self) -> str:
2486        return self.this.alias_or_name
is_semi_or_anti_join: bool
2488    @property
2489    def is_semi_or_anti_join(self) -> bool:
2490        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:
2492    def on(
2493        self,
2494        *expressions: t.Optional[ExpOrStr],
2495        append: bool = True,
2496        dialect: DialectType = None,
2497        copy: bool = True,
2498        **opts,
2499    ) -> Join:
2500        """
2501        Append to or set the ON expressions.
2502
2503        Example:
2504            >>> import sqlglot
2505            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2506            'JOIN x ON y = 1'
2507
2508        Args:
2509            *expressions: the SQL code strings to parse.
2510                If an `Expression` instance is passed, it will be used as-is.
2511                Multiple expressions are combined with an AND operator.
2512            append: if `True`, AND the new expressions to any existing expression.
2513                Otherwise, this resets the expression.
2514            dialect: the dialect used to parse the input expressions.
2515            copy: if `False`, modify this expression instance in-place.
2516            opts: other options to use to parse the input expressions.
2517
2518        Returns:
2519            The modified Join expression.
2520        """
2521        join = _apply_conjunction_builder(
2522            *expressions,
2523            instance=self,
2524            arg="on",
2525            append=append,
2526            dialect=dialect,
2527            copy=copy,
2528            **opts,
2529        )
2530
2531        if join.kind == "CROSS":
2532            join.set("kind", None)
2533
2534        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:
2536    def using(
2537        self,
2538        *expressions: t.Optional[ExpOrStr],
2539        append: bool = True,
2540        dialect: DialectType = None,
2541        copy: bool = True,
2542        **opts,
2543    ) -> Join:
2544        """
2545        Append to or set the USING expressions.
2546
2547        Example:
2548            >>> import sqlglot
2549            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2550            'JOIN x USING (foo, bla)'
2551
2552        Args:
2553            *expressions: the SQL code strings to parse.
2554                If an `Expression` instance is passed, it will be used as-is.
2555            append: if `True`, concatenate the new expressions to the existing "using" list.
2556                Otherwise, this resets the expression.
2557            dialect: the dialect used to parse the input expressions.
2558            copy: if `False`, modify this expression instance in-place.
2559            opts: other options to use to parse the input expressions.
2560
2561        Returns:
2562            The modified Join expression.
2563        """
2564        join = _apply_list_builder(
2565            *expressions,
2566            instance=self,
2567            arg="using",
2568            append=append,
2569            dialect=dialect,
2570            copy=copy,
2571            **opts,
2572        )
2573
2574        if join.kind == "CROSS":
2575            join.set("kind", None)
2576
2577        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):
2580class Lateral(UDTF):
2581    arg_types = {
2582        "this": True,
2583        "view": False,
2584        "outer": False,
2585        "alias": False,
2586        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2587    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False}
key = 'lateral'
class MatchRecognizeMeasure(Expression):
2590class MatchRecognizeMeasure(Expression):
2591    arg_types = {
2592        "this": True,
2593        "window_frame": False,
2594    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
class MatchRecognize(Expression):
2597class MatchRecognize(Expression):
2598    arg_types = {
2599        "partition_by": False,
2600        "order": False,
2601        "measures": False,
2602        "rows": False,
2603        "after": False,
2604        "pattern": False,
2605        "define": False,
2606        "alias": False,
2607    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
class Final(Expression):
2612class Final(Expression):
2613    pass
key = 'final'
class Offset(Expression):
2616class Offset(Expression):
2617    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
class Order(Expression):
2620class Order(Expression):
2621    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
class WithFill(Expression):
2625class WithFill(Expression):
2626    arg_types = {
2627        "from": False,
2628        "to": False,
2629        "step": False,
2630        "interpolate": False,
2631    }
arg_types = {'from': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
class Cluster(Order):
2636class Cluster(Order):
2637    pass
key = 'cluster'
class Distribute(Order):
2640class Distribute(Order):
2641    pass
key = 'distribute'
class Sort(Order):
2644class Sort(Order):
2645    pass
key = 'sort'
class Ordered(Expression):
2648class Ordered(Expression):
2649    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):
2652class Property(Expression):
2653    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
class GrantPrivilege(Expression):
2656class GrantPrivilege(Expression):
2657    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
class GrantPrincipal(Expression):
2660class GrantPrincipal(Expression):
2661    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
class AllowedValuesProperty(Expression):
2664class AllowedValuesProperty(Expression):
2665    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
class AlgorithmProperty(Property):
2668class AlgorithmProperty(Property):
2669    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
class AutoIncrementProperty(Property):
2672class AutoIncrementProperty(Property):
2673    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autoincrementproperty'
class AutoRefreshProperty(Property):
2677class AutoRefreshProperty(Property):
2678    arg_types = {"this": True}
arg_types = {'this': True}
key = 'autorefreshproperty'
class BackupProperty(Property):
2681class BackupProperty(Property):
2682    arg_types = {"this": True}
arg_types = {'this': True}
key = 'backupproperty'
class BlockCompressionProperty(Property):
2685class BlockCompressionProperty(Property):
2686    arg_types = {
2687        "autotemp": False,
2688        "always": False,
2689        "default": False,
2690        "manual": False,
2691        "never": False,
2692    }
arg_types = {'autotemp': False, 'always': False, 'default': False, 'manual': False, 'never': False}
key = 'blockcompressionproperty'
class CharacterSetProperty(Property):
2695class CharacterSetProperty(Property):
2696    arg_types = {"this": True, "default": True}
arg_types = {'this': True, 'default': True}
key = 'charactersetproperty'
class ChecksumProperty(Property):
2699class ChecksumProperty(Property):
2700    arg_types = {"on": False, "default": False}
arg_types = {'on': False, 'default': False}
key = 'checksumproperty'
class CollateProperty(Property):
2703class CollateProperty(Property):
2704    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'collateproperty'
class CopyGrantsProperty(Property):
2707class CopyGrantsProperty(Property):
2708    arg_types = {}
arg_types = {}
key = 'copygrantsproperty'
class DataBlocksizeProperty(Property):
2711class DataBlocksizeProperty(Property):
2712    arg_types = {
2713        "size": False,
2714        "units": False,
2715        "minimum": False,
2716        "maximum": False,
2717        "default": False,
2718    }
arg_types = {'size': False, 'units': False, 'minimum': False, 'maximum': False, 'default': False}
key = 'datablocksizeproperty'
class DataDeletionProperty(Property):
2721class DataDeletionProperty(Property):
2722    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):
2725class DefinerProperty(Property):
2726    arg_types = {"this": True}
arg_types = {'this': True}
key = 'definerproperty'
class DistKeyProperty(Property):
2729class DistKeyProperty(Property):
2730    arg_types = {"this": True}
arg_types = {'this': True}
key = 'distkeyproperty'
class DistributedByProperty(Property):
2735class DistributedByProperty(Property):
2736    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):
2739class DistStyleProperty(Property):
2740    arg_types = {"this": True}
arg_types = {'this': True}
key = 'diststyleproperty'
class DuplicateKeyProperty(Property):
2743class DuplicateKeyProperty(Property):
2744    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'duplicatekeyproperty'
class EngineProperty(Property):
2747class EngineProperty(Property):
2748    arg_types = {"this": True}
arg_types = {'this': True}
key = 'engineproperty'
class HeapProperty(Property):
2751class HeapProperty(Property):
2752    arg_types = {}
arg_types = {}
key = 'heapproperty'
class ToTableProperty(Property):
2755class ToTableProperty(Property):
2756    arg_types = {"this": True}
arg_types = {'this': True}
key = 'totableproperty'
class ExecuteAsProperty(Property):
2759class ExecuteAsProperty(Property):
2760    arg_types = {"this": True}
arg_types = {'this': True}
key = 'executeasproperty'
class ExternalProperty(Property):
2763class ExternalProperty(Property):
2764    arg_types = {"this": False}
arg_types = {'this': False}
key = 'externalproperty'
class FallbackProperty(Property):
2767class FallbackProperty(Property):
2768    arg_types = {"no": True, "protection": False}
arg_types = {'no': True, 'protection': False}
key = 'fallbackproperty'
class FileFormatProperty(Property):
2771class FileFormatProperty(Property):
2772    arg_types = {"this": True}
arg_types = {'this': True}
key = 'fileformatproperty'
class FreespaceProperty(Property):
2775class FreespaceProperty(Property):
2776    arg_types = {"this": True, "percent": False}
arg_types = {'this': True, 'percent': False}
key = 'freespaceproperty'
class GlobalProperty(Property):
2779class GlobalProperty(Property):
2780    arg_types = {}
arg_types = {}
key = 'globalproperty'
class IcebergProperty(Property):
2783class IcebergProperty(Property):
2784    arg_types = {}
arg_types = {}
key = 'icebergproperty'
class InheritsProperty(Property):
2787class InheritsProperty(Property):
2788    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'inheritsproperty'
class InputModelProperty(Property):
2791class InputModelProperty(Property):
2792    arg_types = {"this": True}
arg_types = {'this': True}
key = 'inputmodelproperty'
class OutputModelProperty(Property):
2795class OutputModelProperty(Property):
2796    arg_types = {"this": True}
arg_types = {'this': True}
key = 'outputmodelproperty'
class IsolatedLoadingProperty(Property):
2799class IsolatedLoadingProperty(Property):
2800    arg_types = {"no": False, "concurrent": False, "target": False}
arg_types = {'no': False, 'concurrent': False, 'target': False}
key = 'isolatedloadingproperty'
class JournalProperty(Property):
2803class JournalProperty(Property):
2804    arg_types = {
2805        "no": False,
2806        "dual": False,
2807        "before": False,
2808        "local": False,
2809        "after": False,
2810    }
arg_types = {'no': False, 'dual': False, 'before': False, 'local': False, 'after': False}
key = 'journalproperty'
class LanguageProperty(Property):
2813class LanguageProperty(Property):
2814    arg_types = {"this": True}
arg_types = {'this': True}
key = 'languageproperty'
class ClusteredByProperty(Property):
2818class ClusteredByProperty(Property):
2819    arg_types = {"expressions": True, "sorted_by": False, "buckets": True}
arg_types = {'expressions': True, 'sorted_by': False, 'buckets': True}
key = 'clusteredbyproperty'
class DictProperty(Property):
2822class DictProperty(Property):
2823    arg_types = {"this": True, "kind": True, "settings": False}
arg_types = {'this': True, 'kind': True, 'settings': False}
key = 'dictproperty'
class DictSubProperty(Property):
2826class DictSubProperty(Property):
2827    pass
key = 'dictsubproperty'
class DictRange(Property):
2830class DictRange(Property):
2831    arg_types = {"this": True, "min": True, "max": True}
arg_types = {'this': True, 'min': True, 'max': True}
key = 'dictrange'
class DynamicProperty(Property):
2834class DynamicProperty(Property):
2835    arg_types = {}
arg_types = {}
key = 'dynamicproperty'
class OnCluster(Property):
2840class OnCluster(Property):
2841    arg_types = {"this": True}
arg_types = {'this': True}
key = 'oncluster'
class EmptyProperty(Property):
2845class EmptyProperty(Property):
2846    arg_types = {}
arg_types = {}
key = 'emptyproperty'
class LikeProperty(Property):
2849class LikeProperty(Property):
2850    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'likeproperty'
class LocationProperty(Property):
2853class LocationProperty(Property):
2854    arg_types = {"this": True}
arg_types = {'this': True}
key = 'locationproperty'
class LockProperty(Property):
2857class LockProperty(Property):
2858    arg_types = {"this": True}
arg_types = {'this': True}
key = 'lockproperty'
class LockingProperty(Property):
2861class LockingProperty(Property):
2862    arg_types = {
2863        "this": False,
2864        "kind": True,
2865        "for_or_in": False,
2866        "lock_type": True,
2867        "override": False,
2868    }
arg_types = {'this': False, 'kind': True, 'for_or_in': False, 'lock_type': True, 'override': False}
key = 'lockingproperty'
class LogProperty(Property):
2871class LogProperty(Property):
2872    arg_types = {"no": True}
arg_types = {'no': True}
key = 'logproperty'
class MaterializedProperty(Property):
2875class MaterializedProperty(Property):
2876    arg_types = {"this": False}
arg_types = {'this': False}
key = 'materializedproperty'
class MergeBlockRatioProperty(Property):
2879class MergeBlockRatioProperty(Property):
2880    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):
2883class NoPrimaryIndexProperty(Property):
2884    arg_types = {}
arg_types = {}
key = 'noprimaryindexproperty'
class OnProperty(Property):
2887class OnProperty(Property):
2888    arg_types = {"this": True}
arg_types = {'this': True}
key = 'onproperty'
class OnCommitProperty(Property):
2891class OnCommitProperty(Property):
2892    arg_types = {"delete": False}
arg_types = {'delete': False}
key = 'oncommitproperty'
class PartitionedByProperty(Property):
2895class PartitionedByProperty(Property):
2896    arg_types = {"this": True}
arg_types = {'this': True}
key = 'partitionedbyproperty'
class PartitionByRangeProperty(Property):
2900class PartitionByRangeProperty(Property):
2901    arg_types = {"partition_expressions": True, "create_expressions": True}
arg_types = {'partition_expressions': True, 'create_expressions': True}
key = 'partitionbyrangeproperty'
class PartitionByRangePropertyDynamic(Expression):
2905class PartitionByRangePropertyDynamic(Expression):
2906    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):
2910class UniqueKeyProperty(Property):
2911    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'uniquekeyproperty'
class PartitionBoundSpec(Expression):
2915class PartitionBoundSpec(Expression):
2916    # this -> IN / MODULUS, expression -> REMAINDER, from_expressions -> FROM (...), to_expressions -> TO (...)
2917    arg_types = {
2918        "this": False,
2919        "expression": False,
2920        "from_expressions": False,
2921        "to_expressions": False,
2922    }
arg_types = {'this': False, 'expression': False, 'from_expressions': False, 'to_expressions': False}
key = 'partitionboundspec'
class PartitionedOfProperty(Property):
2925class PartitionedOfProperty(Property):
2926    # this -> parent_table (schema), expression -> FOR VALUES ... / DEFAULT
2927    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'partitionedofproperty'
class StreamingTableProperty(Property):
2930class StreamingTableProperty(Property):
2931    arg_types = {}
arg_types = {}
key = 'streamingtableproperty'
class RemoteWithConnectionModelProperty(Property):
2934class RemoteWithConnectionModelProperty(Property):
2935    arg_types = {"this": True}
arg_types = {'this': True}
key = 'remotewithconnectionmodelproperty'
class ReturnsProperty(Property):
2938class ReturnsProperty(Property):
2939    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):
2942class StrictProperty(Property):
2943    arg_types = {}
arg_types = {}
key = 'strictproperty'
class RowFormatProperty(Property):
2946class RowFormatProperty(Property):
2947    arg_types = {"this": True}
arg_types = {'this': True}
key = 'rowformatproperty'
class RowFormatDelimitedProperty(Property):
2950class RowFormatDelimitedProperty(Property):
2951    # https://cwiki.apache.org/confluence/display/hive/languagemanual+dml
2952    arg_types = {
2953        "fields": False,
2954        "escaped": False,
2955        "collection_items": False,
2956        "map_keys": False,
2957        "lines": False,
2958        "null": False,
2959        "serde": False,
2960    }
arg_types = {'fields': False, 'escaped': False, 'collection_items': False, 'map_keys': False, 'lines': False, 'null': False, 'serde': False}
key = 'rowformatdelimitedproperty'
class RowFormatSerdeProperty(Property):
2963class RowFormatSerdeProperty(Property):
2964    arg_types = {"this": True, "serde_properties": False}
arg_types = {'this': True, 'serde_properties': False}
key = 'rowformatserdeproperty'
class QueryTransform(Expression):
2968class QueryTransform(Expression):
2969    arg_types = {
2970        "expressions": True,
2971        "command_script": True,
2972        "schema": False,
2973        "row_format_before": False,
2974        "record_writer": False,
2975        "row_format_after": False,
2976        "record_reader": False,
2977    }
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):
2980class SampleProperty(Property):
2981    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sampleproperty'
class SecurityProperty(Property):
2985class SecurityProperty(Property):
2986    arg_types = {"this": True}
arg_types = {'this': True}
key = 'securityproperty'
class SchemaCommentProperty(Property):
2989class SchemaCommentProperty(Property):
2990    arg_types = {"this": True}
arg_types = {'this': True}
key = 'schemacommentproperty'
class SerdeProperties(Property):
2993class SerdeProperties(Property):
2994    arg_types = {"expressions": True, "with": False}
arg_types = {'expressions': True, 'with': False}
key = 'serdeproperties'
class SetProperty(Property):
2997class SetProperty(Property):
2998    arg_types = {"multi": True}
arg_types = {'multi': True}
key = 'setproperty'
class SharingProperty(Property):
3001class SharingProperty(Property):
3002    arg_types = {"this": False}
arg_types = {'this': False}
key = 'sharingproperty'
class SetConfigProperty(Property):
3005class SetConfigProperty(Property):
3006    arg_types = {"this": True}
arg_types = {'this': True}
key = 'setconfigproperty'
class SettingsProperty(Property):
3009class SettingsProperty(Property):
3010    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'settingsproperty'
class SortKeyProperty(Property):
3013class SortKeyProperty(Property):
3014    arg_types = {"this": True, "compound": False}
arg_types = {'this': True, 'compound': False}
key = 'sortkeyproperty'
class SqlReadWriteProperty(Property):
3017class SqlReadWriteProperty(Property):
3018    arg_types = {"this": True}
arg_types = {'this': True}
key = 'sqlreadwriteproperty'
class SqlSecurityProperty(Property):
3021class SqlSecurityProperty(Property):
3022    arg_types = {"definer": True}
arg_types = {'definer': True}
key = 'sqlsecurityproperty'
class StabilityProperty(Property):
3025class StabilityProperty(Property):
3026    arg_types = {"this": True}
arg_types = {'this': True}
key = 'stabilityproperty'
class TemporaryProperty(Property):
3029class TemporaryProperty(Property):
3030    arg_types = {"this": False}
arg_types = {'this': False}
key = 'temporaryproperty'
class SecureProperty(Property):
3033class SecureProperty(Property):
3034    arg_types = {}
arg_types = {}
key = 'secureproperty'
class Tags(ColumnConstraintKind, Property):
3038class Tags(ColumnConstraintKind, Property):
3039    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'tags'
class TransformModelProperty(Property):
3042class TransformModelProperty(Property):
3043    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'transformmodelproperty'
class TransientProperty(Property):
3046class TransientProperty(Property):
3047    arg_types = {"this": False}
arg_types = {'this': False}
key = 'transientproperty'
class UnloggedProperty(Property):
3050class UnloggedProperty(Property):
3051    arg_types = {}
arg_types = {}
key = 'unloggedproperty'
class ViewAttributeProperty(Property):
3055class ViewAttributeProperty(Property):
3056    arg_types = {"this": True}
arg_types = {'this': True}
key = 'viewattributeproperty'
class VolatileProperty(Property):
3059class VolatileProperty(Property):
3060    arg_types = {"this": False}
arg_types = {'this': False}
key = 'volatileproperty'
class WithDataProperty(Property):
3063class WithDataProperty(Property):
3064    arg_types = {"no": True, "statistics": False}
arg_types = {'no': True, 'statistics': False}
key = 'withdataproperty'
class WithJournalTableProperty(Property):
3067class WithJournalTableProperty(Property):
3068    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withjournaltableproperty'
class WithSchemaBindingProperty(Property):
3071class WithSchemaBindingProperty(Property):
3072    arg_types = {"this": True}
arg_types = {'this': True}
key = 'withschemabindingproperty'
class WithSystemVersioningProperty(Property):
3075class WithSystemVersioningProperty(Property):
3076    arg_types = {
3077        "on": False,
3078        "this": False,
3079        "data_consistency": False,
3080        "retention_period": False,
3081        "with": True,
3082    }
arg_types = {'on': False, 'this': False, 'data_consistency': False, 'retention_period': False, 'with': True}
key = 'withsystemversioningproperty'
class WithProcedureOptions(Property):
3085class WithProcedureOptions(Property):
3086    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withprocedureoptions'
class EncodeProperty(Property):
3089class EncodeProperty(Property):
3090    arg_types = {"this": True, "properties": False, "key": False}
arg_types = {'this': True, 'properties': False, 'key': False}
key = 'encodeproperty'
class IncludeProperty(Property):
3093class IncludeProperty(Property):
3094    arg_types = {"this": True, "alias": False, "column_def": False}
arg_types = {'this': True, 'alias': False, 'column_def': False}
key = 'includeproperty'
class Properties(Expression):
3097class Properties(Expression):
3098    arg_types = {"expressions": True}
3099
3100    NAME_TO_PROPERTY = {
3101        "ALGORITHM": AlgorithmProperty,
3102        "AUTO_INCREMENT": AutoIncrementProperty,
3103        "CHARACTER SET": CharacterSetProperty,
3104        "CLUSTERED_BY": ClusteredByProperty,
3105        "COLLATE": CollateProperty,
3106        "COMMENT": SchemaCommentProperty,
3107        "DEFINER": DefinerProperty,
3108        "DISTKEY": DistKeyProperty,
3109        "DISTRIBUTED_BY": DistributedByProperty,
3110        "DISTSTYLE": DistStyleProperty,
3111        "ENGINE": EngineProperty,
3112        "EXECUTE AS": ExecuteAsProperty,
3113        "FORMAT": FileFormatProperty,
3114        "LANGUAGE": LanguageProperty,
3115        "LOCATION": LocationProperty,
3116        "LOCK": LockProperty,
3117        "PARTITIONED_BY": PartitionedByProperty,
3118        "RETURNS": ReturnsProperty,
3119        "ROW_FORMAT": RowFormatProperty,
3120        "SORTKEY": SortKeyProperty,
3121        "ENCODE": EncodeProperty,
3122        "INCLUDE": IncludeProperty,
3123    }
3124
3125    PROPERTY_TO_NAME = {v: k for k, v in NAME_TO_PROPERTY.items()}
3126
3127    # CREATE property locations
3128    # Form: schema specified
3129    #   create [POST_CREATE]
3130    #     table a [POST_NAME]
3131    #     (b int) [POST_SCHEMA]
3132    #     with ([POST_WITH])
3133    #     index (b) [POST_INDEX]
3134    #
3135    # Form: alias selection
3136    #   create [POST_CREATE]
3137    #     table a [POST_NAME]
3138    #     as [POST_ALIAS] (select * from b) [POST_EXPRESSION]
3139    #     index (c) [POST_INDEX]
3140    class Location(AutoName):
3141        POST_CREATE = auto()
3142        POST_NAME = auto()
3143        POST_SCHEMA = auto()
3144        POST_WITH = auto()
3145        POST_ALIAS = auto()
3146        POST_EXPRESSION = auto()
3147        POST_INDEX = auto()
3148        UNSUPPORTED = auto()
3149
3150    @classmethod
3151    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3152        expressions = []
3153        for key, value in properties_dict.items():
3154            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3155            if property_cls:
3156                expressions.append(property_cls(this=convert(value)))
3157            else:
3158                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3159
3160        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:
3150    @classmethod
3151    def from_dict(cls, properties_dict: t.Dict) -> Properties:
3152        expressions = []
3153        for key, value in properties_dict.items():
3154            property_cls = cls.NAME_TO_PROPERTY.get(key.upper())
3155            if property_cls:
3156                expressions.append(property_cls(this=convert(value)))
3157            else:
3158                expressions.append(Property(this=Literal.string(key), value=convert(value)))
3159
3160        return cls(expressions=expressions)
key = 'properties'
class Properties.Location(sqlglot.helper.AutoName):
3140    class Location(AutoName):
3141        POST_CREATE = auto()
3142        POST_NAME = auto()
3143        POST_SCHEMA = auto()
3144        POST_WITH = auto()
3145        POST_ALIAS = auto()
3146        POST_EXPRESSION = auto()
3147        POST_INDEX = auto()
3148        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):
3163class Qualify(Expression):
3164    pass
key = 'qualify'
class InputOutputFormat(Expression):
3167class InputOutputFormat(Expression):
3168    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key = 'inputoutputformat'
class Return(Expression):
3172class Return(Expression):
3173    pass
key = 'return'
class Reference(Expression):
3176class Reference(Expression):
3177    arg_types = {"this": True, "expressions": False, "options": False}
arg_types = {'this': True, 'expressions': False, 'options': False}
key = 'reference'
class Tuple(Expression):
3180class Tuple(Expression):
3181    arg_types = {"expressions": False}
3182
3183    def isin(
3184        self,
3185        *expressions: t.Any,
3186        query: t.Optional[ExpOrStr] = None,
3187        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3188        copy: bool = True,
3189        **opts,
3190    ) -> In:
3191        return In(
3192            this=maybe_copy(self, copy),
3193            expressions=[convert(e, copy=copy) for e in expressions],
3194            query=maybe_parse(query, copy=copy, **opts) if query else None,
3195            unnest=(
3196                Unnest(
3197                    expressions=[
3198                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3199                        for e in ensure_list(unnest)
3200                    ]
3201                )
3202                if unnest
3203                else None
3204            ),
3205        )
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:
3183    def isin(
3184        self,
3185        *expressions: t.Any,
3186        query: t.Optional[ExpOrStr] = None,
3187        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
3188        copy: bool = True,
3189        **opts,
3190    ) -> In:
3191        return In(
3192            this=maybe_copy(self, copy),
3193            expressions=[convert(e, copy=copy) for e in expressions],
3194            query=maybe_parse(query, copy=copy, **opts) if query else None,
3195            unnest=(
3196                Unnest(
3197                    expressions=[
3198                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
3199                        for e in ensure_list(unnest)
3200                    ]
3201                )
3202                if unnest
3203                else None
3204            ),
3205        )
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):
3236class QueryOption(Expression):
3237    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'queryoption'
class WithTableHint(Expression):
3241class WithTableHint(Expression):
3242    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'withtablehint'
class IndexTableHint(Expression):
3246class IndexTableHint(Expression):
3247    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key = 'indextablehint'
class HistoricalData(Expression):
3251class HistoricalData(Expression):
3252    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key = 'historicaldata'
class Table(Expression):
3255class Table(Expression):
3256    arg_types = {
3257        "this": False,
3258        "alias": False,
3259        "db": False,
3260        "catalog": False,
3261        "laterals": False,
3262        "joins": False,
3263        "pivots": False,
3264        "hints": False,
3265        "system_time": False,
3266        "version": False,
3267        "format": False,
3268        "pattern": False,
3269        "ordinality": False,
3270        "when": False,
3271        "only": False,
3272        "partition": False,
3273        "changes": False,
3274        "rows_from": False,
3275        "sample": False,
3276    }
3277
3278    @property
3279    def name(self) -> str:
3280        if not self.this or isinstance(self.this, Func):
3281            return ""
3282        return self.this.name
3283
3284    @property
3285    def db(self) -> str:
3286        return self.text("db")
3287
3288    @property
3289    def catalog(self) -> str:
3290        return self.text("catalog")
3291
3292    @property
3293    def selects(self) -> t.List[Expression]:
3294        return []
3295
3296    @property
3297    def named_selects(self) -> t.List[str]:
3298        return []
3299
3300    @property
3301    def parts(self) -> t.List[Expression]:
3302        """Return the parts of a table in order catalog, db, table."""
3303        parts: t.List[Expression] = []
3304
3305        for arg in ("catalog", "db", "this"):
3306            part = self.args.get(arg)
3307
3308            if isinstance(part, Dot):
3309                parts.extend(part.flatten())
3310            elif isinstance(part, Expression):
3311                parts.append(part)
3312
3313        return parts
3314
3315    def to_column(self, copy: bool = True) -> Expression:
3316        parts = self.parts
3317        last_part = parts[-1]
3318
3319        if isinstance(last_part, Identifier):
3320            col: Expression = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
3321        else:
3322            # This branch will be reached if a function or array is wrapped in a `Table`
3323            col = last_part
3324
3325        alias = self.args.get("alias")
3326        if alias:
3327            col = alias_(col, alias.this, copy=copy)
3328
3329        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
3278    @property
3279    def name(self) -> str:
3280        if not self.this or isinstance(self.this, Func):
3281            return ""
3282        return self.this.name
db: str
3284    @property
3285    def db(self) -> str:
3286        return self.text("db")
catalog: str
3288    @property
3289    def catalog(self) -> str:
3290        return self.text("catalog")
selects: List[Expression]
3292    @property
3293    def selects(self) -> t.List[Expression]:
3294        return []
named_selects: List[str]
3296    @property
3297    def named_selects(self) -> t.List[str]:
3298        return []
parts: List[Expression]
3300    @property
3301    def parts(self) -> t.List[Expression]:
3302        """Return the parts of a table in order catalog, db, table."""
3303        parts: t.List[Expression] = []
3304
3305        for arg in ("catalog", "db", "this"):
3306            part = self.args.get(arg)
3307
3308            if isinstance(part, Dot):
3309                parts.extend(part.flatten())
3310            elif isinstance(part, Expression):
3311                parts.append(part)
3312
3313        return parts

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

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

Returns the output names of the query's projections.

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

Checks whether an expression is a star.

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

Returns the query's projections.

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

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

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

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

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

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

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

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

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

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:
3798    def select(
3799        self,
3800        *expressions: t.Optional[ExpOrStr],
3801        append: bool = True,
3802        dialect: DialectType = None,
3803        copy: bool = True,
3804        **opts,
3805    ) -> Select:
3806        return _apply_list_builder(
3807            *expressions,
3808            instance=self,
3809            arg="expressions",
3810            append=append,
3811            dialect=dialect,
3812            into=Expression,
3813            copy=copy,
3814            **opts,
3815        )

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

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

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

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

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:
4032    def window(
4033        self,
4034        *expressions: t.Optional[ExpOrStr],
4035        append: bool = True,
4036        dialect: DialectType = None,
4037        copy: bool = True,
4038        **opts,
4039    ) -> Select:
4040        return _apply_list_builder(
4041            *expressions,
4042            instance=self,
4043            arg="windows",
4044            append=append,
4045            into=Window,
4046            dialect=dialect,
4047            copy=copy,
4048            **opts,
4049        )
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:
4051    def qualify(
4052        self,
4053        *expressions: t.Optional[ExpOrStr],
4054        append: bool = True,
4055        dialect: DialectType = None,
4056        copy: bool = True,
4057        **opts,
4058    ) -> Select:
4059        return _apply_conjunction_builder(
4060            *expressions,
4061            instance=self,
4062            arg="qualify",
4063            append=append,
4064            into=Qualify,
4065            dialect=dialect,
4066            copy=copy,
4067            **opts,
4068        )
def distinct( self, *ons: Union[str, Expression, NoneType], distinct: bool = True, copy: bool = True) -> Select:
4070    def distinct(
4071        self, *ons: t.Optional[ExpOrStr], distinct: bool = True, copy: bool = True
4072    ) -> Select:
4073        """
4074        Set the OFFSET expression.
4075
4076        Example:
4077            >>> Select().from_("tbl").select("x").distinct().sql()
4078            'SELECT DISTINCT x FROM tbl'
4079
4080        Args:
4081            ons: the expressions to distinct on
4082            distinct: whether the Select should be distinct
4083            copy: if `False`, modify this expression instance in-place.
4084
4085        Returns:
4086            Select: the modified expression.
4087        """
4088        instance = maybe_copy(self, copy)
4089        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
4090        instance.set("distinct", Distinct(on=on) if distinct else None)
4091        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:
4093    def ctas(
4094        self,
4095        table: ExpOrStr,
4096        properties: t.Optional[t.Dict] = None,
4097        dialect: DialectType = None,
4098        copy: bool = True,
4099        **opts,
4100    ) -> Create:
4101        """
4102        Convert this expression to a CREATE TABLE AS statement.
4103
4104        Example:
4105            >>> Select().select("*").from_("tbl").ctas("x").sql()
4106            'CREATE TABLE x AS SELECT * FROM tbl'
4107
4108        Args:
4109            table: the SQL code string to parse as the table name.
4110                If another `Expression` instance is passed, it will be used as-is.
4111            properties: an optional mapping of table properties
4112            dialect: the dialect used to parse the input table.
4113            copy: if `False`, modify this expression instance in-place.
4114            opts: other options to use to parse the input table.
4115
4116        Returns:
4117            The new Create expression.
4118        """
4119        instance = maybe_copy(self, copy)
4120        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
4121
4122        properties_expression = None
4123        if properties:
4124            properties_expression = Properties.from_dict(properties)
4125
4126        return Create(
4127            this=table_expression,
4128            kind="TABLE",
4129            expression=instance,
4130            properties=properties_expression,
4131        )

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:
4133    def lock(self, update: bool = True, copy: bool = True) -> Select:
4134        """
4135        Set the locking read mode for this expression.
4136
4137        Examples:
4138            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
4139            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
4140
4141            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
4142            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
4143
4144        Args:
4145            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
4146            copy: if `False`, modify this expression instance in-place.
4147
4148        Returns:
4149            The modified expression.
4150        """
4151        inst = maybe_copy(self, copy)
4152        inst.set("locks", [Lock(update=update)])
4153
4154        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:
4156    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
4157        """
4158        Set hints for this expression.
4159
4160        Examples:
4161            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
4162            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
4163
4164        Args:
4165            hints: The SQL code strings to parse as the hints.
4166                If an `Expression` instance is passed, it will be used as-is.
4167            dialect: The dialect used to parse the hints.
4168            copy: If `False`, modify this expression instance in-place.
4169
4170        Returns:
4171            The modified expression.
4172        """
4173        inst = maybe_copy(self, copy)
4174        inst.set(
4175            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
4176        )
4177
4178        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]
4180    @property
4181    def named_selects(self) -> t.List[str]:
4182        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
4184    @property
4185    def is_star(self) -> bool:
4186        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

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

Returns the query's projections.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

Tags are used for generating arbitrary sql like SELECT x.

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

Returns a Python object equivalent of the SQL node.

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

Returns a Python object equivalent of the SQL node.

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

Checks whether an expression is a star.

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

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

key = 'dot'
class DPipe(Binary):
4923class DPipe(Binary):
4924    arg_types = {"this": True, "expression": True, "safe": False}
arg_types = {'this': True, 'expression': True, 'safe': False}
key = 'dpipe'
class EQ(Binary, Predicate):
4927class EQ(Binary, Predicate):
4928    pass
key = 'eq'
class NullSafeEQ(Binary, Predicate):
4931class NullSafeEQ(Binary, Predicate):
4932    pass
key = 'nullsafeeq'
class NullSafeNEQ(Binary, Predicate):
4935class NullSafeNEQ(Binary, Predicate):
4936    pass
key = 'nullsafeneq'
class PropertyEQ(Binary):
4940class PropertyEQ(Binary):
4941    pass
key = 'propertyeq'
class Distance(Binary):
4944class Distance(Binary):
4945    pass
key = 'distance'
class Escape(Binary):
4948class Escape(Binary):
4949    pass
key = 'escape'
class Glob(Binary, Predicate):
4952class Glob(Binary, Predicate):
4953    pass
key = 'glob'
class GT(Binary, Predicate):
4956class GT(Binary, Predicate):
4957    pass
key = 'gt'
class GTE(Binary, Predicate):
4960class GTE(Binary, Predicate):
4961    pass
key = 'gte'
class ILike(Binary, Predicate):
4964class ILike(Binary, Predicate):
4965    pass
key = 'ilike'
class ILikeAny(Binary, Predicate):
4968class ILikeAny(Binary, Predicate):
4969    pass
key = 'ilikeany'
class IntDiv(Binary):
4972class IntDiv(Binary):
4973    pass
key = 'intdiv'
class Is(Binary, Predicate):
4976class Is(Binary, Predicate):
4977    pass
key = 'is'
class Kwarg(Binary):
4980class Kwarg(Binary):
4981    """Kwarg in special functions like func(kwarg => y)."""

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

key = 'kwarg'
class Like(Binary, Predicate):
4984class Like(Binary, Predicate):
4985    pass
key = 'like'
class LikeAny(Binary, Predicate):
4988class LikeAny(Binary, Predicate):
4989    pass
key = 'likeany'
class LT(Binary, Predicate):
4992class LT(Binary, Predicate):
4993    pass
key = 'lt'
class LTE(Binary, Predicate):
4996class LTE(Binary, Predicate):
4997    pass
key = 'lte'
class Mod(Binary):
5000class Mod(Binary):
5001    pass
key = 'mod'
class Mul(Binary):
5004class Mul(Binary):
5005    pass
key = 'mul'
class NEQ(Binary, Predicate):
5008class NEQ(Binary, Predicate):
5009    pass
key = 'neq'
class Operator(Binary):
5013class Operator(Binary):
5014    arg_types = {"this": True, "operator": True, "expression": True}
arg_types = {'this': True, 'operator': True, 'expression': True}
key = 'operator'
class SimilarTo(Binary, Predicate):
5017class SimilarTo(Binary, Predicate):
5018    pass
key = 'similarto'
class Slice(Binary):
5021class Slice(Binary):
5022    arg_types = {"this": False, "expression": False}
arg_types = {'this': False, 'expression': False}
key = 'slice'
class Sub(Binary):
5025class Sub(Binary):
5026    pass
key = 'sub'
class Unary(Condition):
5031class Unary(Condition):
5032    pass
key = 'unary'
class BitwiseNot(Unary):
5035class BitwiseNot(Unary):
5036    pass
key = 'bitwisenot'
class Not(Unary):
5039class Not(Unary):
5040    pass
key = 'not'
class Paren(Unary):
5043class Paren(Unary):
5044    @property
5045    def output_name(self) -> str:
5046        return self.this.name
output_name: str
5044    @property
5045    def output_name(self) -> str:
5046        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):
5049class Neg(Unary):
5050    def to_py(self) -> int | Decimal:
5051        if self.is_number:
5052            return self.this.to_py() * -1
5053        return super().to_py()
def to_py(self) -> int | decimal.Decimal:
5050    def to_py(self) -> int | Decimal:
5051        if self.is_number:
5052            return self.this.to_py() * -1
5053        return super().to_py()

Returns a Python object equivalent of the SQL node.

key = 'neg'
class Alias(Expression):
5056class Alias(Expression):
5057    arg_types = {"this": True, "alias": False}
5058
5059    @property
5060    def output_name(self) -> str:
5061        return self.alias
arg_types = {'this': True, 'alias': False}
output_name: str
5059    @property
5060    def output_name(self) -> str:
5061        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):
5066class PivotAlias(Alias):
5067    pass
key = 'pivotalias'
class PivotAny(Expression):
5072class PivotAny(Expression):
5073    arg_types = {"this": False}
arg_types = {'this': False}
key = 'pivotany'
class Aliases(Expression):
5076class Aliases(Expression):
5077    arg_types = {"this": True, "expressions": True}
5078
5079    @property
5080    def aliases(self):
5081        return self.expressions
arg_types = {'this': True, 'expressions': True}
aliases
5079    @property
5080    def aliases(self):
5081        return self.expressions
key = 'aliases'
class AtIndex(Expression):
5085class AtIndex(Expression):
5086    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'atindex'
class AtTimeZone(Expression):
5089class AtTimeZone(Expression):
5090    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'attimezone'
class FromTimeZone(Expression):
5093class FromTimeZone(Expression):
5094    arg_types = {"this": True, "zone": True}
arg_types = {'this': True, 'zone': True}
key = 'fromtimezone'
class Between(Predicate):
5097class Between(Predicate):
5098    arg_types = {"this": True, "low": True, "high": True}
arg_types = {'this': True, 'low': True, 'high': True}
key = 'between'
class Bracket(Condition):
5101class Bracket(Condition):
5102    # https://cloud.google.com/bigquery/docs/reference/standard-sql/operators#array_subscript_operator
5103    arg_types = {
5104        "this": True,
5105        "expressions": True,
5106        "offset": False,
5107        "safe": False,
5108        "returns_list_for_maps": False,
5109    }
5110
5111    @property
5112    def output_name(self) -> str:
5113        if len(self.expressions) == 1:
5114            return self.expressions[0].output_name
5115
5116        return super().output_name
arg_types = {'this': True, 'expressions': True, 'offset': False, 'safe': False, 'returns_list_for_maps': False}
output_name: str
5111    @property
5112    def output_name(self) -> str:
5113        if len(self.expressions) == 1:
5114            return self.expressions[0].output_name
5115
5116        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):
5119class Distinct(Expression):
5120    arg_types = {"expressions": False, "on": False}
arg_types = {'expressions': False, 'on': False}
key = 'distinct'
class In(Predicate):
5123class In(Predicate):
5124    arg_types = {
5125        "this": True,
5126        "expressions": False,
5127        "query": False,
5128        "unnest": False,
5129        "field": False,
5130        "is_global": False,
5131    }
arg_types = {'this': True, 'expressions': False, 'query': False, 'unnest': False, 'field': False, 'is_global': False}
key = 'in'
class ForIn(Expression):
5135class ForIn(Expression):
5136    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'forin'
class TimeUnit(Expression):
5139class TimeUnit(Expression):
5140    """Automatically converts unit arg into a var."""
5141
5142    arg_types = {"unit": False}
5143
5144    UNABBREVIATED_UNIT_NAME = {
5145        "D": "DAY",
5146        "H": "HOUR",
5147        "M": "MINUTE",
5148        "MS": "MILLISECOND",
5149        "NS": "NANOSECOND",
5150        "Q": "QUARTER",
5151        "S": "SECOND",
5152        "US": "MICROSECOND",
5153        "W": "WEEK",
5154        "Y": "YEAR",
5155    }
5156
5157    VAR_LIKE = (Column, Literal, Var)
5158
5159    def __init__(self, **args):
5160        unit = args.get("unit")
5161        if isinstance(unit, self.VAR_LIKE):
5162            args["unit"] = Var(
5163                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5164            )
5165        elif isinstance(unit, Week):
5166            unit.set("this", Var(this=unit.this.name.upper()))
5167
5168        super().__init__(**args)
5169
5170    @property
5171    def unit(self) -> t.Optional[Var | IntervalSpan]:
5172        return self.args.get("unit")

Automatically converts unit arg into a var.

TimeUnit(**args)
5159    def __init__(self, **args):
5160        unit = args.get("unit")
5161        if isinstance(unit, self.VAR_LIKE):
5162            args["unit"] = Var(
5163                this=(self.UNABBREVIATED_UNIT_NAME.get(unit.name) or unit.name).upper()
5164            )
5165        elif isinstance(unit, Week):
5166            unit.set("this", Var(this=unit.this.name.upper()))
5167
5168        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]
5170    @property
5171    def unit(self) -> t.Optional[Var | IntervalSpan]:
5172        return self.args.get("unit")
key = 'timeunit'
class IntervalOp(TimeUnit):
5175class IntervalOp(TimeUnit):
5176    arg_types = {"unit": False, "expression": True}
5177
5178    def interval(self):
5179        return Interval(
5180            this=self.expression.copy(),
5181            unit=self.unit.copy() if self.unit else None,
5182        )
arg_types = {'unit': False, 'expression': True}
def interval(self):
5178    def interval(self):
5179        return Interval(
5180            this=self.expression.copy(),
5181            unit=self.unit.copy() if self.unit else None,
5182        )
key = 'intervalop'
class IntervalSpan(DataType):
5188class IntervalSpan(DataType):
5189    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'intervalspan'
class Interval(TimeUnit):
5192class Interval(TimeUnit):
5193    arg_types = {"this": False, "unit": False}
arg_types = {'this': False, 'unit': False}
key = 'interval'
class IgnoreNulls(Expression):
5196class IgnoreNulls(Expression):
5197    pass
key = 'ignorenulls'
class RespectNulls(Expression):
5200class RespectNulls(Expression):
5201    pass
key = 'respectnulls'
class HavingMax(Expression):
5205class HavingMax(Expression):
5206    arg_types = {"this": True, "expression": True, "max": True}
arg_types = {'this': True, 'expression': True, 'max': True}
key = 'havingmax'
class Func(Condition):
5210class Func(Condition):
5211    """
5212    The base class for all function expressions.
5213
5214    Attributes:
5215        is_var_len_args (bool): if set to True the last argument defined in arg_types will be
5216            treated as a variable length argument and the argument's value will be stored as a list.
5217        _sql_names (list): the SQL name (1st item in the list) and aliases (subsequent items) for this
5218            function expression. These values are used to map this node to a name during parsing as
5219            well as to provide the function's name during SQL string generation. By default the SQL
5220            name is set to the expression's class name transformed to snake case.
5221    """
5222
5223    is_var_len_args = False
5224
5225    @classmethod
5226    def from_arg_list(cls, args):
5227        if cls.is_var_len_args:
5228            all_arg_keys = list(cls.arg_types)
5229            # If this function supports variable length argument treat the last argument as such.
5230            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5231            num_non_var = len(non_var_len_arg_keys)
5232
5233            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5234            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5235        else:
5236            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5237
5238        return cls(**args_dict)
5239
5240    @classmethod
5241    def sql_names(cls):
5242        if cls is Func:
5243            raise NotImplementedError(
5244                "SQL name is only supported by concrete function implementations"
5245            )
5246        if "_sql_names" not in cls.__dict__:
5247            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5248        return cls._sql_names
5249
5250    @classmethod
5251    def sql_name(cls):
5252        return cls.sql_names()[0]
5253
5254    @classmethod
5255    def default_parser_mappings(cls):
5256        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):
5225    @classmethod
5226    def from_arg_list(cls, args):
5227        if cls.is_var_len_args:
5228            all_arg_keys = list(cls.arg_types)
5229            # If this function supports variable length argument treat the last argument as such.
5230            non_var_len_arg_keys = all_arg_keys[:-1] if cls.is_var_len_args else all_arg_keys
5231            num_non_var = len(non_var_len_arg_keys)
5232
5233            args_dict = {arg_key: arg for arg, arg_key in zip(args, non_var_len_arg_keys)}
5234            args_dict[all_arg_keys[-1]] = args[num_non_var:]
5235        else:
5236            args_dict = {arg_key: arg for arg, arg_key in zip(args, cls.arg_types)}
5237
5238        return cls(**args_dict)
@classmethod
def sql_names(cls):
5240    @classmethod
5241    def sql_names(cls):
5242        if cls is Func:
5243            raise NotImplementedError(
5244                "SQL name is only supported by concrete function implementations"
5245            )
5246        if "_sql_names" not in cls.__dict__:
5247            cls._sql_names = [camel_to_snake_case(cls.__name__)]
5248        return cls._sql_names
@classmethod
def sql_name(cls):
5250    @classmethod
5251    def sql_name(cls):
5252        return cls.sql_names()[0]
@classmethod
def default_parser_mappings(cls):
5254    @classmethod
5255    def default_parser_mappings(cls):
5256        return {name: cls.from_arg_list for name in cls.sql_names()}
key = 'func'
class AggFunc(Func):
5259class AggFunc(Func):
5260    pass
key = 'aggfunc'
class ParameterizedAgg(AggFunc):
5263class ParameterizedAgg(AggFunc):
5264    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'parameterizedagg'
class Abs(Func):
5267class Abs(Func):
5268    pass
key = 'abs'
class ArgMax(AggFunc):
5271class ArgMax(AggFunc):
5272    arg_types = {"this": True, "expression": True, "count": False}
5273    _sql_names = ["ARG_MAX", "ARGMAX", "MAX_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmax'
class ArgMin(AggFunc):
5276class ArgMin(AggFunc):
5277    arg_types = {"this": True, "expression": True, "count": False}
5278    _sql_names = ["ARG_MIN", "ARGMIN", "MIN_BY"]
arg_types = {'this': True, 'expression': True, 'count': False}
key = 'argmin'
class ApproxTopK(AggFunc):
5281class ApproxTopK(AggFunc):
5282    arg_types = {"this": True, "expression": False, "counters": False}
arg_types = {'this': True, 'expression': False, 'counters': False}
key = 'approxtopk'
class Flatten(Func):
5285class Flatten(Func):
5286    pass
key = 'flatten'
class Transform(Func):
5290class Transform(Func):
5291    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'transform'
class Anonymous(Func):
5294class Anonymous(Func):
5295    arg_types = {"this": True, "expressions": False}
5296    is_var_len_args = True
5297
5298    @property
5299    def name(self) -> str:
5300        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
5298    @property
5299    def name(self) -> str:
5300        return self.this if isinstance(self.this, str) else self.this.name
key = 'anonymous'
class AnonymousAggFunc(AggFunc):
5303class AnonymousAggFunc(AggFunc):
5304    arg_types = {"this": True, "expressions": False}
5305    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'anonymousaggfunc'
class CombinedAggFunc(AnonymousAggFunc):
5309class CombinedAggFunc(AnonymousAggFunc):
5310    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'combinedaggfunc'
class CombinedParameterizedAgg(ParameterizedAgg):
5313class CombinedParameterizedAgg(ParameterizedAgg):
5314    arg_types = {"this": True, "expressions": True, "params": True}
arg_types = {'this': True, 'expressions': True, 'params': True}
key = 'combinedparameterizedagg'
class Hll(AggFunc):
5319class Hll(AggFunc):
5320    arg_types = {"this": True, "expressions": False}
5321    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'hll'
class ApproxDistinct(AggFunc):
5324class ApproxDistinct(AggFunc):
5325    arg_types = {"this": True, "accuracy": False}
5326    _sql_names = ["APPROX_DISTINCT", "APPROX_COUNT_DISTINCT"]
arg_types = {'this': True, 'accuracy': False}
key = 'approxdistinct'
class Apply(Func):
5329class Apply(Func):
5330    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'apply'
class Array(Func):
5333class Array(Func):
5334    arg_types = {"expressions": False, "bracket_notation": False}
5335    is_var_len_args = True
arg_types = {'expressions': False, 'bracket_notation': False}
is_var_len_args = True
key = 'array'
class ToArray(Func):
5339class ToArray(Func):
5340    pass
key = 'toarray'
class List(Func):
5344class List(Func):
5345    arg_types = {"expressions": False}
5346    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'list'
class Pad(Func):
5350class Pad(Func):
5351    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):
5356class ToChar(Func):
5357    arg_types = {"this": True, "format": False, "nlsparam": False}
arg_types = {'this': True, 'format': False, 'nlsparam': False}
key = 'tochar'
class ToNumber(Func):
5362class ToNumber(Func):
5363    arg_types = {
5364        "this": True,
5365        "format": False,
5366        "nlsparam": False,
5367        "precision": False,
5368        "scale": False,
5369    }
arg_types = {'this': True, 'format': False, 'nlsparam': False, 'precision': False, 'scale': False}
key = 'tonumber'
class ToDouble(Func):
5373class ToDouble(Func):
5374    arg_types = {
5375        "this": True,
5376        "format": False,
5377    }
arg_types = {'this': True, 'format': False}
key = 'todouble'
class Columns(Func):
5380class Columns(Func):
5381    arg_types = {"this": True, "unpack": False}
arg_types = {'this': True, 'unpack': False}
key = 'columns'
class Convert(Func):
5385class Convert(Func):
5386    arg_types = {"this": True, "expression": True, "style": False}
arg_types = {'this': True, 'expression': True, 'style': False}
key = 'convert'
class ConvertTimezone(Func):
5389class ConvertTimezone(Func):
5390    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):
5393class GenerateSeries(Func):
5394    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):
5400class ExplodingGenerateSeries(GenerateSeries):
5401    pass
key = 'explodinggenerateseries'
class ArrayAgg(AggFunc):
5404class ArrayAgg(AggFunc):
5405    arg_types = {"this": True, "nulls_excluded": False}
arg_types = {'this': True, 'nulls_excluded': False}
key = 'arrayagg'
class ArrayUniqueAgg(AggFunc):
5408class ArrayUniqueAgg(AggFunc):
5409    pass
key = 'arrayuniqueagg'
class ArrayAll(Func):
5412class ArrayAll(Func):
5413    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayall'
class ArrayAny(Func):
5417class ArrayAny(Func):
5418    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'arrayany'
class ArrayConcat(Func):
5421class ArrayConcat(Func):
5422    _sql_names = ["ARRAY_CONCAT", "ARRAY_CAT"]
5423    arg_types = {"this": True, "expressions": False}
5424    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'arrayconcat'
class ArrayConstructCompact(Func):
5427class ArrayConstructCompact(Func):
5428    arg_types = {"expressions": True}
5429    is_var_len_args = True
arg_types = {'expressions': True}
is_var_len_args = True
key = 'arrayconstructcompact'
class ArrayContains(Binary, Func):
5432class ArrayContains(Binary, Func):
5433    _sql_names = ["ARRAY_CONTAINS", "ARRAY_HAS"]
key = 'arraycontains'
class ArrayContainsAll(Binary, Func):
5436class ArrayContainsAll(Binary, Func):
5437    _sql_names = ["ARRAY_CONTAINS_ALL", "ARRAY_HAS_ALL"]
key = 'arraycontainsall'
class ArrayFilter(Func):
5440class ArrayFilter(Func):
5441    arg_types = {"this": True, "expression": True}
5442    _sql_names = ["FILTER", "ARRAY_FILTER"]
arg_types = {'this': True, 'expression': True}
key = 'arrayfilter'
class ArrayToString(Func):
5445class ArrayToString(Func):
5446    arg_types = {"this": True, "expression": True, "null": False}
5447    _sql_names = ["ARRAY_TO_STRING", "ARRAY_JOIN"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'arraytostring'
class String(Func):
5451class String(Func):
5452    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'string'
class StringToArray(Func):
5455class StringToArray(Func):
5456    arg_types = {"this": True, "expression": True, "null": False}
5457    _sql_names = ["STRING_TO_ARRAY", "SPLIT_BY_STRING"]
arg_types = {'this': True, 'expression': True, 'null': False}
key = 'stringtoarray'
class ArrayOverlaps(Binary, Func):
5460class ArrayOverlaps(Binary, Func):
5461    pass
key = 'arrayoverlaps'
class ArraySize(Func):
5464class ArraySize(Func):
5465    arg_types = {"this": True, "expression": False}
5466    _sql_names = ["ARRAY_SIZE", "ARRAY_LENGTH"]
arg_types = {'this': True, 'expression': False}
key = 'arraysize'
class ArraySort(Func):
5469class ArraySort(Func):
5470    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysort'
class ArraySum(Func):
5473class ArraySum(Func):
5474    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'arraysum'
class ArrayUnionAgg(AggFunc):
5477class ArrayUnionAgg(AggFunc):
5478    pass
key = 'arrayunionagg'
class Avg(AggFunc):
5481class Avg(AggFunc):
5482    pass
key = 'avg'
class AnyValue(AggFunc):
5485class AnyValue(AggFunc):
5486    pass
key = 'anyvalue'
class Lag(AggFunc):
5489class Lag(AggFunc):
5490    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lag'
class Lead(AggFunc):
5493class Lead(AggFunc):
5494    arg_types = {"this": True, "offset": False, "default": False}
arg_types = {'this': True, 'offset': False, 'default': False}
key = 'lead'
class First(AggFunc):
5499class First(AggFunc):
5500    pass
key = 'first'
class Last(AggFunc):
5503class Last(AggFunc):
5504    pass
key = 'last'
class FirstValue(AggFunc):
5507class FirstValue(AggFunc):
5508    pass
key = 'firstvalue'
class LastValue(AggFunc):
5511class LastValue(AggFunc):
5512    pass
key = 'lastvalue'
class NthValue(AggFunc):
5515class NthValue(AggFunc):
5516    arg_types = {"this": True, "offset": True}
arg_types = {'this': True, 'offset': True}
key = 'nthvalue'
class Case(Func):
5519class Case(Func):
5520    arg_types = {"this": False, "ifs": True, "default": False}
5521
5522    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5523        instance = maybe_copy(self, copy)
5524        instance.append(
5525            "ifs",
5526            If(
5527                this=maybe_parse(condition, copy=copy, **opts),
5528                true=maybe_parse(then, copy=copy, **opts),
5529            ),
5530        )
5531        return instance
5532
5533    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5534        instance = maybe_copy(self, copy)
5535        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5536        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:
5522    def when(self, condition: ExpOrStr, then: ExpOrStr, copy: bool = True, **opts) -> Case:
5523        instance = maybe_copy(self, copy)
5524        instance.append(
5525            "ifs",
5526            If(
5527                this=maybe_parse(condition, copy=copy, **opts),
5528                true=maybe_parse(then, copy=copy, **opts),
5529            ),
5530        )
5531        return instance
def else_( self, condition: Union[str, Expression], copy: bool = True, **opts) -> Case:
5533    def else_(self, condition: ExpOrStr, copy: bool = True, **opts) -> Case:
5534        instance = maybe_copy(self, copy)
5535        instance.set("default", maybe_parse(condition, copy=copy, **opts))
5536        return instance
key = 'case'
class Cast(Func):
5539class Cast(Func):
5540    arg_types = {
5541        "this": True,
5542        "to": True,
5543        "format": False,
5544        "safe": False,
5545        "action": False,
5546        "default": False,
5547    }
5548
5549    @property
5550    def name(self) -> str:
5551        return self.this.name
5552
5553    @property
5554    def to(self) -> DataType:
5555        return self.args["to"]
5556
5557    @property
5558    def output_name(self) -> str:
5559        return self.name
5560
5561    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5562        """
5563        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5564        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5565        array<int> != array<float>.
5566
5567        Args:
5568            dtypes: the data types to compare this Cast's DataType to.
5569
5570        Returns:
5571            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5572        """
5573        return self.to.is_type(*dtypes)
arg_types = {'this': True, 'to': True, 'format': False, 'safe': False, 'action': False, 'default': False}
name: str
5549    @property
5550    def name(self) -> str:
5551        return self.this.name
to: DataType
5553    @property
5554    def to(self) -> DataType:
5555        return self.args["to"]
output_name: str
5557    @property
5558    def output_name(self) -> str:
5559        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:
5561    def is_type(self, *dtypes: DATA_TYPE) -> bool:
5562        """
5563        Checks whether this Cast's DataType matches one of the provided data types. Nested types
5564        like arrays or structs will be compared using "structural equivalence" semantics, so e.g.
5565        array<int> != array<float>.
5566
5567        Args:
5568            dtypes: the data types to compare this Cast's DataType to.
5569
5570        Returns:
5571            True, if and only if there is a type in `dtypes` which is equal to this Cast's DataType.
5572        """
5573        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):
5576class TryCast(Cast):
5577    pass
key = 'trycast'
class JSONCast(Cast):
5581class JSONCast(Cast):
5582    pass
key = 'jsoncast'
class Try(Func):
5585class Try(Func):
5586    pass
key = 'try'
class CastToStrType(Func):
5589class CastToStrType(Func):
5590    arg_types = {"this": True, "to": True}
arg_types = {'this': True, 'to': True}
key = 'casttostrtype'
class Collate(Binary, Func):
5593class Collate(Binary, Func):
5594    pass
key = 'collate'
class Ceil(Func):
5597class Ceil(Func):
5598    arg_types = {"this": True, "decimals": False, "to": False}
5599    _sql_names = ["CEIL", "CEILING"]
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'ceil'
class Coalesce(Func):
5602class Coalesce(Func):
5603    arg_types = {"this": True, "expressions": False, "is_nvl": False}
5604    is_var_len_args = True
5605    _sql_names = ["COALESCE", "IFNULL", "NVL"]
arg_types = {'this': True, 'expressions': False, 'is_nvl': False}
is_var_len_args = True
key = 'coalesce'
class Chr(Func):
5608class Chr(Func):
5609    arg_types = {"expressions": True, "charset": False}
5610    is_var_len_args = True
5611    _sql_names = ["CHR", "CHAR"]
arg_types = {'expressions': True, 'charset': False}
is_var_len_args = True
key = 'chr'
class Concat(Func):
5614class Concat(Func):
5615    arg_types = {"expressions": True, "safe": False, "coalesce": False}
5616    is_var_len_args = True
arg_types = {'expressions': True, 'safe': False, 'coalesce': False}
is_var_len_args = True
key = 'concat'
class ConcatWs(Concat):
5619class ConcatWs(Concat):
5620    _sql_names = ["CONCAT_WS"]
key = 'concatws'
class Contains(Func):
5623class Contains(Func):
5624    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'contains'
class ConnectByRoot(Func):
5628class ConnectByRoot(Func):
5629    pass
key = 'connectbyroot'
class Count(AggFunc):
5632class Count(AggFunc):
5633    arg_types = {"this": False, "expressions": False, "big_int": False}
5634    is_var_len_args = True
arg_types = {'this': False, 'expressions': False, 'big_int': False}
is_var_len_args = True
key = 'count'
class CountIf(AggFunc):
5637class CountIf(AggFunc):
5638    _sql_names = ["COUNT_IF", "COUNTIF"]
key = 'countif'
class Cbrt(Func):
5642class Cbrt(Func):
5643    pass
key = 'cbrt'
class CurrentDate(Func):
5646class CurrentDate(Func):
5647    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdate'
class CurrentDatetime(Func):
5650class CurrentDatetime(Func):
5651    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentdatetime'
class CurrentTime(Func):
5654class CurrentTime(Func):
5655    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currenttime'
class CurrentTimestamp(Func):
5658class CurrentTimestamp(Func):
5659    arg_types = {"this": False, "sysdate": False}
arg_types = {'this': False, 'sysdate': False}
key = 'currenttimestamp'
class CurrentSchema(Func):
5662class CurrentSchema(Func):
5663    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentschema'
class CurrentUser(Func):
5666class CurrentUser(Func):
5667    arg_types = {"this": False}
arg_types = {'this': False}
key = 'currentuser'
class DateAdd(Func, IntervalOp):
5670class DateAdd(Func, IntervalOp):
5671    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'dateadd'
class DateBin(Func, IntervalOp):
5674class DateBin(Func, IntervalOp):
5675    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):
5678class DateSub(Func, IntervalOp):
5679    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datesub'
class DateDiff(Func, TimeUnit):
5682class DateDiff(Func, TimeUnit):
5683    _sql_names = ["DATEDIFF", "DATE_DIFF"]
5684    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datediff'
class DateTrunc(Func):
5687class DateTrunc(Func):
5688    arg_types = {"unit": True, "this": True, "zone": False}
5689
5690    def __init__(self, **args):
5691        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5692        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5693        unabbreviate = args.pop("unabbreviate", True)
5694
5695        unit = args.get("unit")
5696        if isinstance(unit, TimeUnit.VAR_LIKE):
5697            unit_name = unit.name.upper()
5698            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5699                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5700
5701            args["unit"] = Literal.string(unit_name)
5702        elif isinstance(unit, Week):
5703            unit.set("this", Literal.string(unit.this.name.upper()))
5704
5705        super().__init__(**args)
5706
5707    @property
5708    def unit(self) -> Expression:
5709        return self.args["unit"]
DateTrunc(**args)
5690    def __init__(self, **args):
5691        # Across most dialects it's safe to unabbreviate the unit (e.g. 'Q' -> 'QUARTER') except Oracle
5692        # https://docs.oracle.com/en/database/oracle/oracle-database/21/sqlrf/ROUND-and-TRUNC-Date-Functions.html
5693        unabbreviate = args.pop("unabbreviate", True)
5694
5695        unit = args.get("unit")
5696        if isinstance(unit, TimeUnit.VAR_LIKE):
5697            unit_name = unit.name.upper()
5698            if unabbreviate and unit_name in TimeUnit.UNABBREVIATED_UNIT_NAME:
5699                unit_name = TimeUnit.UNABBREVIATED_UNIT_NAME[unit_name]
5700
5701            args["unit"] = Literal.string(unit_name)
5702        elif isinstance(unit, Week):
5703            unit.set("this", Literal.string(unit.this.name.upper()))
5704
5705        super().__init__(**args)
arg_types = {'unit': True, 'this': True, 'zone': False}
unit: Expression
5707    @property
5708    def unit(self) -> Expression:
5709        return self.args["unit"]
key = 'datetrunc'
class Datetime(Func):
5714class Datetime(Func):
5715    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'datetime'
class DatetimeAdd(Func, IntervalOp):
5718class DatetimeAdd(Func, IntervalOp):
5719    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimeadd'
class DatetimeSub(Func, IntervalOp):
5722class DatetimeSub(Func, IntervalOp):
5723    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimesub'
class DatetimeDiff(Func, TimeUnit):
5726class DatetimeDiff(Func, TimeUnit):
5727    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'datetimediff'
class DatetimeTrunc(Func, TimeUnit):
5730class DatetimeTrunc(Func, TimeUnit):
5731    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'datetimetrunc'
class DayOfWeek(Func):
5734class DayOfWeek(Func):
5735    _sql_names = ["DAY_OF_WEEK", "DAYOFWEEK"]
key = 'dayofweek'
class DayOfWeekIso(Func):
5740class DayOfWeekIso(Func):
5741    _sql_names = ["DAYOFWEEK_ISO", "ISODOW"]
key = 'dayofweekiso'
class DayOfMonth(Func):
5744class DayOfMonth(Func):
5745    _sql_names = ["DAY_OF_MONTH", "DAYOFMONTH"]
key = 'dayofmonth'
class DayOfYear(Func):
5748class DayOfYear(Func):
5749    _sql_names = ["DAY_OF_YEAR", "DAYOFYEAR"]
key = 'dayofyear'
class ToDays(Func):
5752class ToDays(Func):
5753    pass
key = 'todays'
class WeekOfYear(Func):
5756class WeekOfYear(Func):
5757    _sql_names = ["WEEK_OF_YEAR", "WEEKOFYEAR"]
key = 'weekofyear'
class MonthsBetween(Func):
5760class MonthsBetween(Func):
5761    arg_types = {"this": True, "expression": True, "roundoff": False}
arg_types = {'this': True, 'expression': True, 'roundoff': False}
key = 'monthsbetween'
class MakeInterval(Func):
5764class MakeInterval(Func):
5765    arg_types = {
5766        "year": False,
5767        "month": False,
5768        "day": False,
5769        "hour": False,
5770        "minute": False,
5771        "second": False,
5772    }
arg_types = {'year': False, 'month': False, 'day': False, 'hour': False, 'minute': False, 'second': False}
key = 'makeinterval'
class LastDay(Func, TimeUnit):
5775class LastDay(Func, TimeUnit):
5776    _sql_names = ["LAST_DAY", "LAST_DAY_OF_MONTH"]
5777    arg_types = {"this": True, "unit": False}
arg_types = {'this': True, 'unit': False}
key = 'lastday'
class Extract(Func):
5780class Extract(Func):
5781    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'extract'
class Exists(Func, SubqueryPredicate):
5784class Exists(Func, SubqueryPredicate):
5785    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'exists'
class Timestamp(Func):
5788class Timestamp(Func):
5789    arg_types = {"this": False, "zone": False, "with_tz": False}
arg_types = {'this': False, 'zone': False, 'with_tz': False}
key = 'timestamp'
class TimestampAdd(Func, TimeUnit):
5792class TimestampAdd(Func, TimeUnit):
5793    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampadd'
class TimestampSub(Func, TimeUnit):
5796class TimestampSub(Func, TimeUnit):
5797    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampsub'
class TimestampDiff(Func, TimeUnit):
5800class TimestampDiff(Func, TimeUnit):
5801    _sql_names = ["TIMESTAMPDIFF", "TIMESTAMP_DIFF"]
5802    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timestampdiff'
class TimestampTrunc(Func, TimeUnit):
5805class TimestampTrunc(Func, TimeUnit):
5806    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timestamptrunc'
class TimeAdd(Func, TimeUnit):
5809class TimeAdd(Func, TimeUnit):
5810    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timeadd'
class TimeSub(Func, TimeUnit):
5813class TimeSub(Func, TimeUnit):
5814    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timesub'
class TimeDiff(Func, TimeUnit):
5817class TimeDiff(Func, TimeUnit):
5818    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'timediff'
class TimeTrunc(Func, TimeUnit):
5821class TimeTrunc(Func, TimeUnit):
5822    arg_types = {"this": True, "unit": True, "zone": False}
arg_types = {'this': True, 'unit': True, 'zone': False}
key = 'timetrunc'
class DateFromParts(Func):
5825class DateFromParts(Func):
5826    _sql_names = ["DATE_FROM_PARTS", "DATEFROMPARTS"]
5827    arg_types = {"year": True, "month": True, "day": True}
arg_types = {'year': True, 'month': True, 'day': True}
key = 'datefromparts'
class TimeFromParts(Func):
5830class TimeFromParts(Func):
5831    _sql_names = ["TIME_FROM_PARTS", "TIMEFROMPARTS"]
5832    arg_types = {
5833        "hour": True,
5834        "min": True,
5835        "sec": True,
5836        "nano": False,
5837        "fractions": False,
5838        "precision": False,
5839    }
arg_types = {'hour': True, 'min': True, 'sec': True, 'nano': False, 'fractions': False, 'precision': False}
key = 'timefromparts'
class DateStrToDate(Func):
5842class DateStrToDate(Func):
5843    pass
key = 'datestrtodate'
class DateToDateStr(Func):
5846class DateToDateStr(Func):
5847    pass
key = 'datetodatestr'
class DateToDi(Func):
5850class DateToDi(Func):
5851    pass
key = 'datetodi'
class Date(Func):
5855class Date(Func):
5856    arg_types = {"this": False, "zone": False, "expressions": False}
5857    is_var_len_args = True
arg_types = {'this': False, 'zone': False, 'expressions': False}
is_var_len_args = True
key = 'date'
class Day(Func):
5860class Day(Func):
5861    pass
key = 'day'
class Decode(Func):
5864class Decode(Func):
5865    arg_types = {"this": True, "charset": True, "replace": False}
arg_types = {'this': True, 'charset': True, 'replace': False}
key = 'decode'
class DiToDate(Func):
5868class DiToDate(Func):
5869    pass
key = 'ditodate'
class Encode(Func):
5872class Encode(Func):
5873    arg_types = {"this": True, "charset": True}
arg_types = {'this': True, 'charset': True}
key = 'encode'
class Exp(Func):
5876class Exp(Func):
5877    pass
key = 'exp'
class Explode(Func, UDTF):
5881class Explode(Func, UDTF):
5882    arg_types = {"this": True, "expressions": False}
5883    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'explode'
class Inline(Func):
5887class Inline(Func):
5888    pass
key = 'inline'
class ExplodeOuter(Explode):
5891class ExplodeOuter(Explode):
5892    pass
key = 'explodeouter'
class Posexplode(Explode):
5895class Posexplode(Explode):
5896    pass
key = 'posexplode'
class PosexplodeOuter(Posexplode, ExplodeOuter):
5899class PosexplodeOuter(Posexplode, ExplodeOuter):
5900    pass
key = 'posexplodeouter'
class Unnest(Func, UDTF):
5903class Unnest(Func, UDTF):
5904    arg_types = {
5905        "expressions": True,
5906        "alias": False,
5907        "offset": False,
5908        "explode_array": False,
5909    }
5910
5911    @property
5912    def selects(self) -> t.List[Expression]:
5913        columns = super().selects
5914        offset = self.args.get("offset")
5915        if offset:
5916            columns = columns + [to_identifier("offset") if offset is True else offset]
5917        return columns
arg_types = {'expressions': True, 'alias': False, 'offset': False, 'explode_array': False}
selects: List[Expression]
5911    @property
5912    def selects(self) -> t.List[Expression]:
5913        columns = super().selects
5914        offset = self.args.get("offset")
5915        if offset:
5916            columns = columns + [to_identifier("offset") if offset is True else offset]
5917        return columns
key = 'unnest'
class Floor(Func):
5920class Floor(Func):
5921    arg_types = {"this": True, "decimals": False, "to": False}
arg_types = {'this': True, 'decimals': False, 'to': False}
key = 'floor'
class FromBase64(Func):
5924class FromBase64(Func):
5925    pass
key = 'frombase64'
class FeaturesAtTime(Func):
5928class FeaturesAtTime(Func):
5929    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):
5932class ToBase64(Func):
5933    pass
key = 'tobase64'
class FromISO8601Timestamp(Func):
5937class FromISO8601Timestamp(Func):
5938    _sql_names = ["FROM_ISO8601_TIMESTAMP"]
key = 'fromiso8601timestamp'
class GapFill(Func):
5941class GapFill(Func):
5942    arg_types = {
5943        "this": True,
5944        "ts_column": True,
5945        "bucket_width": True,
5946        "partitioning_columns": False,
5947        "value_columns": False,
5948        "origin": False,
5949        "ignore_nulls": False,
5950    }
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):
5954class GenerateDateArray(Func):
5955    arg_types = {"start": True, "end": True, "step": False}
arg_types = {'start': True, 'end': True, 'step': False}
key = 'generatedatearray'
class GenerateTimestampArray(Func):
5959class GenerateTimestampArray(Func):
5960    arg_types = {"start": True, "end": True, "step": True}
arg_types = {'start': True, 'end': True, 'step': True}
key = 'generatetimestamparray'
class Greatest(Func):
5963class Greatest(Func):
5964    arg_types = {"this": True, "expressions": False}
5965    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'greatest'
class OverflowTruncateBehavior(Expression):
5970class OverflowTruncateBehavior(Expression):
5971    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key = 'overflowtruncatebehavior'
class GroupConcat(AggFunc):
5974class GroupConcat(AggFunc):
5975    arg_types = {"this": True, "separator": False, "on_overflow": False}
arg_types = {'this': True, 'separator': False, 'on_overflow': False}
key = 'groupconcat'
class Hex(Func):
5978class Hex(Func):
5979    pass
key = 'hex'
class LowerHex(Hex):
5982class LowerHex(Hex):
5983    pass
key = 'lowerhex'
class And(Connector, Func):
5986class And(Connector, Func):
5987    pass
key = 'and'
class Or(Connector, Func):
5990class Or(Connector, Func):
5991    pass
key = 'or'
class Xor(Connector, Func):
5994class Xor(Connector, Func):
5995    arg_types = {"this": False, "expression": False, "expressions": False}
arg_types = {'this': False, 'expression': False, 'expressions': False}
key = 'xor'
class If(Func):
5998class If(Func):
5999    arg_types = {"this": True, "true": True, "false": False}
6000    _sql_names = ["IF", "IIF"]
arg_types = {'this': True, 'true': True, 'false': False}
key = 'if'
class Nullif(Func):
6003class Nullif(Func):
6004    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'nullif'
class Initcap(Func):
6007class Initcap(Func):
6008    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'initcap'
class IsAscii(Func):
6011class IsAscii(Func):
6012    pass
key = 'isascii'
class IsNan(Func):
6015class IsNan(Func):
6016    _sql_names = ["IS_NAN", "ISNAN"]
key = 'isnan'
class Int64(Func):
6020class Int64(Func):
6021    pass
key = 'int64'
class IsInf(Func):
6024class IsInf(Func):
6025    _sql_names = ["IS_INF", "ISINF"]
key = 'isinf'
class JSON(Expression):
6029class JSON(Expression):
6030    arg_types = {"this": False, "with": False, "unique": False}
arg_types = {'this': False, 'with': False, 'unique': False}
key = 'json'
class JSONPath(Expression):
6033class JSONPath(Expression):
6034    arg_types = {"expressions": True, "escape": False}
6035
6036    @property
6037    def output_name(self) -> str:
6038        last_segment = self.expressions[-1].this
6039        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
6036    @property
6037    def output_name(self) -> str:
6038        last_segment = self.expressions[-1].this
6039        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):
6042class JSONPathPart(Expression):
6043    arg_types = {}
arg_types = {}
key = 'jsonpathpart'
class JSONPathFilter(JSONPathPart):
6046class JSONPathFilter(JSONPathPart):
6047    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathfilter'
class JSONPathKey(JSONPathPart):
6050class JSONPathKey(JSONPathPart):
6051    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathkey'
class JSONPathRecursive(JSONPathPart):
6054class JSONPathRecursive(JSONPathPart):
6055    arg_types = {"this": False}
arg_types = {'this': False}
key = 'jsonpathrecursive'
class JSONPathRoot(JSONPathPart):
6058class JSONPathRoot(JSONPathPart):
6059    pass
key = 'jsonpathroot'
class JSONPathScript(JSONPathPart):
6062class JSONPathScript(JSONPathPart):
6063    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathscript'
class JSONPathSlice(JSONPathPart):
6066class JSONPathSlice(JSONPathPart):
6067    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key = 'jsonpathslice'
class JSONPathSelector(JSONPathPart):
6070class JSONPathSelector(JSONPathPart):
6071    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathselector'
class JSONPathSubscript(JSONPathPart):
6074class JSONPathSubscript(JSONPathPart):
6075    arg_types = {"this": True}
arg_types = {'this': True}
key = 'jsonpathsubscript'
class JSONPathUnion(JSONPathPart):
6078class JSONPathUnion(JSONPathPart):
6079    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonpathunion'
class JSONPathWildcard(JSONPathPart):
6082class JSONPathWildcard(JSONPathPart):
6083    pass
key = 'jsonpathwildcard'
class FormatJson(Expression):
6086class FormatJson(Expression):
6087    pass
key = 'formatjson'
class JSONKeyValue(Expression):
6090class JSONKeyValue(Expression):
6091    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonkeyvalue'
class JSONObject(Func):
6094class JSONObject(Func):
6095    arg_types = {
6096        "expressions": False,
6097        "null_handling": False,
6098        "unique_keys": False,
6099        "return_type": False,
6100        "encoding": False,
6101    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobject'
class JSONObjectAgg(AggFunc):
6104class JSONObjectAgg(AggFunc):
6105    arg_types = {
6106        "expressions": False,
6107        "null_handling": False,
6108        "unique_keys": False,
6109        "return_type": False,
6110        "encoding": False,
6111    }
arg_types = {'expressions': False, 'null_handling': False, 'unique_keys': False, 'return_type': False, 'encoding': False}
key = 'jsonobjectagg'
class JSONBObjectAgg(AggFunc):
6115class JSONBObjectAgg(AggFunc):
6116    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'jsonbobjectagg'
class JSONArray(Func):
6120class JSONArray(Func):
6121    arg_types = {
6122        "expressions": True,
6123        "null_handling": False,
6124        "return_type": False,
6125        "strict": False,
6126    }
arg_types = {'expressions': True, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarray'
class JSONArrayAgg(Func):
6130class JSONArrayAgg(Func):
6131    arg_types = {
6132        "this": True,
6133        "order": False,
6134        "null_handling": False,
6135        "return_type": False,
6136        "strict": False,
6137    }
arg_types = {'this': True, 'order': False, 'null_handling': False, 'return_type': False, 'strict': False}
key = 'jsonarrayagg'
class JSONExists(Func):
6140class JSONExists(Func):
6141    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):
6146class JSONColumnDef(Expression):
6147    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):
6150class JSONSchema(Expression):
6151    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'jsonschema'
class JSONValue(Expression):
6155class JSONValue(Expression):
6156    arg_types = {
6157        "this": True,
6158        "path": True,
6159        "returning": False,
6160        "on_condition": False,
6161    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key = 'jsonvalue'
class JSONValueArray(Func):
6164class JSONValueArray(Func):
6165    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'jsonvaluearray'
class JSONTable(Func):
6169class JSONTable(Func):
6170    arg_types = {
6171        "this": True,
6172        "schema": True,
6173        "path": False,
6174        "error_handling": False,
6175        "empty_handling": False,
6176    }
arg_types = {'this': True, 'schema': True, 'path': False, 'error_handling': False, 'empty_handling': False}
key = 'jsontable'
class ObjectInsert(Func):
6180class ObjectInsert(Func):
6181    arg_types = {
6182        "this": True,
6183        "key": True,
6184        "value": True,
6185        "update_flag": False,
6186    }
arg_types = {'this': True, 'key': True, 'value': True, 'update_flag': False}
key = 'objectinsert'
class OpenJSONColumnDef(Expression):
6189class OpenJSONColumnDef(Expression):
6190    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):
6193class OpenJSON(Func):
6194    arg_types = {"this": True, "path": False, "expressions": False}
arg_types = {'this': True, 'path': False, 'expressions': False}
key = 'openjson'
class JSONBContains(Binary, Func):
6197class JSONBContains(Binary, Func):
6198    _sql_names = ["JSONB_CONTAINS"]
key = 'jsonbcontains'
class JSONBExists(Func):
6201class JSONBExists(Func):
6202    arg_types = {"this": True, "path": True}
6203    _sql_names = ["JSONB_EXISTS"]
arg_types = {'this': True, 'path': True}
key = 'jsonbexists'
class JSONExtract(Binary, Func):
6206class JSONExtract(Binary, Func):
6207    arg_types = {
6208        "this": True,
6209        "expression": True,
6210        "only_json_types": False,
6211        "expressions": False,
6212        "variant_extract": False,
6213        "json_query": False,
6214        "option": False,
6215        "quote": False,
6216        "on_condition": False,
6217    }
6218    _sql_names = ["JSON_EXTRACT"]
6219    is_var_len_args = True
6220
6221    @property
6222    def output_name(self) -> str:
6223        return self.expression.output_name if not self.expressions else ""
arg_types = {'this': True, 'expression': True, 'only_json_types': False, 'expressions': False, 'variant_extract': False, 'json_query': False, 'option': False, 'quote': False, 'on_condition': False}
is_var_len_args = True
output_name: str
6221    @property
6222    def output_name(self) -> str:
6223        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):
6227class JSONExtractQuote(Expression):
6228    arg_types = {
6229        "option": True,
6230        "scalar": False,
6231    }
arg_types = {'option': True, 'scalar': False}
key = 'jsonextractquote'
class JSONExtractArray(Func):
6234class JSONExtractArray(Func):
6235    arg_types = {"this": True, "expression": False}
6236    _sql_names = ["JSON_EXTRACT_ARRAY"]
arg_types = {'this': True, 'expression': False}
key = 'jsonextractarray'
class JSONExtractScalar(Binary, Func):
6239class JSONExtractScalar(Binary, Func):
6240    arg_types = {"this": True, "expression": True, "only_json_types": False, "expressions": False}
6241    _sql_names = ["JSON_EXTRACT_SCALAR"]
6242    is_var_len_args = True
6243
6244    @property
6245    def output_name(self) -> str:
6246        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
6244    @property
6245    def output_name(self) -> str:
6246        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):
6249class JSONBExtract(Binary, Func):
6250    _sql_names = ["JSONB_EXTRACT"]
key = 'jsonbextract'
class JSONBExtractScalar(Binary, Func):
6253class JSONBExtractScalar(Binary, Func):
6254    _sql_names = ["JSONB_EXTRACT_SCALAR"]
key = 'jsonbextractscalar'
class JSONFormat(Func):
6257class JSONFormat(Func):
6258    arg_types = {"this": False, "options": False}
6259    _sql_names = ["JSON_FORMAT"]
arg_types = {'this': False, 'options': False}
key = 'jsonformat'
class JSONArrayContains(Binary, Predicate, Func):
6263class JSONArrayContains(Binary, Predicate, Func):
6264    _sql_names = ["JSON_ARRAY_CONTAINS"]
key = 'jsonarraycontains'
class ParseJSON(Func):
6267class ParseJSON(Func):
6268    # BigQuery, Snowflake have PARSE_JSON, Presto has JSON_PARSE
6269    # Snowflake also has TRY_PARSE_JSON, which is represented using `safe`
6270    _sql_names = ["PARSE_JSON", "JSON_PARSE"]
6271    arg_types = {"this": True, "expression": False, "safe": False}
arg_types = {'this': True, 'expression': False, 'safe': False}
key = 'parsejson'
class Least(Func):
6274class Least(Func):
6275    arg_types = {"this": True, "expressions": False}
6276    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'least'
class Left(Func):
6279class Left(Func):
6280    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'left'
class Length(Func):
6287class Length(Func):
6288    arg_types = {"this": True, "binary": False, "encoding": False}
6289    _sql_names = ["LENGTH", "LEN", "CHAR_LENGTH", "CHARACTER_LENGTH"]
arg_types = {'this': True, 'binary': False, 'encoding': False}
key = 'length'
class Levenshtein(Func):
6292class Levenshtein(Func):
6293    arg_types = {
6294        "this": True,
6295        "expression": False,
6296        "ins_cost": False,
6297        "del_cost": False,
6298        "sub_cost": False,
6299        "max_dist": False,
6300    }
arg_types = {'this': True, 'expression': False, 'ins_cost': False, 'del_cost': False, 'sub_cost': False, 'max_dist': False}
key = 'levenshtein'
class Ln(Func):
6303class Ln(Func):
6304    pass
key = 'ln'
class Log(Func):
6307class Log(Func):
6308    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'log'
class LogicalOr(AggFunc):
6311class LogicalOr(AggFunc):
6312    _sql_names = ["LOGICAL_OR", "BOOL_OR", "BOOLOR_AGG"]
key = 'logicalor'
class LogicalAnd(AggFunc):
6315class LogicalAnd(AggFunc):
6316    _sql_names = ["LOGICAL_AND", "BOOL_AND", "BOOLAND_AGG"]
key = 'logicaland'
class Lower(Func):
6319class Lower(Func):
6320    _sql_names = ["LOWER", "LCASE"]
key = 'lower'
class Map(Func):
6323class Map(Func):
6324    arg_types = {"keys": False, "values": False}
6325
6326    @property
6327    def keys(self) -> t.List[Expression]:
6328        keys = self.args.get("keys")
6329        return keys.expressions if keys else []
6330
6331    @property
6332    def values(self) -> t.List[Expression]:
6333        values = self.args.get("values")
6334        return values.expressions if values else []
arg_types = {'keys': False, 'values': False}
keys: List[Expression]
6326    @property
6327    def keys(self) -> t.List[Expression]:
6328        keys = self.args.get("keys")
6329        return keys.expressions if keys else []
values: List[Expression]
6331    @property
6332    def values(self) -> t.List[Expression]:
6333        values = self.args.get("values")
6334        return values.expressions if values else []
key = 'map'
class ToMap(Func):
6338class ToMap(Func):
6339    pass
key = 'tomap'
class MapFromEntries(Func):
6342class MapFromEntries(Func):
6343    pass
key = 'mapfromentries'
class ScopeResolution(Expression):
6347class ScopeResolution(Expression):
6348    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key = 'scoperesolution'
class Stream(Expression):
6351class Stream(Expression):
6352    pass
key = 'stream'
class StarMap(Func):
6355class StarMap(Func):
6356    pass
key = 'starmap'
class VarMap(Func):
6359class VarMap(Func):
6360    arg_types = {"keys": True, "values": True}
6361    is_var_len_args = True
6362
6363    @property
6364    def keys(self) -> t.List[Expression]:
6365        return self.args["keys"].expressions
6366
6367    @property
6368    def values(self) -> t.List[Expression]:
6369        return self.args["values"].expressions
arg_types = {'keys': True, 'values': True}
is_var_len_args = True
keys: List[Expression]
6363    @property
6364    def keys(self) -> t.List[Expression]:
6365        return self.args["keys"].expressions
values: List[Expression]
6367    @property
6368    def values(self) -> t.List[Expression]:
6369        return self.args["values"].expressions
key = 'varmap'
class MatchAgainst(Func):
6373class MatchAgainst(Func):
6374    arg_types = {"this": True, "expressions": True, "modifier": False}
arg_types = {'this': True, 'expressions': True, 'modifier': False}
key = 'matchagainst'
class Max(AggFunc):
6377class Max(AggFunc):
6378    arg_types = {"this": True, "expressions": False}
6379    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'max'
class MD5(Func):
6382class MD5(Func):
6383    _sql_names = ["MD5"]
key = 'md5'
class MD5Digest(Func):
6387class MD5Digest(Func):
6388    _sql_names = ["MD5_DIGEST"]
key = 'md5digest'
class Median(AggFunc):
6391class Median(AggFunc):
6392    pass
key = 'median'
class Min(AggFunc):
6395class Min(AggFunc):
6396    arg_types = {"this": True, "expressions": False}
6397    is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
is_var_len_args = True
key = 'min'
class Month(Func):
6400class Month(Func):
6401    pass
key = 'month'
class AddMonths(Func):
6404class AddMonths(Func):
6405    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'addmonths'
class Nvl2(Func):
6408class Nvl2(Func):
6409    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key = 'nvl2'
class Normalize(Func):
6412class Normalize(Func):
6413    arg_types = {"this": True, "form": False}
arg_types = {'this': True, 'form': False}
key = 'normalize'
class Overlay(Func):
6416class Overlay(Func):
6417    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):
6421class Predict(Func):
6422    arg_types = {"this": True, "expression": True, "params_struct": False}
arg_types = {'this': True, 'expression': True, 'params_struct': False}
key = 'predict'
class Pow(Binary, Func):
6425class Pow(Binary, Func):
6426    _sql_names = ["POWER", "POW"]
key = 'pow'
class PercentileCont(AggFunc):
6429class PercentileCont(AggFunc):
6430    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentilecont'
class PercentileDisc(AggFunc):
6433class PercentileDisc(AggFunc):
6434    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'percentiledisc'
class Quantile(AggFunc):
6437class Quantile(AggFunc):
6438    arg_types = {"this": True, "quantile": True}
arg_types = {'this': True, 'quantile': True}
key = 'quantile'
class ApproxQuantile(Quantile):
6441class ApproxQuantile(Quantile):
6442    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):
6445class Quarter(Func):
6446    pass
key = 'quarter'
class Rand(Func):
6451class Rand(Func):
6452    _sql_names = ["RAND", "RANDOM"]
6453    arg_types = {"this": False, "lower": False, "upper": False}
arg_types = {'this': False, 'lower': False, 'upper': False}
key = 'rand'
class Randn(Func):
6456class Randn(Func):
6457    arg_types = {"this": False}
arg_types = {'this': False}
key = 'randn'
class RangeN(Func):
6460class RangeN(Func):
6461    arg_types = {"this": True, "expressions": True, "each": False}
arg_types = {'this': True, 'expressions': True, 'each': False}
key = 'rangen'
class ReadCSV(Func):
6464class ReadCSV(Func):
6465    _sql_names = ["READ_CSV"]
6466    is_var_len_args = True
6467    arg_types = {"this": True, "expressions": False}
is_var_len_args = True
arg_types = {'this': True, 'expressions': False}
key = 'readcsv'
class Reduce(Func):
6470class Reduce(Func):
6471    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):
6474class RegexpExtract(Func):
6475    arg_types = {
6476        "this": True,
6477        "expression": True,
6478        "position": False,
6479        "occurrence": False,
6480        "parameters": False,
6481        "group": False,
6482    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextract'
class RegexpExtractAll(Func):
6485class RegexpExtractAll(Func):
6486    arg_types = {
6487        "this": True,
6488        "expression": True,
6489        "position": False,
6490        "occurrence": False,
6491        "parameters": False,
6492        "group": False,
6493    }
arg_types = {'this': True, 'expression': True, 'position': False, 'occurrence': False, 'parameters': False, 'group': False}
key = 'regexpextractall'
class RegexpReplace(Func):
6496class RegexpReplace(Func):
6497    arg_types = {
6498        "this": True,
6499        "expression": True,
6500        "replacement": False,
6501        "position": False,
6502        "occurrence": False,
6503        "modifiers": False,
6504    }
arg_types = {'this': True, 'expression': True, 'replacement': False, 'position': False, 'occurrence': False, 'modifiers': False}
key = 'regexpreplace'
class RegexpLike(Binary, Func):
6507class RegexpLike(Binary, Func):
6508    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexplike'
class RegexpILike(Binary, Func):
6511class RegexpILike(Binary, Func):
6512    arg_types = {"this": True, "expression": True, "flag": False}
arg_types = {'this': True, 'expression': True, 'flag': False}
key = 'regexpilike'
class RegexpSplit(Func):
6517class RegexpSplit(Func):
6518    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'regexpsplit'
class Repeat(Func):
6521class Repeat(Func):
6522    arg_types = {"this": True, "times": True}
arg_types = {'this': True, 'times': True}
key = 'repeat'
class Round(Func):
6527class Round(Func):
6528    arg_types = {"this": True, "decimals": False, "truncate": False}
arg_types = {'this': True, 'decimals': False, 'truncate': False}
key = 'round'
class RowNumber(Func):
6531class RowNumber(Func):
6532    arg_types = {"this": False}
arg_types = {'this': False}
key = 'rownumber'
class SafeDivide(Func):
6535class SafeDivide(Func):
6536    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'safedivide'
class SHA(Func):
6539class SHA(Func):
6540    _sql_names = ["SHA", "SHA1"]
key = 'sha'
class SHA2(Func):
6543class SHA2(Func):
6544    _sql_names = ["SHA2"]
6545    arg_types = {"this": True, "length": False}
arg_types = {'this': True, 'length': False}
key = 'sha2'
class Sign(Func):
6548class Sign(Func):
6549    _sql_names = ["SIGN", "SIGNUM"]
key = 'sign'
class SortArray(Func):
6552class SortArray(Func):
6553    arg_types = {"this": True, "asc": False}
arg_types = {'this': True, 'asc': False}
key = 'sortarray'
class Split(Func):
6556class Split(Func):
6557    arg_types = {"this": True, "expression": True, "limit": False}
arg_types = {'this': True, 'expression': True, 'limit': False}
key = 'split'
class SplitPart(Func):
6561class SplitPart(Func):
6562    arg_types = {"this": True, "delimiter": True, "part_index": True}
arg_types = {'this': True, 'delimiter': True, 'part_index': True}
key = 'splitpart'
class Substring(Func):
6567class Substring(Func):
6568    _sql_names = ["SUBSTRING", "SUBSTR"]
6569    arg_types = {"this": True, "start": False, "length": False}
arg_types = {'this': True, 'start': False, 'length': False}
key = 'substring'
class StandardHash(Func):
6572class StandardHash(Func):
6573    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'standardhash'
class StartsWith(Func):
6576class StartsWith(Func):
6577    _sql_names = ["STARTS_WITH", "STARTSWITH"]
6578    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'startswith'
class StrPosition(Func):
6581class StrPosition(Func):
6582    arg_types = {
6583        "this": True,
6584        "substr": True,
6585        "position": False,
6586        "occurrence": False,
6587    }
arg_types = {'this': True, 'substr': True, 'position': False, 'occurrence': False}
key = 'strposition'
class StrToDate(Func):
6590class StrToDate(Func):
6591    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'strtodate'
class StrToTime(Func):
6594class StrToTime(Func):
6595    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):
6600class StrToUnix(Func):
6601    arg_types = {"this": False, "format": False}
arg_types = {'this': False, 'format': False}
key = 'strtounix'
class StrToMap(Func):
6606class StrToMap(Func):
6607    arg_types = {
6608        "this": True,
6609        "pair_delim": False,
6610        "key_value_delim": False,
6611        "duplicate_resolution_callback": False,
6612    }
arg_types = {'this': True, 'pair_delim': False, 'key_value_delim': False, 'duplicate_resolution_callback': False}
key = 'strtomap'
class NumberToStr(Func):
6615class NumberToStr(Func):
6616    arg_types = {"this": True, "format": True, "culture": False}
arg_types = {'this': True, 'format': True, 'culture': False}
key = 'numbertostr'
class FromBase(Func):
6619class FromBase(Func):
6620    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'frombase'
class Struct(Func):
6623class Struct(Func):
6624    arg_types = {"expressions": False}
6625    is_var_len_args = True
arg_types = {'expressions': False}
is_var_len_args = True
key = 'struct'
class StructExtract(Func):
6628class StructExtract(Func):
6629    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'structextract'
class Stuff(Func):
6634class Stuff(Func):
6635    _sql_names = ["STUFF", "INSERT"]
6636    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):
6639class Sum(AggFunc):
6640    pass
key = 'sum'
class Sqrt(Func):
6643class Sqrt(Func):
6644    pass
key = 'sqrt'
class Stddev(AggFunc):
6647class Stddev(AggFunc):
6648    _sql_names = ["STDDEV", "STDEV"]
key = 'stddev'
class StddevPop(AggFunc):
6651class StddevPop(AggFunc):
6652    pass
key = 'stddevpop'
class StddevSamp(AggFunc):
6655class StddevSamp(AggFunc):
6656    pass
key = 'stddevsamp'
class Time(Func):
6660class Time(Func):
6661    arg_types = {"this": False, "zone": False}
arg_types = {'this': False, 'zone': False}
key = 'time'
class TimeToStr(Func):
6664class TimeToStr(Func):
6665    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):
6668class TimeToTimeStr(Func):
6669    pass
key = 'timetotimestr'
class TimeToUnix(Func):
6672class TimeToUnix(Func):
6673    pass
key = 'timetounix'
class TimeStrToDate(Func):
6676class TimeStrToDate(Func):
6677    pass
key = 'timestrtodate'
class TimeStrToTime(Func):
6680class TimeStrToTime(Func):
6681    arg_types = {"this": True, "zone": False}
arg_types = {'this': True, 'zone': False}
key = 'timestrtotime'
class TimeStrToUnix(Func):
6684class TimeStrToUnix(Func):
6685    pass
key = 'timestrtounix'
class Trim(Func):
6688class Trim(Func):
6689    arg_types = {
6690        "this": True,
6691        "expression": False,
6692        "position": False,
6693        "collation": False,
6694    }
arg_types = {'this': True, 'expression': False, 'position': False, 'collation': False}
key = 'trim'
class TsOrDsAdd(Func, TimeUnit):
6697class TsOrDsAdd(Func, TimeUnit):
6698    # return_type is used to correctly cast the arguments of this expression when transpiling it
6699    arg_types = {"this": True, "expression": True, "unit": False, "return_type": False}
6700
6701    @property
6702    def return_type(self) -> DataType:
6703        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
6701    @property
6702    def return_type(self) -> DataType:
6703        return DataType.build(self.args.get("return_type") or DataType.Type.DATE)
key = 'tsordsadd'
class TsOrDsDiff(Func, TimeUnit):
6706class TsOrDsDiff(Func, TimeUnit):
6707    arg_types = {"this": True, "expression": True, "unit": False}
arg_types = {'this': True, 'expression': True, 'unit': False}
key = 'tsordsdiff'
class TsOrDsToDateStr(Func):
6710class TsOrDsToDateStr(Func):
6711    pass
key = 'tsordstodatestr'
class TsOrDsToDate(Func):
6714class TsOrDsToDate(Func):
6715    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstodate'
class TsOrDsToDatetime(Func):
6718class TsOrDsToDatetime(Func):
6719    pass
key = 'tsordstodatetime'
class TsOrDsToTime(Func):
6722class TsOrDsToTime(Func):
6723    arg_types = {"this": True, "format": False, "safe": False}
arg_types = {'this': True, 'format': False, 'safe': False}
key = 'tsordstotime'
class TsOrDsToTimestamp(Func):
6726class TsOrDsToTimestamp(Func):
6727    pass
key = 'tsordstotimestamp'
class TsOrDiToDi(Func):
6730class TsOrDiToDi(Func):
6731    pass
key = 'tsorditodi'
class Unhex(Func):
6734class Unhex(Func):
6735    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'unhex'
class Unicode(Func):
6738class Unicode(Func):
6739    pass
key = 'unicode'
class UnixDate(Func):
6743class UnixDate(Func):
6744    pass
key = 'unixdate'
class UnixToStr(Func):
6747class UnixToStr(Func):
6748    arg_types = {"this": True, "format": False}
arg_types = {'this': True, 'format': False}
key = 'unixtostr'
class UnixToTime(Func):
6753class UnixToTime(Func):
6754    arg_types = {
6755        "this": True,
6756        "scale": False,
6757        "zone": False,
6758        "hours": False,
6759        "minutes": False,
6760        "format": False,
6761    }
6762
6763    SECONDS = Literal.number(0)
6764    DECIS = Literal.number(1)
6765    CENTIS = Literal.number(2)
6766    MILLIS = Literal.number(3)
6767    DECIMILLIS = Literal.number(4)
6768    CENTIMILLIS = Literal.number(5)
6769    MICROS = Literal.number(6)
6770    DECIMICROS = Literal.number(7)
6771    CENTIMICROS = Literal.number(8)
6772    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):
6775class UnixToTimeStr(Func):
6776    pass
key = 'unixtotimestr'
class UnixSeconds(Func):
6779class UnixSeconds(Func):
6780    pass
key = 'unixseconds'
class Uuid(Func):
6783class Uuid(Func):
6784    _sql_names = ["UUID", "GEN_RANDOM_UUID", "GENERATE_UUID", "UUID_STRING"]
6785
6786    arg_types = {"this": False, "name": False}
arg_types = {'this': False, 'name': False}
key = 'uuid'
class TimestampFromParts(Func):
6789class TimestampFromParts(Func):
6790    _sql_names = ["TIMESTAMP_FROM_PARTS", "TIMESTAMPFROMPARTS"]
6791    arg_types = {
6792        "year": True,
6793        "month": True,
6794        "day": True,
6795        "hour": True,
6796        "min": True,
6797        "sec": True,
6798        "nano": False,
6799        "zone": False,
6800        "milli": False,
6801    }
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):
6804class Upper(Func):
6805    _sql_names = ["UPPER", "UCASE"]
key = 'upper'
class Corr(Binary, AggFunc):
6808class Corr(Binary, AggFunc):
6809    pass
key = 'corr'
class Variance(AggFunc):
6812class Variance(AggFunc):
6813    _sql_names = ["VARIANCE", "VARIANCE_SAMP", "VAR_SAMP"]
key = 'variance'
class VariancePop(AggFunc):
6816class VariancePop(AggFunc):
6817    _sql_names = ["VARIANCE_POP", "VAR_POP"]
key = 'variancepop'
class CovarSamp(Binary, AggFunc):
6820class CovarSamp(Binary, AggFunc):
6821    pass
key = 'covarsamp'
class CovarPop(Binary, AggFunc):
6824class CovarPop(Binary, AggFunc):
6825    pass
key = 'covarpop'
class Week(Func):
6828class Week(Func):
6829    arg_types = {"this": True, "mode": False}
arg_types = {'this': True, 'mode': False}
key = 'week'
class XMLElement(Func):
6832class XMLElement(Func):
6833    _sql_names = ["XMLELEMENT"]
6834    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'xmlelement'
class XMLTable(Func):
6837class XMLTable(Func):
6838    arg_types = {
6839        "this": True,
6840        "namespaces": False,
6841        "passing": False,
6842        "columns": False,
6843        "by_ref": False,
6844    }
arg_types = {'this': True, 'namespaces': False, 'passing': False, 'columns': False, 'by_ref': False}
key = 'xmltable'
class XMLNamespace(Expression):
6847class XMLNamespace(Expression):
6848    pass
key = 'xmlnamespace'
class Year(Func):
6851class Year(Func):
6852    pass
key = 'year'
class Use(Expression):
6855class Use(Expression):
6856    arg_types = {"this": False, "expressions": False, "kind": False}
arg_types = {'this': False, 'expressions': False, 'kind': False}
key = 'use'
class Merge(DML):
6859class Merge(DML):
6860    arg_types = {
6861        "this": True,
6862        "using": True,
6863        "on": True,
6864        "whens": True,
6865        "with": False,
6866        "returning": False,
6867    }
arg_types = {'this': True, 'using': True, 'on': True, 'whens': True, 'with': False, 'returning': False}
key = 'merge'
class When(Expression):
6870class When(Expression):
6871    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):
6874class Whens(Expression):
6875    """Wraps around one or more WHEN [NOT] MATCHED [...] clauses."""
6876
6877    arg_types = {"expressions": True}

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

arg_types = {'expressions': True}
key = 'whens'
class NextValueFor(Func):
6882class NextValueFor(Func):
6883    arg_types = {"this": True, "order": False}
arg_types = {'this': True, 'order': False}
key = 'nextvaluefor'
class Semicolon(Expression):
6888class Semicolon(Expression):
6889    arg_types = {}
arg_types = {}
key = 'semicolon'
ALL_FUNCTIONS = [<class 'Abs'>, <class 'AddMonths'>, <class 'And'>, <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 'Or'>, <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'>, 'AND': <class 'And'>, 'ANONYMOUS_AGG_FUNC': <class 'AnonymousAggFunc'>, 'ANY_VALUE': <class 'AnyValue'>, 'APPLY': <class 'Apply'>, 'APPROX_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_COUNT_DISTINCT': <class 'ApproxDistinct'>, 'APPROX_QUANTILE': <class 'ApproxQuantile'>, 'APPROX_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'>, 'OR': <class 'Or'>, '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:
6929def maybe_parse(
6930    sql_or_expression: ExpOrStr,
6931    *,
6932    into: t.Optional[IntoType] = None,
6933    dialect: DialectType = None,
6934    prefix: t.Optional[str] = None,
6935    copy: bool = False,
6936    **opts,
6937) -> Expression:
6938    """Gracefully handle a possible string or expression.
6939
6940    Example:
6941        >>> maybe_parse("1")
6942        Literal(this=1, is_string=False)
6943        >>> maybe_parse(to_identifier("x"))
6944        Identifier(this=x, quoted=False)
6945
6946    Args:
6947        sql_or_expression: the SQL code string or an expression
6948        into: the SQLGlot Expression to parse into
6949        dialect: the dialect used to parse the input expressions (in the case that an
6950            input expression is a SQL string).
6951        prefix: a string to prefix the sql with before it gets parsed
6952            (automatically includes a space)
6953        copy: whether to copy the expression.
6954        **opts: other options to use to parse the input expressions (again, in the case
6955            that an input expression is a SQL string).
6956
6957    Returns:
6958        Expression: the parsed or given expression.
6959    """
6960    if isinstance(sql_or_expression, Expression):
6961        if copy:
6962            return sql_or_expression.copy()
6963        return sql_or_expression
6964
6965    if sql_or_expression is None:
6966        raise ParseError("SQL cannot be None")
6967
6968    import sqlglot
6969
6970    sql = str(sql_or_expression)
6971    if prefix:
6972        sql = f"{prefix} {sql}"
6973
6974    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):
6985def maybe_copy(instance, copy=True):
6986    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:
7234def union(
7235    *expressions: ExpOrStr,
7236    distinct: bool = True,
7237    dialect: DialectType = None,
7238    copy: bool = True,
7239    **opts,
7240) -> Union:
7241    """
7242    Initializes a syntax tree for the `UNION` operation.
7243
7244    Example:
7245        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
7246        'SELECT * FROM foo UNION SELECT * FROM bla'
7247
7248    Args:
7249        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
7250            If `Expression` instances are passed, they will be used as-is.
7251        distinct: set the DISTINCT flag if and only if this is true.
7252        dialect: the dialect used to parse the input expression.
7253        copy: whether to copy the expression.
7254        opts: other options to use to parse the input expressions.
7255
7256    Returns:
7257        The new Union instance.
7258    """
7259    assert len(expressions) >= 2, "At least two expressions are required by `union`."
7260    return _apply_set_operation(
7261        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
7262    )

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

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

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:
7327def select(*expressions: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7328    """
7329    Initializes a syntax tree from one or multiple SELECT expressions.
7330
7331    Example:
7332        >>> select("col1", "col2").from_("tbl").sql()
7333        'SELECT col1, col2 FROM tbl'
7334
7335    Args:
7336        *expressions: the SQL code string to parse as the expressions of a
7337            SELECT statement. If an Expression instance is passed, this is used as-is.
7338        dialect: the dialect used to parse the input expressions (in the case that an
7339            input expression is a SQL string).
7340        **opts: other options to use to parse the input expressions (again, in the case
7341            that an input expression is a SQL string).
7342
7343    Returns:
7344        Select: the syntax tree for the SELECT statement.
7345    """
7346    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:
7349def from_(expression: ExpOrStr, dialect: DialectType = None, **opts) -> Select:
7350    """
7351    Initializes a syntax tree from a FROM expression.
7352
7353    Example:
7354        >>> from_("tbl").select("col1", "col2").sql()
7355        'SELECT col1, col2 FROM tbl'
7356
7357    Args:
7358        *expression: the SQL code string to parse as the FROM expressions of a
7359            SELECT statement. If an Expression instance is passed, this is used as-is.
7360        dialect: the dialect used to parse the input expression (in the case that the
7361            input expression is a SQL string).
7362        **opts: other options to use to parse the input expressions (again, in the case
7363            that the input expression is a SQL string).
7364
7365    Returns:
7366        Select: the syntax tree for the SELECT statement.
7367    """
7368    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:
7371def update(
7372    table: str | Table,
7373    properties: t.Optional[dict] = None,
7374    where: t.Optional[ExpOrStr] = None,
7375    from_: t.Optional[ExpOrStr] = None,
7376    with_: t.Optional[t.Dict[str, ExpOrStr]] = None,
7377    dialect: DialectType = None,
7378    **opts,
7379) -> Update:
7380    """
7381    Creates an update statement.
7382
7383    Example:
7384        >>> 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()
7385        "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"
7386
7387    Args:
7388        properties: dictionary of properties to SET which are
7389            auto converted to sql objects eg None -> NULL
7390        where: sql conditional parsed into a WHERE statement
7391        from_: sql statement parsed into a FROM statement
7392        with_: dictionary of CTE aliases / select statements to include in a WITH clause.
7393        dialect: the dialect used to parse the input expressions.
7394        **opts: other options to use to parse the input expressions.
7395
7396    Returns:
7397        Update: the syntax tree for the UPDATE statement.
7398    """
7399    update_expr = Update(this=maybe_parse(table, into=Table, dialect=dialect))
7400    if properties:
7401        update_expr.set(
7402            "expressions",
7403            [
7404                EQ(this=maybe_parse(k, dialect=dialect, **opts), expression=convert(v))
7405                for k, v in properties.items()
7406            ],
7407        )
7408    if from_:
7409        update_expr.set(
7410            "from",
7411            maybe_parse(from_, into=From, dialect=dialect, prefix="FROM", **opts),
7412        )
7413    if isinstance(where, Condition):
7414        where = Where(this=where)
7415    if where:
7416        update_expr.set(
7417            "where",
7418            maybe_parse(where, into=Where, dialect=dialect, prefix="WHERE", **opts),
7419        )
7420    if with_:
7421        cte_list = [
7422            alias_(CTE(this=maybe_parse(qry, dialect=dialect, **opts)), alias, table=True)
7423            for alias, qry in with_.items()
7424        ]
7425        update_expr.set(
7426            "with",
7427            With(expressions=cte_list),
7428        )
7429    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:
7432def delete(
7433    table: ExpOrStr,
7434    where: t.Optional[ExpOrStr] = None,
7435    returning: t.Optional[ExpOrStr] = None,
7436    dialect: DialectType = None,
7437    **opts,
7438) -> Delete:
7439    """
7440    Builds a delete statement.
7441
7442    Example:
7443        >>> delete("my_table", where="id > 1").sql()
7444        'DELETE FROM my_table WHERE id > 1'
7445
7446    Args:
7447        where: sql conditional parsed into a WHERE statement
7448        returning: sql conditional parsed into a RETURNING statement
7449        dialect: the dialect used to parse the input expressions.
7450        **opts: other options to use to parse the input expressions.
7451
7452    Returns:
7453        Delete: the syntax tree for the DELETE statement.
7454    """
7455    delete_expr = Delete().delete(table, dialect=dialect, copy=False, **opts)
7456    if where:
7457        delete_expr = delete_expr.where(where, dialect=dialect, copy=False, **opts)
7458    if returning:
7459        delete_expr = delete_expr.returning(returning, dialect=dialect, copy=False, **opts)
7460    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:
7463def insert(
7464    expression: ExpOrStr,
7465    into: ExpOrStr,
7466    columns: t.Optional[t.Sequence[str | Identifier]] = None,
7467    overwrite: t.Optional[bool] = None,
7468    returning: t.Optional[ExpOrStr] = None,
7469    dialect: DialectType = None,
7470    copy: bool = True,
7471    **opts,
7472) -> Insert:
7473    """
7474    Builds an INSERT statement.
7475
7476    Example:
7477        >>> insert("VALUES (1, 2, 3)", "tbl").sql()
7478        'INSERT INTO tbl VALUES (1, 2, 3)'
7479
7480    Args:
7481        expression: the sql string or expression of the INSERT statement
7482        into: the tbl to insert data to.
7483        columns: optionally the table's column names.
7484        overwrite: whether to INSERT OVERWRITE or not.
7485        returning: sql conditional parsed into a RETURNING statement
7486        dialect: the dialect used to parse the input expressions.
7487        copy: whether to copy the expression.
7488        **opts: other options to use to parse the input expressions.
7489
7490    Returns:
7491        Insert: the syntax tree for the INSERT statement.
7492    """
7493    expr = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7494    this: Table | Schema = maybe_parse(into, into=Table, dialect=dialect, copy=copy, **opts)
7495
7496    if columns:
7497        this = Schema(this=this, expressions=[to_identifier(c, copy=copy) for c in columns])
7498
7499    insert = Insert(this=this, expression=expr, overwrite=overwrite)
7500
7501    if returning:
7502        insert = insert.returning(returning, dialect=dialect, copy=False, **opts)
7503
7504    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:
7507def merge(
7508    *when_exprs: ExpOrStr,
7509    into: ExpOrStr,
7510    using: ExpOrStr,
7511    on: ExpOrStr,
7512    returning: t.Optional[ExpOrStr] = None,
7513    dialect: DialectType = None,
7514    copy: bool = True,
7515    **opts,
7516) -> Merge:
7517    """
7518    Builds a MERGE statement.
7519
7520    Example:
7521        >>> merge("WHEN MATCHED THEN UPDATE SET col1 = source_table.col1",
7522        ...       "WHEN NOT MATCHED THEN INSERT (col1) VALUES (source_table.col1)",
7523        ...       into="my_table",
7524        ...       using="source_table",
7525        ...       on="my_table.id = source_table.id").sql()
7526        '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)'
7527
7528    Args:
7529        *when_exprs: The WHEN clauses specifying actions for matched and unmatched rows.
7530        into: The target table to merge data into.
7531        using: The source table to merge data from.
7532        on: The join condition for the merge.
7533        returning: The columns to return from the merge.
7534        dialect: The dialect used to parse the input expressions.
7535        copy: Whether to copy the expression.
7536        **opts: Other options to use to parse the input expressions.
7537
7538    Returns:
7539        Merge: The syntax tree for the MERGE statement.
7540    """
7541    expressions: t.List[Expression] = []
7542    for when_expr in when_exprs:
7543        expression = maybe_parse(when_expr, dialect=dialect, copy=copy, into=Whens, **opts)
7544        expressions.extend([expression] if isinstance(expression, When) else expression.expressions)
7545
7546    merge = Merge(
7547        this=maybe_parse(into, dialect=dialect, copy=copy, **opts),
7548        using=maybe_parse(using, dialect=dialect, copy=copy, **opts),
7549        on=maybe_parse(on, dialect=dialect, copy=copy, **opts),
7550        whens=Whens(expressions=expressions),
7551    )
7552    if returning:
7553        merge = merge.returning(returning, dialect=dialect, copy=False, **opts)
7554
7555    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:
7558def condition(
7559    expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts
7560) -> Condition:
7561    """
7562    Initialize a logical condition expression.
7563
7564    Example:
7565        >>> condition("x=1").sql()
7566        'x = 1'
7567
7568        This is helpful for composing larger logical syntax trees:
7569        >>> where = condition("x=1")
7570        >>> where = where.and_("y=1")
7571        >>> Select().from_("tbl").select("*").where(where).sql()
7572        'SELECT * FROM tbl WHERE x = 1 AND y = 1'
7573
7574    Args:
7575        *expression: the SQL code string to parse.
7576            If an Expression instance is passed, this is used as-is.
7577        dialect: the dialect used to parse the input expression (in the case that the
7578            input expression is a SQL string).
7579        copy: Whether to copy `expression` (only applies to expressions).
7580        **opts: other options to use to parse the input expressions (again, in the case
7581            that the input expression is a SQL string).
7582
7583    Returns:
7584        The new Condition instance
7585    """
7586    return maybe_parse(
7587        expression,
7588        into=Condition,
7589        dialect=dialect,
7590        copy=copy,
7591        **opts,
7592    )

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:
7595def and_(
7596    *expressions: t.Optional[ExpOrStr],
7597    dialect: DialectType = None,
7598    copy: bool = True,
7599    wrap: bool = True,
7600    **opts,
7601) -> Condition:
7602    """
7603    Combine multiple conditions with an AND logical operator.
7604
7605    Example:
7606        >>> and_("x=1", and_("y=1", "z=1")).sql()
7607        'x = 1 AND (y = 1 AND z = 1)'
7608
7609    Args:
7610        *expressions: the SQL code strings to parse.
7611            If an Expression instance is passed, this is used as-is.
7612        dialect: the dialect used to parse the input expression.
7613        copy: whether to copy `expressions` (only applies to Expressions).
7614        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7615            precedence issues, but can be turned off when the produced AST is too deep and
7616            causes recursion-related issues.
7617        **opts: other options to use to parse the input expressions.
7618
7619    Returns:
7620        The new condition
7621    """
7622    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:
7625def or_(
7626    *expressions: t.Optional[ExpOrStr],
7627    dialect: DialectType = None,
7628    copy: bool = True,
7629    wrap: bool = True,
7630    **opts,
7631) -> Condition:
7632    """
7633    Combine multiple conditions with an OR logical operator.
7634
7635    Example:
7636        >>> or_("x=1", or_("y=1", "z=1")).sql()
7637        'x = 1 OR (y = 1 OR z = 1)'
7638
7639    Args:
7640        *expressions: the SQL code strings to parse.
7641            If an Expression instance is passed, this is used as-is.
7642        dialect: the dialect used to parse the input expression.
7643        copy: whether to copy `expressions` (only applies to Expressions).
7644        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7645            precedence issues, but can be turned off when the produced AST is too deep and
7646            causes recursion-related issues.
7647        **opts: other options to use to parse the input expressions.
7648
7649    Returns:
7650        The new condition
7651    """
7652    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:
7655def xor(
7656    *expressions: t.Optional[ExpOrStr],
7657    dialect: DialectType = None,
7658    copy: bool = True,
7659    wrap: bool = True,
7660    **opts,
7661) -> Condition:
7662    """
7663    Combine multiple conditions with an XOR logical operator.
7664
7665    Example:
7666        >>> xor("x=1", xor("y=1", "z=1")).sql()
7667        'x = 1 XOR (y = 1 XOR z = 1)'
7668
7669    Args:
7670        *expressions: the SQL code strings to parse.
7671            If an Expression instance is passed, this is used as-is.
7672        dialect: the dialect used to parse the input expression.
7673        copy: whether to copy `expressions` (only applies to Expressions).
7674        wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
7675            precedence issues, but can be turned off when the produced AST is too deep and
7676            causes recursion-related issues.
7677        **opts: other options to use to parse the input expressions.
7678
7679    Returns:
7680        The new condition
7681    """
7682    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:
7685def not_(expression: ExpOrStr, dialect: DialectType = None, copy: bool = True, **opts) -> Not:
7686    """
7687    Wrap a condition with a NOT operator.
7688
7689    Example:
7690        >>> not_("this_suit='black'").sql()
7691        "NOT this_suit = 'black'"
7692
7693    Args:
7694        expression: the SQL code string to parse.
7695            If an Expression instance is passed, this is used as-is.
7696        dialect: the dialect used to parse the input expression.
7697        copy: whether to copy the expression or not.
7698        **opts: other options to use to parse the input expressions.
7699
7700    Returns:
7701        The new condition.
7702    """
7703    this = condition(
7704        expression,
7705        dialect=dialect,
7706        copy=copy,
7707        **opts,
7708    )
7709    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:
7712def paren(expression: ExpOrStr, copy: bool = True) -> Paren:
7713    """
7714    Wrap an expression in parentheses.
7715
7716    Example:
7717        >>> paren("5 + 3").sql()
7718        '(5 + 3)'
7719
7720    Args:
7721        expression: the SQL code string to parse.
7722            If an Expression instance is passed, this is used as-is.
7723        copy: whether to copy the expression or not.
7724
7725    Returns:
7726        The wrapped expression.
7727    """
7728    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):
7744def to_identifier(name, quoted=None, copy=True):
7745    """Builds an identifier.
7746
7747    Args:
7748        name: The name to turn into an identifier.
7749        quoted: Whether to force quote the identifier.
7750        copy: Whether to copy name if it's an Identifier.
7751
7752    Returns:
7753        The identifier ast node.
7754    """
7755
7756    if name is None:
7757        return None
7758
7759    if isinstance(name, Identifier):
7760        identifier = maybe_copy(name, copy)
7761    elif isinstance(name, str):
7762        identifier = Identifier(
7763            this=name,
7764            quoted=not SAFE_IDENTIFIER_RE.match(name) if quoted is None else quoted,
7765        )
7766    else:
7767        raise ValueError(f"Name needs to be a string or an Identifier, got: {name.__class__}")
7768    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:
7771def parse_identifier(name: str | Identifier, dialect: DialectType = None) -> Identifier:
7772    """
7773    Parses a given string into an identifier.
7774
7775    Args:
7776        name: The name to parse into an identifier.
7777        dialect: The dialect to parse against.
7778
7779    Returns:
7780        The identifier ast node.
7781    """
7782    try:
7783        expression = maybe_parse(name, dialect=dialect, into=Identifier)
7784    except (ParseError, TokenError):
7785        expression = to_identifier(name)
7786
7787    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:
7793def to_interval(interval: str | Literal) -> Interval:
7794    """Builds an interval expression from a string like '1 day' or '5 months'."""
7795    if isinstance(interval, Literal):
7796        if not interval.is_string:
7797            raise ValueError("Invalid interval string.")
7798
7799        interval = interval.this
7800
7801    interval = maybe_parse(f"INTERVAL {interval}")
7802    assert isinstance(interval, Interval)
7803    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:
7806def to_table(
7807    sql_path: str | Table, dialect: DialectType = None, copy: bool = True, **kwargs
7808) -> Table:
7809    """
7810    Create a table expression from a `[catalog].[schema].[table]` sql path. Catalog and schema are optional.
7811    If a table is passed in then that table is returned.
7812
7813    Args:
7814        sql_path: a `[catalog].[schema].[table]` string.
7815        dialect: the source dialect according to which the table name will be parsed.
7816        copy: Whether to copy a table if it is passed in.
7817        kwargs: the kwargs to instantiate the resulting `Table` expression with.
7818
7819    Returns:
7820        A table expression.
7821    """
7822    if isinstance(sql_path, Table):
7823        return maybe_copy(sql_path, copy=copy)
7824
7825    table = maybe_parse(sql_path, into=Table, dialect=dialect)
7826
7827    for k, v in kwargs.items():
7828        table.set(k, v)
7829
7830    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:
7833def to_column(
7834    sql_path: str | Column,
7835    quoted: t.Optional[bool] = None,
7836    dialect: DialectType = None,
7837    copy: bool = True,
7838    **kwargs,
7839) -> Column:
7840    """
7841    Create a column from a `[table].[column]` sql path. Table is optional.
7842    If a column is passed in then that column is returned.
7843
7844    Args:
7845        sql_path: a `[table].[column]` string.
7846        quoted: Whether or not to force quote identifiers.
7847        dialect: the source dialect according to which the column name will be parsed.
7848        copy: Whether to copy a column if it is passed in.
7849        kwargs: the kwargs to instantiate the resulting `Column` expression with.
7850
7851    Returns:
7852        A column expression.
7853    """
7854    if isinstance(sql_path, Column):
7855        return maybe_copy(sql_path, copy=copy)
7856
7857    try:
7858        col = maybe_parse(sql_path, into=Column, dialect=dialect)
7859    except ParseError:
7860        return column(*reversed(sql_path.split(".")), quoted=quoted, **kwargs)
7861
7862    for k, v in kwargs.items():
7863        col.set(k, v)
7864
7865    if quoted:
7866        for i in col.find_all(Identifier):
7867            i.set("quoted", True)
7868
7869    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):
7872def alias_(
7873    expression: ExpOrStr,
7874    alias: t.Optional[str | Identifier],
7875    table: bool | t.Sequence[str | Identifier] = False,
7876    quoted: t.Optional[bool] = None,
7877    dialect: DialectType = None,
7878    copy: bool = True,
7879    **opts,
7880):
7881    """Create an Alias expression.
7882
7883    Example:
7884        >>> alias_('foo', 'bar').sql()
7885        'foo AS bar'
7886
7887        >>> alias_('(select 1, 2)', 'bar', table=['a', 'b']).sql()
7888        '(SELECT 1, 2) AS bar(a, b)'
7889
7890    Args:
7891        expression: the SQL code strings to parse.
7892            If an Expression instance is passed, this is used as-is.
7893        alias: the alias name to use. If the name has
7894            special characters it is quoted.
7895        table: Whether to create a table alias, can also be a list of columns.
7896        quoted: whether to quote the alias
7897        dialect: the dialect used to parse the input expression.
7898        copy: Whether to copy the expression.
7899        **opts: other options to use to parse the input expressions.
7900
7901    Returns:
7902        Alias: the aliased expression
7903    """
7904    exp = maybe_parse(expression, dialect=dialect, copy=copy, **opts)
7905    alias = to_identifier(alias, quoted=quoted)
7906
7907    if table:
7908        table_alias = TableAlias(this=alias)
7909        exp.set("alias", table_alias)
7910
7911        if not isinstance(table, bool):
7912            for column in table:
7913                table_alias.append("columns", to_identifier(column, quoted=quoted))
7914
7915        return exp
7916
7917    # We don't set the "alias" arg for Window expressions, because that would add an IDENTIFIER node in
7918    # the AST, representing a "named_window" [1] construct (eg. bigquery). What we want is an ALIAS node
7919    # for the complete Window expression.
7920    #
7921    # [1]: https://cloud.google.com/bigquery/docs/reference/standard-sql/window-function-calls
7922
7923    if "alias" in exp.arg_types and not isinstance(exp, Window):
7924        exp.set("alias", alias)
7925        return exp
7926    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:
7929def subquery(
7930    expression: ExpOrStr,
7931    alias: t.Optional[Identifier | str] = None,
7932    dialect: DialectType = None,
7933    **opts,
7934) -> Select:
7935    """
7936    Build a subquery expression that's selected from.
7937
7938    Example:
7939        >>> subquery('select x from tbl', 'bar').select('x').sql()
7940        'SELECT x FROM (SELECT x FROM tbl) AS bar'
7941
7942    Args:
7943        expression: the SQL code strings to parse.
7944            If an Expression instance is passed, this is used as-is.
7945        alias: the alias name to use.
7946        dialect: the dialect used to parse the input expression.
7947        **opts: other options to use to parse the input expressions.
7948
7949    Returns:
7950        A new Select instance with the subquery expression included.
7951    """
7952
7953    expression = maybe_parse(expression, dialect=dialect, **opts).subquery(alias, **opts)
7954    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):
7985def column(
7986    col,
7987    table=None,
7988    db=None,
7989    catalog=None,
7990    *,
7991    fields=None,
7992    quoted=None,
7993    copy=True,
7994):
7995    """
7996    Build a Column.
7997
7998    Args:
7999        col: Column name.
8000        table: Table name.
8001        db: Database name.
8002        catalog: Catalog name.
8003        fields: Additional fields using dots.
8004        quoted: Whether to force quotes on the column's identifiers.
8005        copy: Whether to copy identifiers if passed in.
8006
8007    Returns:
8008        The new Column instance.
8009    """
8010    this = Column(
8011        this=to_identifier(col, quoted=quoted, copy=copy),
8012        table=to_identifier(table, quoted=quoted, copy=copy),
8013        db=to_identifier(db, quoted=quoted, copy=copy),
8014        catalog=to_identifier(catalog, quoted=quoted, copy=copy),
8015    )
8016
8017    if fields:
8018        this = Dot.build(
8019            (this, *(to_identifier(field, quoted=quoted, copy=copy) for field in fields))
8020        )
8021    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:
8024def cast(
8025    expression: ExpOrStr, to: DATA_TYPE, copy: bool = True, dialect: DialectType = None, **opts
8026) -> Cast:
8027    """Cast an expression to a data type.
8028
8029    Example:
8030        >>> cast('x + 1', 'int').sql()
8031        'CAST(x + 1 AS INT)'
8032
8033    Args:
8034        expression: The expression to cast.
8035        to: The datatype to cast to.
8036        copy: Whether to copy the supplied expressions.
8037        dialect: The target dialect. This is used to prevent a re-cast in the following scenario:
8038            - The expression to be cast is already a exp.Cast expression
8039            - The existing cast is to a type that is logically equivalent to new type
8040
8041            For example, if :expression='CAST(x as DATETIME)' and :to=Type.TIMESTAMP,
8042            but in the target dialect DATETIME is mapped to TIMESTAMP, then we will NOT return `CAST(x (as DATETIME) as TIMESTAMP)`
8043            and instead just return the original expression `CAST(x as DATETIME)`.
8044
8045            This is to prevent it being output as a double cast `CAST(x (as TIMESTAMP) as TIMESTAMP)` once the DATETIME -> TIMESTAMP
8046            mapping is applied in the target dialect generator.
8047
8048    Returns:
8049        The new Cast instance.
8050    """
8051    expr = maybe_parse(expression, copy=copy, dialect=dialect, **opts)
8052    data_type = DataType.build(to, copy=copy, dialect=dialect, **opts)
8053
8054    # dont re-cast if the expression is already a cast to the correct type
8055    if isinstance(expr, Cast):
8056        from sqlglot.dialects.dialect import Dialect
8057
8058        target_dialect = Dialect.get_or_raise(dialect)
8059        type_mapping = target_dialect.generator_class.TYPE_MAPPING
8060
8061        existing_cast_type: DataType.Type = expr.to.this
8062        new_cast_type: DataType.Type = data_type.this
8063        types_are_equivalent = type_mapping.get(
8064            existing_cast_type, existing_cast_type.value
8065        ) == type_mapping.get(new_cast_type, new_cast_type.value)
8066
8067        if expr.is_type(data_type) or types_are_equivalent:
8068            return expr
8069
8070    expr = Cast(this=expr, to=data_type)
8071    expr.type = data_type
8072
8073    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:
8076def table_(
8077    table: Identifier | str,
8078    db: t.Optional[Identifier | str] = None,
8079    catalog: t.Optional[Identifier | str] = None,
8080    quoted: t.Optional[bool] = None,
8081    alias: t.Optional[Identifier | str] = None,
8082) -> Table:
8083    """Build a Table.
8084
8085    Args:
8086        table: Table name.
8087        db: Database name.
8088        catalog: Catalog name.
8089        quote: Whether to force quotes on the table's identifiers.
8090        alias: Table's alias.
8091
8092    Returns:
8093        The new Table instance.
8094    """
8095    return Table(
8096        this=to_identifier(table, quoted=quoted) if table else None,
8097        db=to_identifier(db, quoted=quoted) if db else None,
8098        catalog=to_identifier(catalog, quoted=quoted) if catalog else None,
8099        alias=TableAlias(this=to_identifier(alias)) if alias else None,
8100    )

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

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:
8136def var(name: t.Optional[ExpOrStr]) -> Var:
8137    """Build a SQL variable.
8138
8139    Example:
8140        >>> repr(var('x'))
8141        'Var(this=x)'
8142
8143        >>> repr(var(column('x', table='y')))
8144        'Var(this=x)'
8145
8146    Args:
8147        name: The name of the var or an expression who's name will become the var.
8148
8149    Returns:
8150        The new variable node.
8151    """
8152    if not name:
8153        raise ValueError("Cannot convert empty name into var.")
8154
8155    if isinstance(name, Expression):
8156        name = name.name
8157    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:
8160def rename_table(
8161    old_name: str | Table,
8162    new_name: str | Table,
8163    dialect: DialectType = None,
8164) -> Alter:
8165    """Build ALTER TABLE... RENAME... expression
8166
8167    Args:
8168        old_name: The old name of the table
8169        new_name: The new name of the table
8170        dialect: The dialect to parse the table.
8171
8172    Returns:
8173        Alter table expression
8174    """
8175    old_table = to_table(old_name, dialect=dialect)
8176    new_table = to_table(new_name, dialect=dialect)
8177    return Alter(
8178        this=old_table,
8179        kind="TABLE",
8180        actions=[
8181            AlterRename(this=new_table),
8182        ],
8183    )

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

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

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

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

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

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

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

Returns a true Boolean expression.

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

Returns a false Boolean expression.

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

Returns a Null expression.

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