Edit on GitHub

Expressions

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

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


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

name: str
125    @property
126    def name(self) -> str:
127        return self.text("this")
is_string: bool
129    @property
130    def is_string(self) -> bool:
131        """
132        Checks whether a Literal expression is a string.
133        """
134        return isinstance(self, Literal) and self.args["is_string"]

Checks whether a Literal expression is a string.

is_number: bool
136    @property
137    def is_number(self) -> bool:
138        """
139        Checks whether a Literal expression is a number.
140        """
141        return (isinstance(self, Literal) and not self.args["is_string"]) or (
142            isinstance(self, Neg) and self.this.is_number
143        )

Checks whether a Literal expression is a number.

is_int: bool
145    @property
146    def is_int(self) -> bool:
147        """
148        Checks whether an expression is an integer.
149        """
150        return self.is_number and isinstance(self.to_py(), int)

Checks whether an expression is an integer.

is_star: bool
152    @property
153    def is_star(self) -> bool:
154        """Checks whether an expression is a star."""
155        return isinstance(self, Star) or (isinstance(self, Column) and isinstance(self.this, Star))

Checks whether an expression is a star.

type: Optional[DataType]
157    @property
158    def type(self) -> t.Optional[DataType]:
159        if isinstance(self, Cast):
160            return self._type or self.to  # type: ignore[return-value]
161        return self._type  # type: ignore[return-value]
def is_type(self, *dtypes) -> bool:
169    def is_type(self, *dtypes) -> bool:
170        return self.type is not None and self.type.is_type(*dtypes)
parent_select: Optional[Select]
172    @property
173    def parent_select(self) -> t.Optional[Select]:
174        """
175        Returns the parent select statement.
176        """
177        return self.find_ancestor(Select)

Returns the parent select statement.

def unnest(self):
179    def unnest(self):
180        """
181        Returns the first non parenthesis child or self.
182        """
183        expression = self
184        while type(expression) is Paren:
185            expression = expression.this
186        return expression

Returns the first non parenthesis child or self.

def unalias(self):
188    def unalias(self):
189        """
190        Returns the inner expression if this is an Alias.
191        """
192        if isinstance(self, Alias):
193            return self.this
194        return self

Returns the inner expression if this is an Alias.

def unnest_operands(self):
196    def unnest_operands(self):
197        """
198        Returns unnested operands as a tuple.
199        """
200        return tuple(arg.unnest() for arg in self.iter_expressions())

Returns unnested operands as a tuple.

def flatten(self, unnest=True):
202    def flatten(self, unnest=True):
203        """
204        Returns a generator which yields child nodes whose parents are the same class.
205
206        A AND B AND C -> [A, B, C]
207        """
208        for node in self.dfs(prune=lambda n: bool(n.parent and type(n) is not self.__class__)):
209            if type(node) is not self.__class__:
210                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:
218    def to_s(self) -> str:
219        """
220        Same as __repr__, but includes additional information which can be useful
221        for debugging, like empty or missing args and the AST nodes' object IDs.
222        """
223        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:
225    def sql(self, dialect: DialectType = None, **opts) -> str:
226        """
227        Returns SQL string representation of this tree.
228
229        Args:
230            dialect: the dialect of the output SQL string (eg. "spark", "hive", "presto", "mysql").
231            opts: other `sqlglot.generator.Generator` options.
232
233        Returns:
234            The SQL string.
235        """
236        from sqlglot.dialects import Dialect
237
238        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 dump(self):
240    def dump(self):
241        """
242        Dump this Expression to a JSON-serializable dict.
243        """
244        from sqlglot.serde import dump
245
246        return dump(self)

Dump this Expression to a JSON-serializable dict.

@classmethod
def load(cls, obj):
248    @classmethod
249    def load(cls, obj):
250        """
251        Load a dict (as returned by `Expression.dump`) into an Expression instance.
252        """
253        from sqlglot.serde import load
254
255        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:
257    def and_(
258        self,
259        *expressions: t.Optional[ExpOrStr],
260        dialect: DialectType = None,
261        copy: bool = True,
262        wrap: bool = True,
263        **opts,
264    ) -> Condition:
265        """
266        AND this condition with one or multiple expressions.
267
268        Example:
269            >>> condition("x=1").and_("y=1").sql()
270            'x = 1 AND y = 1'
271
272        Args:
273            *expressions: the SQL code strings to parse.
274                If an `Expression` instance is passed, it will be used as-is.
275            dialect: the dialect used to parse the input expression.
276            copy: whether to copy the involved expressions (only applies to Expressions).
277            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
278                precedence issues, but can be turned off when the produced AST is too deep and
279                causes recursion-related issues.
280            opts: other options to use to parse the input expressions.
281
282        Returns:
283            The new And condition.
284        """
285        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:
287    def or_(
288        self,
289        *expressions: t.Optional[ExpOrStr],
290        dialect: DialectType = None,
291        copy: bool = True,
292        wrap: bool = True,
293        **opts,
294    ) -> Condition:
295        """
296        OR this condition with one or multiple expressions.
297
298        Example:
299            >>> condition("x=1").or_("y=1").sql()
300            'x = 1 OR y = 1'
301
302        Args:
303            *expressions: the SQL code strings to parse.
304                If an `Expression` instance is passed, it will be used as-is.
305            dialect: the dialect used to parse the input expression.
306            copy: whether to copy the involved expressions (only applies to Expressions).
307            wrap: whether to wrap the operands in `Paren`s. This is true by default to avoid
308                precedence issues, but can be turned off when the produced AST is too deep and
309                causes recursion-related issues.
310            opts: other options to use to parse the input expressions.
311
312        Returns:
313            The new Or condition.
314        """
315        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):
317    def not_(self, copy: bool = True):
318        """
319        Wrap this condition with NOT.
320
321        Example:
322            >>> condition("x=1").not_().sql()
323            'NOT x = 1'
324
325        Args:
326            copy: whether to copy this object.
327
328        Returns:
329            The new Not instance.
330        """
331        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:
333    def as_(
334        self,
335        alias: str | Identifier,
336        quoted: t.Optional[bool] = None,
337        dialect: DialectType = None,
338        copy: bool = True,
339        **opts,
340    ) -> Alias:
341        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:
366    def isin(
367        self,
368        *expressions: t.Any,
369        query: t.Optional[ExpOrStr] = None,
370        unnest: t.Optional[ExpOrStr] | t.Collection[ExpOrStr] = None,
371        copy: bool = True,
372        **opts,
373    ) -> In:
374        subquery = maybe_parse(query, copy=copy, **opts) if query else None
375        if subquery and not isinstance(subquery, Subquery):
376            subquery = subquery.subquery(copy=False)
377
378        return In(
379            this=maybe_copy(self, copy),
380            expressions=[convert(e, copy=copy) for e in expressions],
381            query=subquery,
382            unnest=(
383                Unnest(
384                    expressions=[
385                        maybe_parse(t.cast(ExpOrStr, e), copy=copy, **opts)
386                        for e in ensure_list(unnest)
387                    ]
388                )
389                if unnest
390                else None
391            ),
392        )
def between( self, low: Any, high: Any, copy: bool = True, symmetric: Optional[bool] = None, **opts) -> Between:
394    def between(
395        self,
396        low: t.Any,
397        high: t.Any,
398        copy: bool = True,
399        symmetric: t.Optional[bool] = None,
400        **opts,
401    ) -> Between:
402        between = Between(
403            this=maybe_copy(self, copy),
404            low=convert(low, copy=copy, **opts),
405            high=convert(high, copy=copy, **opts),
406        )
407        if symmetric is not None:
408            between.set("symmetric", symmetric)
409
410        return between
def is_( self, other: Union[str, Expression]) -> Is:
412    def is_(self, other: ExpOrStr) -> Is:
413        return self._binop(Is, other)
def like( self, other: Union[str, Expression]) -> Like:
415    def like(self, other: ExpOrStr) -> Like:
416        return self._binop(Like, other)
def ilike( self, other: Union[str, Expression]) -> ILike:
418    def ilike(self, other: ExpOrStr) -> ILike:
419        return self._binop(ILike, other)
def eq(self, other: Any) -> EQ:
421    def eq(self, other: t.Any) -> EQ:
422        return self._binop(EQ, other)
def neq(self, other: Any) -> NEQ:
424    def neq(self, other: t.Any) -> NEQ:
425        return self._binop(NEQ, other)
def rlike( self, other: Union[str, Expression]) -> RegexpLike:
427    def rlike(self, other: ExpOrStr) -> RegexpLike:
428        return self._binop(RegexpLike, other)
def div( self, other: Union[str, Expression], typed: bool = False, safe: bool = False) -> Div:
430    def div(self, other: ExpOrStr, typed: bool = False, safe: bool = False) -> Div:
431        div = self._binop(Div, other)
432        div.set("typed", typed)
433        div.set("safe", safe)
434        return div
def asc(self, nulls_first: bool = True) -> Ordered:
436    def asc(self, nulls_first: bool = True) -> Ordered:
437        return Ordered(this=self.copy(), nulls_first=nulls_first)
def desc(self, nulls_first: bool = False) -> Ordered:
439    def desc(self, nulls_first: bool = False) -> Ordered:
440        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):
523class Condition(Expression):
524    """Logical conditions like x AND y, or simply x"""

Logical conditions like x AND y, or simply x

key = 'condition'
required_args = {'this'}
class Predicate(Condition):
527class Predicate(Condition):
528    """Relationships like x = y, x > 1, x >= y."""

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

key = 'predicate'
required_args = {'this'}
class DerivedTable(Expression):
531class DerivedTable(Expression):
532    @property
533    def selects(self) -> t.List[Expression]:
534        return self.this.selects if isinstance(self.this, Query) else []
535
536    @property
537    def named_selects(self) -> t.List[str]:
538        return [select.output_name for select in self.selects]
selects: List[Expression]
532    @property
533    def selects(self) -> t.List[Expression]:
534        return self.this.selects if isinstance(self.this, Query) else []
named_selects: List[str]
536    @property
537    def named_selects(self) -> t.List[str]:
538        return [select.output_name for select in self.selects]
key = 'derivedtable'
required_args = {'this'}
class Query(Expression):
541class Query(Expression):
542    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
543        """
544        Returns a `Subquery` that wraps around this query.
545
546        Example:
547            >>> subquery = Select().select("x").from_("tbl").subquery()
548            >>> Select().select("x").from_(subquery).sql()
549            'SELECT x FROM (SELECT x FROM tbl)'
550
551        Args:
552            alias: an optional alias for the subquery.
553            copy: if `False`, modify this expression instance in-place.
554        """
555        instance = maybe_copy(self, copy)
556        if not isinstance(alias, Expression):
557            alias = TableAlias(this=to_identifier(alias)) if alias else None
558
559        return Subquery(this=instance, alias=alias)
560
561    def limit(
562        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
563    ) -> Q:
564        """
565        Adds a LIMIT clause to this query.
566
567        Example:
568            >>> select("1").union(select("1")).limit(1).sql()
569            'SELECT 1 UNION SELECT 1 LIMIT 1'
570
571        Args:
572            expression: the SQL code string to parse.
573                This can also be an integer.
574                If a `Limit` instance is passed, it will be used as-is.
575                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
576            dialect: the dialect used to parse the input expression.
577            copy: if `False`, modify this expression instance in-place.
578            opts: other options to use to parse the input expressions.
579
580        Returns:
581            A limited Select expression.
582        """
583        return _apply_builder(
584            expression=expression,
585            instance=self,
586            arg="limit",
587            into=Limit,
588            prefix="LIMIT",
589            dialect=dialect,
590            copy=copy,
591            into_arg="expression",
592            **opts,
593        )
594
595    def offset(
596        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
597    ) -> Q:
598        """
599        Set the OFFSET expression.
600
601        Example:
602            >>> Select().from_("tbl").select("x").offset(10).sql()
603            'SELECT x FROM tbl OFFSET 10'
604
605        Args:
606            expression: the SQL code string to parse.
607                This can also be an integer.
608                If a `Offset` instance is passed, this is used as-is.
609                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
610            dialect: the dialect used to parse the input expression.
611            copy: if `False`, modify this expression instance in-place.
612            opts: other options to use to parse the input expressions.
613
614        Returns:
615            The modified Select expression.
616        """
617        return _apply_builder(
618            expression=expression,
619            instance=self,
620            arg="offset",
621            into=Offset,
622            prefix="OFFSET",
623            dialect=dialect,
624            copy=copy,
625            into_arg="expression",
626            **opts,
627        )
628
629    def order_by(
630        self: Q,
631        *expressions: t.Optional[ExpOrStr],
632        append: bool = True,
633        dialect: DialectType = None,
634        copy: bool = True,
635        **opts,
636    ) -> Q:
637        """
638        Set the ORDER BY expression.
639
640        Example:
641            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
642            'SELECT x FROM tbl ORDER BY x DESC'
643
644        Args:
645            *expressions: the SQL code strings to parse.
646                If a `Group` instance is passed, this is used as-is.
647                If another `Expression` instance is passed, it will be wrapped in a `Order`.
648            append: if `True`, add to any existing expressions.
649                Otherwise, this flattens all the `Order` expression into a single expression.
650            dialect: the dialect used to parse the input expression.
651            copy: if `False`, modify this expression instance in-place.
652            opts: other options to use to parse the input expressions.
653
654        Returns:
655            The modified Select expression.
656        """
657        return _apply_child_list_builder(
658            *expressions,
659            instance=self,
660            arg="order",
661            append=append,
662            copy=copy,
663            prefix="ORDER BY",
664            into=Order,
665            dialect=dialect,
666            **opts,
667        )
668
669    @property
670    def ctes(self) -> t.List[CTE]:
671        """Returns a list of all the CTEs attached to this query."""
672        with_ = self.args.get("with_")
673        return with_.expressions if with_ else []
674
675    @property
676    def selects(self) -> t.List[Expression]:
677        """Returns the query's projections."""
678        raise NotImplementedError("Query objects must implement `selects`")
679
680    @property
681    def named_selects(self) -> t.List[str]:
682        """Returns the output names of the query's projections."""
683        raise NotImplementedError("Query objects must implement `named_selects`")
684
685    def select(
686        self: Q,
687        *expressions: t.Optional[ExpOrStr],
688        append: bool = True,
689        dialect: DialectType = None,
690        copy: bool = True,
691        **opts,
692    ) -> Q:
693        """
694        Append to or set the SELECT expressions.
695
696        Example:
697            >>> Select().select("x", "y").sql()
698            'SELECT x, y'
699
700        Args:
701            *expressions: the SQL code strings to parse.
702                If an `Expression` instance is passed, it will be used as-is.
703            append: if `True`, add to any existing expressions.
704                Otherwise, this resets the expressions.
705            dialect: the dialect used to parse the input expressions.
706            copy: if `False`, modify this expression instance in-place.
707            opts: other options to use to parse the input expressions.
708
709        Returns:
710            The modified Query expression.
711        """
712        raise NotImplementedError("Query objects must implement `select`")
713
714    def where(
715        self: Q,
716        *expressions: t.Optional[ExpOrStr],
717        append: bool = True,
718        dialect: DialectType = None,
719        copy: bool = True,
720        **opts,
721    ) -> Q:
722        """
723        Append to or set the WHERE expressions.
724
725        Examples:
726            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
727            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
728
729        Args:
730            *expressions: the SQL code strings to parse.
731                If an `Expression` instance is passed, it will be used as-is.
732                Multiple expressions are combined with an AND operator.
733            append: if `True`, AND the new expressions to any existing expression.
734                Otherwise, this resets the expression.
735            dialect: the dialect used to parse the input expressions.
736            copy: if `False`, modify this expression instance in-place.
737            opts: other options to use to parse the input expressions.
738
739        Returns:
740            The modified expression.
741        """
742        return _apply_conjunction_builder(
743            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
744            instance=self,
745            arg="where",
746            append=append,
747            into=Where,
748            dialect=dialect,
749            copy=copy,
750            **opts,
751        )
752
753    def with_(
754        self: Q,
755        alias: ExpOrStr,
756        as_: ExpOrStr,
757        recursive: t.Optional[bool] = None,
758        materialized: t.Optional[bool] = None,
759        append: bool = True,
760        dialect: DialectType = None,
761        copy: bool = True,
762        scalar: t.Optional[bool] = None,
763        **opts,
764    ) -> Q:
765        """
766        Append to or set the common table expressions.
767
768        Example:
769            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
770            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
771
772        Args:
773            alias: the SQL code string to parse as the table name.
774                If an `Expression` instance is passed, this is used as-is.
775            as_: the SQL code string to parse as the table expression.
776                If an `Expression` instance is passed, it will be used as-is.
777            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
778            materialized: set the MATERIALIZED part of the expression.
779            append: if `True`, add to any existing expressions.
780                Otherwise, this resets the expressions.
781            dialect: the dialect used to parse the input expression.
782            copy: if `False`, modify this expression instance in-place.
783            scalar: if `True`, this is a scalar common table expression.
784            opts: other options to use to parse the input expressions.
785
786        Returns:
787            The modified expression.
788        """
789        return _apply_cte_builder(
790            self,
791            alias,
792            as_,
793            recursive=recursive,
794            materialized=materialized,
795            append=append,
796            dialect=dialect,
797            copy=copy,
798            scalar=scalar,
799            **opts,
800        )
801
802    def union(
803        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
804    ) -> Union:
805        """
806        Builds a UNION expression.
807
808        Example:
809            >>> import sqlglot
810            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
811            'SELECT * FROM foo UNION SELECT * FROM bla'
812
813        Args:
814            expressions: the SQL code strings.
815                If `Expression` instances are passed, they will be used as-is.
816            distinct: set the DISTINCT flag if and only if this is true.
817            dialect: the dialect used to parse the input expression.
818            opts: other options to use to parse the input expressions.
819
820        Returns:
821            The new Union expression.
822        """
823        return union(self, *expressions, distinct=distinct, dialect=dialect, **opts)
824
825    def intersect(
826        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
827    ) -> Intersect:
828        """
829        Builds an INTERSECT expression.
830
831        Example:
832            >>> import sqlglot
833            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
834            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
835
836        Args:
837            expressions: the SQL code strings.
838                If `Expression` instances are passed, they will be used as-is.
839            distinct: set the DISTINCT flag if and only if this is true.
840            dialect: the dialect used to parse the input expression.
841            opts: other options to use to parse the input expressions.
842
843        Returns:
844            The new Intersect expression.
845        """
846        return intersect(self, *expressions, distinct=distinct, dialect=dialect, **opts)
847
848    def except_(
849        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
850    ) -> Except:
851        """
852        Builds an EXCEPT expression.
853
854        Example:
855            >>> import sqlglot
856            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
857            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
858
859        Args:
860            expressions: the SQL code strings.
861                If `Expression` instance are passed, they will be used as-is.
862            distinct: set the DISTINCT flag if and only if this is true.
863            dialect: the dialect used to parse the input expression.
864            opts: other options to use to parse the input expressions.
865
866        Returns:
867            The new Except expression.
868        """
869        return except_(self, *expressions, distinct=distinct, dialect=dialect, **opts)
def subquery( self, alias: Union[str, Expression, NoneType] = None, copy: bool = True) -> Subquery:
542    def subquery(self, alias: t.Optional[ExpOrStr] = None, copy: bool = True) -> Subquery:
543        """
544        Returns a `Subquery` that wraps around this query.
545
546        Example:
547            >>> subquery = Select().select("x").from_("tbl").subquery()
548            >>> Select().select("x").from_(subquery).sql()
549            'SELECT x FROM (SELECT x FROM tbl)'
550
551        Args:
552            alias: an optional alias for the subquery.
553            copy: if `False`, modify this expression instance in-place.
554        """
555        instance = maybe_copy(self, copy)
556        if not isinstance(alias, Expression):
557            alias = TableAlias(this=to_identifier(alias)) if alias else None
558
559        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:
561    def limit(
562        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
563    ) -> Q:
564        """
565        Adds a LIMIT clause to this query.
566
567        Example:
568            >>> select("1").union(select("1")).limit(1).sql()
569            'SELECT 1 UNION SELECT 1 LIMIT 1'
570
571        Args:
572            expression: the SQL code string to parse.
573                This can also be an integer.
574                If a `Limit` instance is passed, it will be used as-is.
575                If another `Expression` instance is passed, it will be wrapped in a `Limit`.
576            dialect: the dialect used to parse the input expression.
577            copy: if `False`, modify this expression instance in-place.
578            opts: other options to use to parse the input expressions.
579
580        Returns:
581            A limited Select expression.
582        """
583        return _apply_builder(
584            expression=expression,
585            instance=self,
586            arg="limit",
587            into=Limit,
588            prefix="LIMIT",
589            dialect=dialect,
590            copy=copy,
591            into_arg="expression",
592            **opts,
593        )

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:
595    def offset(
596        self: Q, expression: ExpOrStr | int, dialect: DialectType = None, copy: bool = True, **opts
597    ) -> Q:
598        """
599        Set the OFFSET expression.
600
601        Example:
602            >>> Select().from_("tbl").select("x").offset(10).sql()
603            'SELECT x FROM tbl OFFSET 10'
604
605        Args:
606            expression: the SQL code string to parse.
607                This can also be an integer.
608                If a `Offset` instance is passed, this is used as-is.
609                If another `Expression` instance is passed, it will be wrapped in a `Offset`.
610            dialect: the dialect used to parse the input expression.
611            copy: if `False`, modify this expression instance in-place.
612            opts: other options to use to parse the input expressions.
613
614        Returns:
615            The modified Select expression.
616        """
617        return _apply_builder(
618            expression=expression,
619            instance=self,
620            arg="offset",
621            into=Offset,
622            prefix="OFFSET",
623            dialect=dialect,
624            copy=copy,
625            into_arg="expression",
626            **opts,
627        )

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:
629    def order_by(
630        self: Q,
631        *expressions: t.Optional[ExpOrStr],
632        append: bool = True,
633        dialect: DialectType = None,
634        copy: bool = True,
635        **opts,
636    ) -> Q:
637        """
638        Set the ORDER BY expression.
639
640        Example:
641            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
642            'SELECT x FROM tbl ORDER BY x DESC'
643
644        Args:
645            *expressions: the SQL code strings to parse.
646                If a `Group` instance is passed, this is used as-is.
647                If another `Expression` instance is passed, it will be wrapped in a `Order`.
648            append: if `True`, add to any existing expressions.
649                Otherwise, this flattens all the `Order` expression into a single expression.
650            dialect: the dialect used to parse the input expression.
651            copy: if `False`, modify this expression instance in-place.
652            opts: other options to use to parse the input expressions.
653
654        Returns:
655            The modified Select expression.
656        """
657        return _apply_child_list_builder(
658            *expressions,
659            instance=self,
660            arg="order",
661            append=append,
662            copy=copy,
663            prefix="ORDER BY",
664            into=Order,
665            dialect=dialect,
666            **opts,
667        )

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]
669    @property
670    def ctes(self) -> t.List[CTE]:
671        """Returns a list of all the CTEs attached to this query."""
672        with_ = self.args.get("with_")
673        return with_.expressions if with_ else []

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

selects: List[Expression]
675    @property
676    def selects(self) -> t.List[Expression]:
677        """Returns the query's projections."""
678        raise NotImplementedError("Query objects must implement `selects`")

Returns the query's projections.

named_selects: List[str]
680    @property
681    def named_selects(self) -> t.List[str]:
682        """Returns the output names of the query's projections."""
683        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:
685    def select(
686        self: Q,
687        *expressions: t.Optional[ExpOrStr],
688        append: bool = True,
689        dialect: DialectType = None,
690        copy: bool = True,
691        **opts,
692    ) -> Q:
693        """
694        Append to or set the SELECT expressions.
695
696        Example:
697            >>> Select().select("x", "y").sql()
698            'SELECT x, y'
699
700        Args:
701            *expressions: the SQL code strings to parse.
702                If an `Expression` instance is passed, it will be used as-is.
703            append: if `True`, add to any existing expressions.
704                Otherwise, this resets the expressions.
705            dialect: the dialect used to parse the input expressions.
706            copy: if `False`, modify this expression instance in-place.
707            opts: other options to use to parse the input expressions.
708
709        Returns:
710            The modified Query expression.
711        """
712        raise NotImplementedError("Query objects must implement `select`")

Append to or set the SELECT expressions.

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

The modified Query expression.

def where( self: ~Q, *expressions: Union[str, Expression, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts) -> ~Q:
714    def where(
715        self: Q,
716        *expressions: t.Optional[ExpOrStr],
717        append: bool = True,
718        dialect: DialectType = None,
719        copy: bool = True,
720        **opts,
721    ) -> Q:
722        """
723        Append to or set the WHERE expressions.
724
725        Examples:
726            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
727            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
728
729        Args:
730            *expressions: the SQL code strings to parse.
731                If an `Expression` instance is passed, it will be used as-is.
732                Multiple expressions are combined with an AND operator.
733            append: if `True`, AND the new expressions to any existing expression.
734                Otherwise, this resets the expression.
735            dialect: the dialect used to parse the input expressions.
736            copy: if `False`, modify this expression instance in-place.
737            opts: other options to use to parse the input expressions.
738
739        Returns:
740            The modified expression.
741        """
742        return _apply_conjunction_builder(
743            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
744            instance=self,
745            arg="where",
746            append=append,
747            into=Where,
748            dialect=dialect,
749            copy=copy,
750            **opts,
751        )

Append to or set the WHERE expressions.

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

The modified expression.

def with_( self: ~Q, alias: Union[str, Expression], as_: Union[str, Expression], recursive: Optional[bool] = None, materialized: Optional[bool] = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, Type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, scalar: Optional[bool] = None, **opts) -> ~Q:
753    def with_(
754        self: Q,
755        alias: ExpOrStr,
756        as_: ExpOrStr,
757        recursive: t.Optional[bool] = None,
758        materialized: t.Optional[bool] = None,
759        append: bool = True,
760        dialect: DialectType = None,
761        copy: bool = True,
762        scalar: t.Optional[bool] = None,
763        **opts,
764    ) -> Q:
765        """
766        Append to or set the common table expressions.
767
768        Example:
769            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
770            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
771
772        Args:
773            alias: the SQL code string to parse as the table name.
774                If an `Expression` instance is passed, this is used as-is.
775            as_: the SQL code string to parse as the table expression.
776                If an `Expression` instance is passed, it will be used as-is.
777            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
778            materialized: set the MATERIALIZED part of the expression.
779            append: if `True`, add to any existing expressions.
780                Otherwise, this resets the expressions.
781            dialect: the dialect used to parse the input expression.
782            copy: if `False`, modify this expression instance in-place.
783            scalar: if `True`, this is a scalar common table expression.
784            opts: other options to use to parse the input expressions.
785
786        Returns:
787            The modified expression.
788        """
789        return _apply_cte_builder(
790            self,
791            alias,
792            as_,
793            recursive=recursive,
794            materialized=materialized,
795            append=append,
796            dialect=dialect,
797            copy=copy,
798            scalar=scalar,
799            **opts,
800        )

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:
802    def union(
803        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
804    ) -> Union:
805        """
806        Builds a UNION expression.
807
808        Example:
809            >>> import sqlglot
810            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
811            'SELECT * FROM foo UNION SELECT * FROM bla'
812
813        Args:
814            expressions: the SQL code strings.
815                If `Expression` instances are passed, they will be used as-is.
816            distinct: set the DISTINCT flag if and only if this is true.
817            dialect: the dialect used to parse the input expression.
818            opts: other options to use to parse the input expressions.
819
820        Returns:
821            The new Union expression.
822        """
823        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:
825    def intersect(
826        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
827    ) -> Intersect:
828        """
829        Builds an INTERSECT expression.
830
831        Example:
832            >>> import sqlglot
833            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
834            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
835
836        Args:
837            expressions: the SQL code strings.
838                If `Expression` instances are passed, they will be used as-is.
839            distinct: set the DISTINCT flag if and only if this is true.
840            dialect: the dialect used to parse the input expression.
841            opts: other options to use to parse the input expressions.
842
843        Returns:
844            The new Intersect expression.
845        """
846        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:
848    def except_(
849        self, *expressions: ExpOrStr, distinct: bool = True, dialect: DialectType = None, **opts
850    ) -> Except:
851        """
852        Builds an EXCEPT expression.
853
854        Example:
855            >>> import sqlglot
856            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
857            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
858
859        Args:
860            expressions: the SQL code strings.
861                If `Expression` instance are passed, they will be used as-is.
862            distinct: set the DISTINCT flag if and only if this is true.
863            dialect: the dialect used to parse the input expression.
864            opts: other options to use to parse the input expressions.
865
866        Returns:
867            The new Except expression.
868        """
869        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'
required_args = {'this'}
class UDTF(DerivedTable):
872class UDTF(DerivedTable):
873    @property
874    def selects(self) -> t.List[Expression]:
875        alias = self.args.get("alias")
876        return alias.columns if alias else []
selects: List[Expression]
873    @property
874    def selects(self) -> t.List[Expression]:
875        alias = self.args.get("alias")
876        return alias.columns if alias else []
key = 'udtf'
required_args = {'this'}
class Cache(Expression):
879class Cache(Expression):
880    arg_types = {
881        "this": True,
882        "lazy": False,
883        "options": False,
884        "expression": False,
885    }
arg_types = {'this': True, 'lazy': False, 'options': False, 'expression': False}
key = 'cache'
required_args = {'this'}
class Uncache(Expression):
888class Uncache(Expression):
889    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'uncache'
required_args = {'this'}
class Refresh(Expression):
892class Refresh(Expression):
893    arg_types = {"this": True, "kind": True}
arg_types = {'this': True, 'kind': True}
key = 'refresh'
required_args = {'kind', 'this'}
class DDL(Expression):
896class DDL(Expression):
897    @property
898    def ctes(self) -> t.List[CTE]:
899        """Returns a list of all the CTEs attached to this statement."""
900        with_ = self.args.get("with_")
901        return with_.expressions if with_ else []
902
903    @property
904    def selects(self) -> t.List[Expression]:
905        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
906        return self.expression.selects if isinstance(self.expression, Query) else []
907
908    @property
909    def named_selects(self) -> t.List[str]:
910        """
911        If this statement contains a query (e.g. a CTAS), this returns the output
912        names of the query's projections.
913        """
914        return self.expression.named_selects if isinstance(self.expression, Query) else []
ctes: List[CTE]
897    @property
898    def ctes(self) -> t.List[CTE]:
899        """Returns a list of all the CTEs attached to this statement."""
900        with_ = self.args.get("with_")
901        return with_.expressions if with_ else []

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

selects: List[Expression]
903    @property
904    def selects(self) -> t.List[Expression]:
905        """If this statement contains a query (e.g. a CTAS), this returns the query's projections."""
906        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]
908    @property
909    def named_selects(self) -> t.List[str]:
910        """
911        If this statement contains a query (e.g. a CTAS), this returns the output
912        names of the query's projections.
913        """
914        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'
required_args = {'this'}
class LockingStatement(Expression):
918class LockingStatement(Expression):
919    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'lockingstatement'
required_args = {'this', 'expression'}
class DML(Expression):
922class DML(Expression):
923    def returning(
924        self,
925        expression: ExpOrStr,
926        dialect: DialectType = None,
927        copy: bool = True,
928        **opts,
929    ) -> "Self":
930        """
931        Set the RETURNING expression. Not supported by all dialects.
932
933        Example:
934            >>> delete("tbl").returning("*", dialect="postgres").sql()
935            'DELETE FROM tbl RETURNING *'
936
937        Args:
938            expression: the SQL code strings to parse.
939                If an `Expression` instance is passed, it will be used as-is.
940            dialect: the dialect used to parse the input expressions.
941            copy: if `False`, modify this expression instance in-place.
942            opts: other options to use to parse the input expressions.
943
944        Returns:
945            Delete: the modified expression.
946        """
947        return _apply_builder(
948            expression=expression,
949            instance=self,
950            arg="returning",
951            prefix="RETURNING",
952            dialect=dialect,
953            copy=copy,
954            into=Returning,
955            **opts,
956        )
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:
923    def returning(
924        self,
925        expression: ExpOrStr,
926        dialect: DialectType = None,
927        copy: bool = True,
928        **opts,
929    ) -> "Self":
930        """
931        Set the RETURNING expression. Not supported by all dialects.
932
933        Example:
934            >>> delete("tbl").returning("*", dialect="postgres").sql()
935            'DELETE FROM tbl RETURNING *'
936
937        Args:
938            expression: the SQL code strings to parse.
939                If an `Expression` instance is passed, it will be used as-is.
940            dialect: the dialect used to parse the input expressions.
941            copy: if `False`, modify this expression instance in-place.
942            opts: other options to use to parse the input expressions.
943
944        Returns:
945            Delete: the modified expression.
946        """
947        return _apply_builder(
948            expression=expression,
949            instance=self,
950            arg="returning",
951            prefix="RETURNING",
952            dialect=dialect,
953            copy=copy,
954            into=Returning,
955            **opts,
956        )

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'
required_args = {'this'}
class Create(DDL):
959class Create(DDL):
960    arg_types = {
961        "with_": False,
962        "this": True,
963        "kind": True,
964        "expression": False,
965        "exists": False,
966        "properties": False,
967        "replace": False,
968        "refresh": False,
969        "unique": False,
970        "indexes": False,
971        "no_schema_binding": False,
972        "begin": False,
973        "clone": False,
974        "concurrently": False,
975        "clustered": False,
976    }
977
978    @property
979    def kind(self) -> t.Optional[str]:
980        kind = self.args.get("kind")
981        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, 'clone': False, 'concurrently': False, 'clustered': False}
kind: Optional[str]
978    @property
979    def kind(self) -> t.Optional[str]:
980        kind = self.args.get("kind")
981        return kind and kind.upper()
key = 'create'
required_args = {'kind', 'this'}
class SequenceProperties(Expression):
984class SequenceProperties(Expression):
985    arg_types = {
986        "increment": False,
987        "minvalue": False,
988        "maxvalue": False,
989        "cache": False,
990        "start": False,
991        "owned": False,
992        "options": False,
993    }
arg_types = {'increment': False, 'minvalue': False, 'maxvalue': False, 'cache': False, 'start': False, 'owned': False, 'options': False}
key = 'sequenceproperties'
required_args = set()
class TriggerProperties(Expression):
 997class TriggerProperties(Expression):
 998    arg_types = {
 999        "table": True,
1000        "timing": True,
1001        "events": True,
1002        "execute": True,
1003        "constraint": False,
1004        "referenced_table": False,
1005        "deferrable": False,
1006        "initially": False,
1007        "referencing": False,
1008        "for_each": False,
1009        "when": False,
1010    }
arg_types = {'table': True, 'timing': True, 'events': True, 'execute': True, 'constraint': False, 'referenced_table': False, 'deferrable': False, 'initially': False, 'referencing': False, 'for_each': False, 'when': False}
key = 'triggerproperties'
required_args = {'events', 'execute', 'table', 'timing'}
class TriggerExecute(Expression):
1013class TriggerExecute(Expression):
1014    pass
key = 'triggerexecute'
required_args = {'this'}
class TriggerEvent(Expression):
1017class TriggerEvent(Expression):
1018    arg_types = {"this": True, "columns": False}
arg_types = {'this': True, 'columns': False}
key = 'triggerevent'
required_args = {'this'}
class TriggerReferencing(Expression):
1021class TriggerReferencing(Expression):
1022    arg_types = {"old": False, "new": False}
arg_types = {'old': False, 'new': False}
key = 'triggerreferencing'
required_args = set()
class TruncateTable(Expression):
1025class TruncateTable(Expression):
1026    arg_types = {
1027        "expressions": True,
1028        "is_database": False,
1029        "exists": False,
1030        "only": False,
1031        "cluster": False,
1032        "identity": False,
1033        "option": False,
1034        "partition": False,
1035    }
arg_types = {'expressions': True, 'is_database': False, 'exists': False, 'only': False, 'cluster': False, 'identity': False, 'option': False, 'partition': False}
key = 'truncatetable'
required_args = {'expressions'}
class Clone(Expression):
1041class Clone(Expression):
1042    arg_types = {"this": True, "shallow": False, "copy": False}
arg_types = {'this': True, 'shallow': False, 'copy': False}
key = 'clone'
required_args = {'this'}
class Describe(Expression):
1045class Describe(Expression):
1046    arg_types = {
1047        "this": True,
1048        "style": False,
1049        "kind": False,
1050        "expressions": False,
1051        "partition": False,
1052        "format": False,
1053        "as_json": False,
1054    }
arg_types = {'this': True, 'style': False, 'kind': False, 'expressions': False, 'partition': False, 'format': False, 'as_json': False}
key = 'describe'
required_args = {'this'}
class Attach(Expression):
1058class Attach(Expression):
1059    arg_types = {"this": True, "exists": False, "expressions": False}
arg_types = {'this': True, 'exists': False, 'expressions': False}
key = 'attach'
required_args = {'this'}
class Detach(Expression):
1063class Detach(Expression):
1064    arg_types = {"this": True, "exists": False}
arg_types = {'this': True, 'exists': False}
key = 'detach'
required_args = {'this'}
class Install(Expression):
1068class Install(Expression):
1069    arg_types = {"this": True, "from_": False, "force": False}
arg_types = {'this': True, 'from_': False, 'force': False}
key = 'install'
required_args = {'this'}
class Summarize(Expression):
1073class Summarize(Expression):
1074    arg_types = {"this": True, "table": False}
arg_types = {'this': True, 'table': False}
key = 'summarize'
required_args = {'this'}
class Kill(Expression):
1077class Kill(Expression):
1078    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'kill'
required_args = {'this'}
class Pragma(Expression):
1081class Pragma(Expression):
1082    pass
key = 'pragma'
required_args = {'this'}
class Declare(Expression):
1085class Declare(Expression):
1086    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'declare'
required_args = {'expressions'}
class DeclareItem(Expression):
1089class DeclareItem(Expression):
1090    arg_types = {"this": True, "kind": False, "default": False}
arg_types = {'this': True, 'kind': False, 'default': False}
key = 'declareitem'
required_args = {'this'}
class Set(Expression):
1093class Set(Expression):
1094    arg_types = {"expressions": False, "unset": False, "tag": False}
arg_types = {'expressions': False, 'unset': False, 'tag': False}
key = 'set'
required_args = set()
class Heredoc(Expression):
1097class Heredoc(Expression):
1098    arg_types = {"this": True, "tag": False}
arg_types = {'this': True, 'tag': False}
key = 'heredoc'
required_args = {'this'}
class SetItem(Expression):
1101class SetItem(Expression):
1102    arg_types = {
1103        "this": False,
1104        "expressions": False,
1105        "kind": False,
1106        "collate": False,  # MySQL SET NAMES statement
1107        "global_": False,
1108    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'collate': False, 'global_': False}
key = 'setitem'
required_args = set()
class QueryBand(Expression):
1111class QueryBand(Expression):
1112    arg_types = {"this": True, "scope": False, "update": False}
arg_types = {'this': True, 'scope': False, 'update': False}
key = 'queryband'
required_args = {'this'}
class Show(Expression):
1115class Show(Expression):
1116    arg_types = {
1117        "this": True,
1118        "history": False,
1119        "terse": False,
1120        "target": False,
1121        "offset": False,
1122        "starts_with": False,
1123        "limit": False,
1124        "from_": False,
1125        "like": False,
1126        "where": False,
1127        "db": False,
1128        "scope": False,
1129        "scope_kind": False,
1130        "full": False,
1131        "mutex": False,
1132        "query": False,
1133        "channel": False,
1134        "global_": False,
1135        "log": False,
1136        "position": False,
1137        "types": False,
1138        "privileges": False,
1139        "for_table": False,
1140        "for_group": False,
1141        "for_user": False,
1142        "for_role": False,
1143        "into_outfile": False,
1144        "json": False,
1145    }
arg_types = {'this': True, 'history': False, 'terse': False, 'target': False, 'offset': False, 'starts_with': False, 'limit': False, 'from_': False, 'like': False, 'where': False, 'db': False, 'scope': False, 'scope_kind': False, 'full': False, 'mutex': False, 'query': False, 'channel': False, 'global_': False, 'log': False, 'position': False, 'types': False, 'privileges': False, 'for_table': False, 'for_group': False, 'for_user': False, 'for_role': False, 'into_outfile': False, 'json': False}
key = 'show'
required_args = {'this'}
class UserDefinedFunction(Expression):
1148class UserDefinedFunction(Expression):
1149    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key = 'userdefinedfunction'
required_args = {'this'}
class CharacterSet(Expression):
1152class CharacterSet(Expression):
1153    arg_types = {"this": True, "default": False}
arg_types = {'this': True, 'default': False}
key = 'characterset'
required_args = {'this'}
class RecursiveWithSearch(Expression):
1156class RecursiveWithSearch(Expression):
1157    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
arg_types = {'kind': True, 'this': True, 'expression': True, 'using': False}
key = 'recursivewithsearch'
required_args = {'kind', 'this', 'expression'}
class With(Expression):
1160class With(Expression):
1161    arg_types = {"expressions": True, "recursive": False, "search": False}
1162
1163    @property
1164    def recursive(self) -> bool:
1165        return bool(self.args.get("recursive"))
arg_types = {'expressions': True, 'recursive': False, 'search': False}
recursive: bool
1163    @property
1164    def recursive(self) -> bool:
1165        return bool(self.args.get("recursive"))
key = 'with'
required_args = {'expressions'}
class WithinGroup(Expression):
1168class WithinGroup(Expression):
1169    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key = 'withingroup'
required_args = {'this'}
class CTE(DerivedTable):
1174class CTE(DerivedTable):
1175    arg_types = {
1176        "this": True,
1177        "alias": True,
1178        "scalar": False,
1179        "materialized": False,
1180        "key_expressions": False,
1181    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False, 'key_expressions': False}
key = 'cte'
required_args = {'alias', 'this'}
class ProjectionDef(Expression):
1184class ProjectionDef(Expression):
1185    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'projectiondef'
required_args = {'this', 'expression'}
class TableAlias(Expression):
1188class TableAlias(Expression):
1189    arg_types = {"this": False, "columns": False}
1190
1191    @property
1192    def columns(self):
1193        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns
1191    @property
1192    def columns(self):
1193        return self.args.get("columns") or []
key = 'tablealias'
required_args = set()
class BitString(Condition):
1196class BitString(Condition):
1197    pass
key = 'bitstring'
required_args = {'this'}
class HexString(Condition):
1200class HexString(Condition):
1201    arg_types = {"this": True, "is_integer": False}
arg_types = {'this': True, 'is_integer': False}
key = 'hexstring'
required_args = {'this'}
class ByteString(Condition):
1204class ByteString(Condition):
1205    arg_types = {"this": True, "is_bytes": False}
arg_types = {'this': True, 'is_bytes': False}
key = 'bytestring'
required_args = {'this'}
class RawString(Condition):
1208class RawString(Condition):
1209    pass
key = 'rawstring'
required_args = {'this'}
class UnicodeString(Condition):
1212class UnicodeString(Condition):
1213    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key = 'unicodestring'
required_args = {'this'}
class Column(Condition):
1216class Column(Condition):
1217    arg_types = {"this": True, "table": False, "db": False, "catalog": False, "join_mark": False}
1218
1219    @property
1220    def table(self) -> str:
1221        return self.text("table")
1222
1223    @property
1224    def db(self) -> str:
1225        return self.text("db")
1226
1227    @property
1228    def catalog(self) -> str:
1229        return self.text("catalog")
1230
1231    @property
1232    def output_name(self) -> str:
1233        return self.name
1234
1235    @property
1236    def parts(self) -> t.List[Identifier]:
1237        """Return the parts of a column in order catalog, db, table, name."""
1238        return [
1239            t.cast(Identifier, self.args[part])
1240            for part in ("catalog", "db", "table", "this")
1241            if self.args.get(part)
1242        ]
1243
1244    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1245        """Converts the column into a dot expression."""
1246        parts = self.parts
1247        parent = self.parent
1248
1249        if include_dots:
1250            while isinstance(parent, Dot):
1251                parts.append(parent.expression)
1252                parent = parent.parent
1253
1254        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
1219    @property
1220    def table(self) -> str:
1221        return self.text("table")
db: str
1223    @property
1224    def db(self) -> str:
1225        return self.text("db")
catalog: str
1227    @property
1228    def catalog(self) -> str:
1229        return self.text("catalog")
output_name: str
1231    @property
1232    def output_name(self) -> str:
1233        return self.name
parts: List[Identifier]
1235    @property
1236    def parts(self) -> t.List[Identifier]:
1237        """Return the parts of a column in order catalog, db, table, name."""
1238        return [
1239            t.cast(Identifier, self.args[part])
1240            for part in ("catalog", "db", "table", "this")
1241            if self.args.get(part)
1242        ]

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

def to_dot( self, include_dots: bool = True) -> Dot | Identifier:
1244    def to_dot(self, include_dots: bool = True) -> Dot | Identifier:
1245        """Converts the column into a dot expression."""
1246        parts = self.parts
1247        parent = self.parent
1248
1249        if include_dots:
1250            while isinstance(parent, Dot):
1251                parts.append(parent.expression)
1252                parent = parent.parent
1253
1254        return Dot.build(deepcopy(parts)) if len(parts) > 1 else parts[0]

Converts the column into a dot expression.

key = 'column'
required_args = {'this'}
class Pseudocolumn(Column):
1257class Pseudocolumn(Column):
1258    pass
key = 'pseudocolumn'
required_args = {'this'}
class ColumnPosition(Expression):
1261class ColumnPosition(Expression):
1262    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key = 'columnposition'
required_args = {'position'}
class ColumnDef(Expression):
1265class ColumnDef(Expression):
1266    arg_types = {
1267        "this": True,
1268        "kind": False,
1269        "constraints": False,
1270        "exists": False,
1271        "position": False,
1272        "default": False,
1273        "output": False,
1274    }
1275
1276    @property
1277    def constraints(self) -> t.List[ColumnConstraint]:
1278        return self.args.get("constraints") or []
1279
1280    @property
1281    def kind(self) -> t.Optional[DataType]:
1282        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: List[ColumnConstraint]
1276    @property
1277    def constraints(self) -> t.List[ColumnConstraint]:
1278        return self.args.get("constraints") or []
kind: Optional[DataType]
1280    @property
1281    def kind(self) -> t.Optional[DataType]:
1282        return self.args.get("kind")
key = 'columndef'
required_args = {'this'}
class AlterColumn(Expression):
1285class AlterColumn(Expression):
1286    arg_types = {
1287        "this": True,
1288        "dtype": False,
1289        "collate": False,
1290        "using": False,
1291        "default": False,
1292        "drop": False,
1293        "comment": False,
1294        "allow_null": False,
1295        "visible": False,
1296        "rename_to": False,
1297    }
arg_types = {'this': True, 'dtype': False, 'collate': False, 'using': False, 'default': False, 'drop': False, 'comment': False, 'allow_null': False, 'visible': False, 'rename_to': False}
key = 'altercolumn'
required_args = {'this'}
class AlterIndex(Expression):
1301class AlterIndex(Expression):
1302    arg_types = {"this": True, "visible": True}
arg_types = {'this': True, 'visible': True}
key = 'alterindex'
required_args = {'this', 'visible'}
class AlterDistStyle(Expression):
1306class AlterDistStyle(Expression):
1307    pass
key = 'alterdiststyle'
required_args = {'this'}
class AlterSortKey(Expression):
1310class AlterSortKey(Expression):
1311    arg_types = {"this": False, "expressions": False, "compound": False}
arg_types = {'this': False, 'expressions': False, 'compound': False}
key = 'altersortkey'
required_args = set()
class AlterSet(Expression):
1314class AlterSet(Expression):
1315    arg_types = {
1316        "expressions": False,
1317        "option": False,
1318        "tablespace": False,
1319        "access_method": False,
1320        "file_format": False,
1321        "copy_options": False,
1322        "tag": False,
1323        "location": False,
1324        "serde": False,
1325    }
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'
required_args = set()
class RenameColumn(Expression):
1328class RenameColumn(Expression):
1329    arg_types = {"this": True, "to": True, "exists": False}
arg_types = {'this': True, 'to': True, 'exists': False}
key = 'renamecolumn'
required_args = {'this', 'to'}
class AlterRename(Expression):
1332class AlterRename(Expression):
1333    pass
key = 'alterrename'
required_args = {'this'}
class SwapTable(Expression):
1336class SwapTable(Expression):
1337    pass
key = 'swaptable'
required_args = {'this'}
class Comment(Expression):
1340class Comment(Expression):
1341    arg_types = {
1342        "this": True,
1343        "kind": True,
1344        "expression": True,
1345        "exists": False,
1346        "materialized": False,
1347    }
arg_types = {'this': True, 'kind': True, 'expression': True, 'exists': False, 'materialized': False}
key = 'comment'
required_args = {'kind', 'this', 'expression'}
class Comprehension(Expression):
1350class Comprehension(Expression):
1351    arg_types = {
1352        "this": True,
1353        "expression": True,
1354        "position": False,
1355        "iterator": True,
1356        "condition": False,
1357    }
arg_types = {'this': True, 'expression': True, 'position': False, 'iterator': True, 'condition': False}
key = 'comprehension'
required_args = {'this', 'iterator', 'expression'}
class MergeTreeTTLAction(Expression):
1361class MergeTreeTTLAction(Expression):
1362    arg_types = {
1363        "this": True,
1364        "delete": False,
1365        "recompress": False,
1366        "to_disk": False,
1367        "to_volume": False,
1368    }
arg_types = {'this': True, 'delete': False, 'recompress': False, 'to_disk': False, 'to_volume': False}
key = 'mergetreettlaction'
required_args = {'this'}
class MergeTreeTTL(Expression):
1372class MergeTreeTTL(Expression):
1373    arg_types = {
1374        "expressions": True,
1375        "where": False,
1376        "group": False,
1377        "aggregates": False,
1378    }
arg_types = {'expressions': True, 'where': False, 'group': False, 'aggregates': False}
key = 'mergetreettl'
required_args = {'expressions'}
class IndexConstraintOption(Expression):
1382class IndexConstraintOption(Expression):
1383    arg_types = {
1384        "key_block_size": False,
1385        "using": False,
1386        "parser": False,
1387        "comment": False,
1388        "visible": False,
1389        "engine_attr": False,
1390        "secondary_engine_attr": False,
1391    }
arg_types = {'key_block_size': False, 'using': False, 'parser': False, 'comment': False, 'visible': False, 'engine_attr': False, 'secondary_engine_attr': False}
key = 'indexconstraintoption'
required_args = set()
class ColumnConstraint(Expression):
1394class ColumnConstraint(Expression):
1395    arg_types = {"this": False, "kind": True}
1396
1397    @property
1398    def kind(self) -> ColumnConstraintKind:
1399        return self.args["kind"]
arg_types = {'this': False, 'kind': True}
kind: ColumnConstraintKind
1397    @property
1398    def kind(self) -> ColumnConstraintKind:
1399        return self.args["kind"]
key = 'columnconstraint'
required_args = {'kind'}
class ColumnConstraintKind(Expression):
1402class ColumnConstraintKind(Expression):
1403    pass
key = 'columnconstraintkind'
required_args = {'this'}
class AutoIncrementColumnConstraint(ColumnConstraintKind):
1406class AutoIncrementColumnConstraint(ColumnConstraintKind):
1407    pass
key = 'autoincrementcolumnconstraint'
required_args = {'this'}
class ZeroFillColumnConstraint(ColumnConstraint):
1410class ZeroFillColumnConstraint(ColumnConstraint):
1411    arg_types = {}
arg_types = {}
key = 'zerofillcolumnconstraint'
required_args = set()
class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1414class PeriodForSystemTimeConstraint(ColumnConstraintKind):
1415    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'periodforsystemtimeconstraint'
required_args = {'this', 'expression'}
class CaseSpecificColumnConstraint(ColumnConstraintKind):
1418class CaseSpecificColumnConstraint(ColumnConstraintKind):
1419    arg_types = {"not_": True}
arg_types = {'not_': True}
key = 'casespecificcolumnconstraint'
required_args = {'not_'}
class CharacterSetColumnConstraint(ColumnConstraintKind):
1422class CharacterSetColumnConstraint(ColumnConstraintKind):
1423    arg_types = {"this": True}
arg_types = {'this': True}
key = 'charactersetcolumnconstraint'
required_args = {'this'}
class CheckColumnConstraint(ColumnConstraintKind):
1426class CheckColumnConstraint(ColumnConstraintKind):
1427    arg_types = {"this": True, "enforced": False}
arg_types = {'this': True, 'enforced': False}
key = 'checkcolumnconstraint'
required_args = {'this'}
class ClusteredColumnConstraint(ColumnConstraintKind):
1430class ClusteredColumnConstraint(ColumnConstraintKind):
1431    pass
key = 'clusteredcolumnconstraint'
required_args = {'this'}
class CollateColumnConstraint(ColumnConstraintKind):
1434class CollateColumnConstraint(ColumnConstraintKind):
1435    pass
key = 'collatecolumnconstraint'
required_args = {'this'}
class CommentColumnConstraint(ColumnConstraintKind):
1438class CommentColumnConstraint(ColumnConstraintKind):
1439    pass
key = 'commentcolumnconstraint'
required_args = {'this'}
class CompressColumnConstraint(ColumnConstraintKind):
1442class CompressColumnConstraint(ColumnConstraintKind):
1443    arg_types = {"this": False}
arg_types = {'this': False}
key = 'compresscolumnconstraint'
required_args = set()
class DateFormatColumnConstraint(ColumnConstraintKind):
1446class DateFormatColumnConstraint(ColumnConstraintKind):
1447    arg_types = {"this": True}
arg_types = {'this': True}
key = 'dateformatcolumnconstraint'
required_args = {'this'}
class DefaultColumnConstraint(ColumnConstraintKind):
1450class DefaultColumnConstraint(ColumnConstraintKind):
1451    pass
key = 'defaultcolumnconstraint'
required_args = {'this'}
class EncodeColumnConstraint(ColumnConstraintKind):
1454class EncodeColumnConstraint(ColumnConstraintKind):
1455    pass
key = 'encodecolumnconstraint'
required_args = {'this'}
class ExcludeColumnConstraint(ColumnConstraintKind):
1459class ExcludeColumnConstraint(ColumnConstraintKind):
1460    pass
key = 'excludecolumnconstraint'
required_args = {'this'}
class EphemeralColumnConstraint(ColumnConstraintKind):
1463class EphemeralColumnConstraint(ColumnConstraintKind):
1464    arg_types = {"this": False}
arg_types = {'this': False}
key = 'ephemeralcolumnconstraint'
required_args = set()
class WithOperator(Expression):
1467class WithOperator(Expression):
1468    arg_types = {"this": True, "op": True}
arg_types = {'this': True, 'op': True}
key = 'withoperator'
required_args = {'op', 'this'}
class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1471class GeneratedAsIdentityColumnConstraint(ColumnConstraintKind):
1472    # this: True -> ALWAYS, this: False -> BY DEFAULT
1473    arg_types = {
1474        "this": False,
1475        "expression": False,
1476        "on_null": False,
1477        "start": False,
1478        "increment": False,
1479        "minvalue": False,
1480        "maxvalue": False,
1481        "cycle": False,
1482        "order": False,
1483    }
arg_types = {'this': False, 'expression': False, 'on_null': False, 'start': False, 'increment': False, 'minvalue': False, 'maxvalue': False, 'cycle': False, 'order': False}
key = 'generatedasidentitycolumnconstraint'
required_args = set()
class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1486class GeneratedAsRowColumnConstraint(ColumnConstraintKind):
1487    arg_types = {"start": False, "hidden": False}
arg_types = {'start': False, 'hidden': False}
key = 'generatedasrowcolumnconstraint'
required_args = set()
class IndexColumnConstraint(ColumnConstraintKind):
1492class IndexColumnConstraint(ColumnConstraintKind):
1493    arg_types = {
1494        "this": False,
1495        "expressions": False,
1496        "kind": False,
1497        "index_type": False,
1498        "options": False,
1499        "expression": False,  # Clickhouse
1500        "granularity": False,
1501    }
arg_types = {'this': False, 'expressions': False, 'kind': False, 'index_type': False, 'options': False, 'expression': False, 'granularity': False}
key = 'indexcolumnconstraint'
required_args = set()
class InlineLengthColumnConstraint(ColumnConstraintKind):
1504class InlineLengthColumnConstraint(ColumnConstraintKind):
1505    pass
key = 'inlinelengthcolumnconstraint'
required_args = {'this'}
class NonClusteredColumnConstraint(ColumnConstraintKind):
1508class NonClusteredColumnConstraint(ColumnConstraintKind):
1509    pass
key = 'nonclusteredcolumnconstraint'
required_args = {'this'}
class NotForReplicationColumnConstraint(ColumnConstraintKind):
1512class NotForReplicationColumnConstraint(ColumnConstraintKind):
1513    arg_types = {}
arg_types = {}
key = 'notforreplicationcolumnconstraint'
required_args = set()
class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1517class MaskingPolicyColumnConstraint(ColumnConstraintKind):
1518    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'maskingpolicycolumnconstraint'
required_args = {'this'}
class NotNullColumnConstraint(ColumnConstraintKind):
1521class NotNullColumnConstraint(ColumnConstraintKind):
1522    arg_types = {"allow_null": False}
arg_types = {'allow_null': False}
key = 'notnullcolumnconstraint'
required_args = set()
class OnUpdateColumnConstraint(ColumnConstraintKind):
1526class OnUpdateColumnConstraint(ColumnConstraintKind):
1527    pass
key = 'onupdatecolumnconstraint'
required_args = {'this'}
class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1530class PrimaryKeyColumnConstraint(ColumnConstraintKind):
1531    arg_types = {"desc": False, "options": False}
arg_types = {'desc': False, 'options': False}
key = 'primarykeycolumnconstraint'
required_args = set()
class TitleColumnConstraint(ColumnConstraintKind):
1534class TitleColumnConstraint(ColumnConstraintKind):
1535    pass
key = 'titlecolumnconstraint'
required_args = {'this'}
class UniqueColumnConstraint(ColumnConstraintKind):
1538class UniqueColumnConstraint(ColumnConstraintKind):
1539    arg_types = {
1540        "this": False,
1541        "index_type": False,
1542        "on_conflict": False,
1543        "nulls": False,
1544        "options": False,
1545    }
arg_types = {'this': False, 'index_type': False, 'on_conflict': False, 'nulls': False, 'options': False}
key = 'uniquecolumnconstraint'
required_args = set()
class UppercaseColumnConstraint(ColumnConstraintKind):
1548class UppercaseColumnConstraint(ColumnConstraintKind):
1549    arg_types: t.ClassVar[t.Dict[str, t.Any]] = {}
arg_types: ClassVar[Dict[str, Any]] = {}
key = 'uppercasecolumnconstraint'
required_args = set()
class WatermarkColumnConstraint(Expression):
1553class WatermarkColumnConstraint(Expression):
1554    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'watermarkcolumnconstraint'
required_args = {'this', 'expression'}
class PathColumnConstraint(ColumnConstraintKind):
1557class PathColumnConstraint(ColumnConstraintKind):
1558    pass
key = 'pathcolumnconstraint'
required_args = {'this'}
class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1562class ProjectionPolicyColumnConstraint(ColumnConstraintKind):
1563    pass
key = 'projectionpolicycolumnconstraint'
required_args = {'this'}
class ComputedColumnConstraint(ColumnConstraintKind):
1568class ComputedColumnConstraint(ColumnConstraintKind):
1569    arg_types = {"this": True, "persisted": False, "not_null": False, "data_type": False}
arg_types = {'this': True, 'persisted': False, 'not_null': False, 'data_type': False}
key = 'computedcolumnconstraint'
required_args = {'this'}
class InOutColumnConstraint(ColumnConstraintKind):
1573class InOutColumnConstraint(ColumnConstraintKind):
1574    arg_types = {"input_": False, "output": False, "variadic": False}
arg_types = {'input_': False, 'output': False, 'variadic': False}
key = 'inoutcolumnconstraint'
required_args = set()
class Constraint(Expression):
1577class Constraint(Expression):
1578    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'constraint'
required_args = {'this', 'expressions'}
class Delete(DML):
1581class Delete(DML):
1582    arg_types = {
1583        "with_": False,
1584        "this": False,
1585        "using": False,
1586        "where": False,
1587        "returning": False,
1588        "order": False,
1589        "limit": False,
1590        "tables": False,  # Multiple-Table Syntax (MySQL)
1591        "cluster": False,  # Clickhouse
1592    }
1593
1594    def delete(
1595        self,
1596        table: ExpOrStr,
1597        dialect: DialectType = None,
1598        copy: bool = True,
1599        **opts,
1600    ) -> Delete:
1601        """
1602        Create a DELETE expression or replace the table on an existing DELETE expression.
1603
1604        Example:
1605            >>> delete("tbl").sql()
1606            'DELETE FROM tbl'
1607
1608        Args:
1609            table: the table from which to delete.
1610            dialect: the dialect used to parse the input expression.
1611            copy: if `False`, modify this expression instance in-place.
1612            opts: other options to use to parse the input expressions.
1613
1614        Returns:
1615            Delete: the modified expression.
1616        """
1617        return _apply_builder(
1618            expression=table,
1619            instance=self,
1620            arg="this",
1621            dialect=dialect,
1622            into=Table,
1623            copy=copy,
1624            **opts,
1625        )
1626
1627    def where(
1628        self,
1629        *expressions: t.Optional[ExpOrStr],
1630        append: bool = True,
1631        dialect: DialectType = None,
1632        copy: bool = True,
1633        **opts,
1634    ) -> Delete:
1635        """
1636        Append to or set the WHERE expressions.
1637
1638        Example:
1639            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1640            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1641
1642        Args:
1643            *expressions: the SQL code strings to parse.
1644                If an `Expression` instance is passed, it will be used as-is.
1645                Multiple expressions are combined with an AND operator.
1646            append: if `True`, AND the new expressions to any existing expression.
1647                Otherwise, this resets the expression.
1648            dialect: the dialect used to parse the input expressions.
1649            copy: if `False`, modify this expression instance in-place.
1650            opts: other options to use to parse the input expressions.
1651
1652        Returns:
1653            Delete: the modified expression.
1654        """
1655        return _apply_conjunction_builder(
1656            *expressions,
1657            instance=self,
1658            arg="where",
1659            append=append,
1660            into=Where,
1661            dialect=dialect,
1662            copy=copy,
1663            **opts,
1664        )
arg_types = {'with_': False, 'this': False, 'using': False, 'where': False, 'returning': False, 'order': 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:
1594    def delete(
1595        self,
1596        table: ExpOrStr,
1597        dialect: DialectType = None,
1598        copy: bool = True,
1599        **opts,
1600    ) -> Delete:
1601        """
1602        Create a DELETE expression or replace the table on an existing DELETE expression.
1603
1604        Example:
1605            >>> delete("tbl").sql()
1606            'DELETE FROM tbl'
1607
1608        Args:
1609            table: the table from which to delete.
1610            dialect: the dialect used to parse the input expression.
1611            copy: if `False`, modify this expression instance in-place.
1612            opts: other options to use to parse the input expressions.
1613
1614        Returns:
1615            Delete: the modified expression.
1616        """
1617        return _apply_builder(
1618            expression=table,
1619            instance=self,
1620            arg="this",
1621            dialect=dialect,
1622            into=Table,
1623            copy=copy,
1624            **opts,
1625        )

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:
1627    def where(
1628        self,
1629        *expressions: t.Optional[ExpOrStr],
1630        append: bool = True,
1631        dialect: DialectType = None,
1632        copy: bool = True,
1633        **opts,
1634    ) -> Delete:
1635        """
1636        Append to or set the WHERE expressions.
1637
1638        Example:
1639            >>> delete("tbl").where("x = 'a' OR x < 'b'").sql()
1640            "DELETE FROM tbl WHERE x = 'a' OR x < 'b'"
1641
1642        Args:
1643            *expressions: the SQL code strings to parse.
1644                If an `Expression` instance is passed, it will be used as-is.
1645                Multiple expressions are combined with an AND operator.
1646            append: if `True`, AND the new expressions to any existing expression.
1647                Otherwise, this resets the expression.
1648            dialect: the dialect used to parse the input expressions.
1649            copy: if `False`, modify this expression instance in-place.
1650            opts: other options to use to parse the input expressions.
1651
1652        Returns:
1653            Delete: the modified expression.
1654        """
1655        return _apply_conjunction_builder(
1656            *expressions,
1657            instance=self,
1658            arg="where",
1659            append=append,
1660            into=Where,
1661            dialect=dialect,
1662            copy=copy,
1663            **opts,
1664        )

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'
required_args = set()
class Drop(Expression):
1667class Drop(Expression):
1668    arg_types = {
1669        "this": False,
1670        "kind": False,
1671        "expressions": False,
1672        "exists": False,
1673        "temporary": False,
1674        "materialized": False,
1675        "cascade": False,
1676        "constraints": False,
1677        "purge": False,
1678        "cluster": False,
1679        "concurrently": False,
1680    }
1681
1682    @property
1683    def kind(self) -> t.Optional[str]:
1684        kind = self.args.get("kind")
1685        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]
1682    @property
1683    def kind(self) -> t.Optional[str]:
1684        kind = self.args.get("kind")
1685        return kind and kind.upper()
key = 'drop'
required_args = set()
class Export(Expression):
1689class Export(Expression):
1690    arg_types = {"this": True, "connection": False, "options": True}
arg_types = {'this': True, 'connection': False, 'options': True}
key = 'export'
required_args = {'options', 'this'}
class Filter(Expression):
1693class Filter(Expression):
1694    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'filter'
required_args = {'this', 'expression'}
class Check(Expression):
1697class Check(Expression):
1698    pass
key = 'check'
required_args = {'this'}
class Changes(Expression):
1701class Changes(Expression):
1702    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key = 'changes'
required_args = {'information'}
class Connect(Expression):
1706class Connect(Expression):
1707    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key = 'connect'
required_args = {'connect'}
class CopyParameter(Expression):
1710class CopyParameter(Expression):
1711    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'copyparameter'
required_args = {'this'}
class Copy(DML):
1714class Copy(DML):
1715    arg_types = {
1716        "this": True,
1717        "kind": True,
1718        "files": False,
1719        "credentials": False,
1720        "format": False,
1721        "params": False,
1722    }
arg_types = {'this': True, 'kind': True, 'files': False, 'credentials': False, 'format': False, 'params': False}
key = 'copy'
required_args = {'kind', 'this'}
class Credentials(Expression):
1725class Credentials(Expression):
1726    arg_types = {
1727        "credentials": False,
1728        "encryption": False,
1729        "storage": False,
1730        "iam_role": False,
1731        "region": False,
1732    }
arg_types = {'credentials': False, 'encryption': False, 'storage': False, 'iam_role': False, 'region': False}
key = 'credentials'
required_args = set()
class Prior(Expression):
1735class Prior(Expression):
1736    pass
key = 'prior'
required_args = {'this'}
class Directory(Expression):
1739class Directory(Expression):
1740    arg_types = {"this": True, "local": False, "row_format": False}
arg_types = {'this': True, 'local': False, 'row_format': False}
key = 'directory'
required_args = {'this'}
class DirectoryStage(Expression):
1744class DirectoryStage(Expression):
1745    pass
key = 'directorystage'
required_args = {'this'}
class ForeignKey(Expression):
1748class ForeignKey(Expression):
1749    arg_types = {
1750        "expressions": False,
1751        "reference": False,
1752        "delete": False,
1753        "update": False,
1754        "options": False,
1755    }
arg_types = {'expressions': False, 'reference': False, 'delete': False, 'update': False, 'options': False}
key = 'foreignkey'
required_args = set()
class ColumnPrefix(Expression):
1758class ColumnPrefix(Expression):
1759    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'columnprefix'
required_args = {'this', 'expression'}
class PrimaryKey(Expression):
1762class PrimaryKey(Expression):
1763    arg_types = {"this": False, "expressions": True, "options": False, "include": False}
arg_types = {'this': False, 'expressions': True, 'options': False, 'include': False}
key = 'primarykey'
required_args = {'expressions'}
class Into(Expression):
1768class Into(Expression):
1769    arg_types = {
1770        "this": False,
1771        "temporary": False,
1772        "unlogged": False,
1773        "bulk_collect": False,
1774        "expressions": False,
1775    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key = 'into'
required_args = set()
class From(Expression):
1778class From(Expression):
1779    @property
1780    def name(self) -> str:
1781        return self.this.name
1782
1783    @property
1784    def alias_or_name(self) -> str:
1785        return self.this.alias_or_name
name: str
1779    @property
1780    def name(self) -> str:
1781        return self.this.name
alias_or_name: str
1783    @property
1784    def alias_or_name(self) -> str:
1785        return self.this.alias_or_name
key = 'from'
required_args = {'this'}
class Having(Expression):
1788class Having(Expression):
1789    pass
key = 'having'
required_args = {'this'}
class Hint(Expression):
1792class Hint(Expression):
1793    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'hint'
required_args = {'expressions'}
class JoinHint(Expression):
1796class JoinHint(Expression):
1797    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key = 'joinhint'
required_args = {'this', 'expressions'}
class Identifier(Expression):
1800class Identifier(Expression):
1801    arg_types = {"this": True, "quoted": False, "global_": False, "temporary": False}
1802    _hash_raw_args = True
1803
1804    @property
1805    def quoted(self) -> bool:
1806        return bool(self.args.get("quoted"))
1807
1808    @property
1809    def output_name(self) -> str:
1810        return self.name
arg_types = {'this': True, 'quoted': False, 'global_': False, 'temporary': False}
quoted: bool
1804    @property
1805    def quoted(self) -> bool:
1806        return bool(self.args.get("quoted"))
output_name: str
1808    @property
1809    def output_name(self) -> str:
1810        return self.name
key = 'identifier'
required_args = {'this'}
class Opclass(Expression):
1814class Opclass(Expression):
1815    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'opclass'
required_args = {'this', 'expression'}
class Index(Expression):
1818class Index(Expression):
1819    arg_types = {
1820        "this": False,
1821        "table": False,
1822        "unique": False,
1823        "primary": False,
1824        "amp": False,  # teradata
1825        "params": False,
1826    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key = 'index'
required_args = set()
class IndexParameters(Expression):
1829class IndexParameters(Expression):
1830    arg_types = {
1831        "using": False,
1832        "include": False,
1833        "columns": False,
1834        "with_storage": False,
1835        "partition_by": False,
1836        "tablespace": False,
1837        "where": False,
1838        "on": False,
1839    }
arg_types = {'using': False, 'include': False, 'columns': False, 'with_storage': False, 'partition_by': False, 'tablespace': False, 'where': False, 'on': False}
key = 'indexparameters'
required_args = set()
class Insert(DDL, DML):
1842class Insert(DDL, DML):
1843    arg_types = {
1844        "hint": False,
1845        "with_": False,
1846        "is_function": False,
1847        "this": False,
1848        "expression": False,
1849        "conflict": False,
1850        "returning": False,
1851        "overwrite": False,
1852        "exists": False,
1853        "alternative": False,
1854        "where": False,
1855        "ignore": False,
1856        "by_name": False,
1857        "stored": False,
1858        "partition": False,
1859        "settings": False,
1860        "source": False,
1861        "default": False,
1862    }
1863
1864    def with_(
1865        self,
1866        alias: ExpOrStr,
1867        as_: ExpOrStr,
1868        recursive: t.Optional[bool] = None,
1869        materialized: t.Optional[bool] = None,
1870        append: bool = True,
1871        dialect: DialectType = None,
1872        copy: bool = True,
1873        **opts,
1874    ) -> Insert:
1875        """
1876        Append to or set the common table expressions.
1877
1878        Example:
1879            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1880            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1881
1882        Args:
1883            alias: the SQL code string to parse as the table name.
1884                If an `Expression` instance is passed, this is used as-is.
1885            as_: the SQL code string to parse as the table expression.
1886                If an `Expression` instance is passed, it will be used as-is.
1887            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1888            materialized: set the MATERIALIZED part of the expression.
1889            append: if `True`, add to any existing expressions.
1890                Otherwise, this resets the expressions.
1891            dialect: the dialect used to parse the input expression.
1892            copy: if `False`, modify this expression instance in-place.
1893            opts: other options to use to parse the input expressions.
1894
1895        Returns:
1896            The modified expression.
1897        """
1898        return _apply_cte_builder(
1899            self,
1900            alias,
1901            as_,
1902            recursive=recursive,
1903            materialized=materialized,
1904            append=append,
1905            dialect=dialect,
1906            copy=copy,
1907            **opts,
1908        )
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, 'default': 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:
1864    def with_(
1865        self,
1866        alias: ExpOrStr,
1867        as_: ExpOrStr,
1868        recursive: t.Optional[bool] = None,
1869        materialized: t.Optional[bool] = None,
1870        append: bool = True,
1871        dialect: DialectType = None,
1872        copy: bool = True,
1873        **opts,
1874    ) -> Insert:
1875        """
1876        Append to or set the common table expressions.
1877
1878        Example:
1879            >>> insert("SELECT x FROM cte", "t").with_("cte", as_="SELECT * FROM tbl").sql()
1880            'WITH cte AS (SELECT * FROM tbl) INSERT INTO t SELECT x FROM cte'
1881
1882        Args:
1883            alias: the SQL code string to parse as the table name.
1884                If an `Expression` instance is passed, this is used as-is.
1885            as_: the SQL code string to parse as the table expression.
1886                If an `Expression` instance is passed, it will be used as-is.
1887            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
1888            materialized: set the MATERIALIZED part of the expression.
1889            append: if `True`, add to any existing expressions.
1890                Otherwise, this resets the expressions.
1891            dialect: the dialect used to parse the input expression.
1892            copy: if `False`, modify this expression instance in-place.
1893            opts: other options to use to parse the input expressions.
1894
1895        Returns:
1896            The modified expression.
1897        """
1898        return _apply_cte_builder(
1899            self,
1900            alias,
1901            as_,
1902            recursive=recursive,
1903            materialized=materialized,
1904            append=append,
1905            dialect=dialect,
1906            copy=copy,
1907            **opts,
1908        )

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'
required_args = set()
class ConditionalInsert(Expression):
1911class ConditionalInsert(Expression):
1912    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key = 'conditionalinsert'
required_args = {'this'}
class MultitableInserts(Expression):
1915class MultitableInserts(Expression):
1916    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key = 'multitableinserts'
required_args = {'source', 'kind', 'expressions'}
class OnConflict(Expression):
1919class OnConflict(Expression):
1920    arg_types = {
1921        "duplicate": False,
1922        "expressions": False,
1923        "action": False,
1924        "conflict_keys": False,
1925        "index_predicate": False,
1926        "constraint": False,
1927        "where": False,
1928    }
arg_types = {'duplicate': False, 'expressions': False, 'action': False, 'conflict_keys': False, 'index_predicate': False, 'constraint': False, 'where': False}
key = 'onconflict'
required_args = set()
class OnCondition(Expression):
1931class OnCondition(Expression):
1932    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key = 'oncondition'
required_args = set()
class Returning(Expression):
1935class Returning(Expression):
1936    arg_types = {"expressions": True, "into": False}
arg_types = {'expressions': True, 'into': False}
key = 'returning'
required_args = {'expressions'}
class Introducer(Expression):
1940class Introducer(Expression):
1941    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key = 'introducer'
required_args = {'this', 'expression'}
class National(Expression):
1945class National(Expression):
1946    pass
key = 'national'
required_args = {'this'}
class LoadData(Expression):
1949class LoadData(Expression):
1950    arg_types = {
1951        "this": True,
1952        "local": False,
1953        "overwrite": False,
1954        "inpath": True,
1955        "partition": False,
1956        "input_format": False,
1957        "serde": False,
1958    }
arg_types = {'this': True, 'local': False, 'overwrite': False, 'inpath': True, 'partition': False, 'input_format': False, 'serde': False}
key = 'loaddata'
required_args = {'inpath', 'this'}
class Partition(Expression):
1961class Partition(Expression):
1962    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key = 'partition'
required_args = {'expressions'}
class PartitionRange(Expression):
1965class PartitionRange(Expression):
1966    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key = 'partitionrange'
required_args = {'this'}
class PartitionId(Expression):
1970class PartitionId(Expression):
1971    pass
key = 'partitionid'
required_args = {'this'}
class Fetch(Expression):
1974class Fetch(Expression):
1975    arg_types = {
1976        "direction": False,
1977        "count": False,
1978        "limit_options": False,
1979    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key = 'fetch'
required_args = set()
class Grant(Expression):
1982class Grant(Expression):
1983    arg_types = {
1984        "privileges": True,
1985        "kind": False,
1986        "securable": True,
1987        "principals": True,
1988        "grant_option": False,
1989    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key = 'grant'
required_args = {'privileges', 'principals', 'securable'}
class Revoke(Expression):
1992class Revoke(Expression):
1993    arg_types = {**Grant.arg_types, "cascade": False}
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False, 'cascade': False}
key = 'revoke'
required_args = {'privileges', 'principals', 'securable'}
class Group(Expression):
1996class Group(Expression):
1997    arg_types = {
1998        "expressions": False,
1999        "grouping_sets": False,
2000        "cube": False,
2001        "rollup": False,
2002        "totals": False,
2003        "all": False,
2004    }
arg_types = {'expressions': False, 'grouping_sets': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key = 'group'
required_args = set()
class Cube(Expression):
2007class Cube(Expression):
2008    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'cube'
required_args = set()
class Rollup(Expression):
2011class Rollup(Expression):
2012    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key = 'rollup'
required_args = set()
class GroupingSets(Expression):
2015class GroupingSets(Expression):
2016    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'groupingsets'
required_args = {'expressions'}
class Lambda(Expression):
2019class Lambda(Expression):
2020    arg_types = {"this": True, "expressions": True, "colon": False}
arg_types = {'this': True, 'expressions': True, 'colon': False}
key = 'lambda'
required_args = {'this', 'expressions'}
class Limit(Expression):
2023class Limit(Expression):
2024    arg_types = {
2025        "this": False,
2026        "expression": True,
2027        "offset": False,
2028        "limit_options": False,
2029        "expressions": False,
2030    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key = 'limit'
required_args = {'expression'}
class LimitOptions(Expression):
2033class LimitOptions(Expression):
2034    arg_types = {
2035        "percent": False,
2036        "rows": False,
2037        "with_ties": False,
2038    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key = 'limitoptions'
required_args = set()
class Literal(Condition):
2041class Literal(Condition):
2042    arg_types = {"this": True, "is_string": True}
2043    _hash_raw_args = True
2044
2045    @classmethod
2046    def number(cls, number) -> Literal | Neg:
2047        expr: Literal | Neg = cls(this=str(number), is_string=False)
2048
2049        try:
2050            to_py = expr.to_py()
2051
2052            if not isinstance(to_py, str) and to_py < 0:
2053                expr.set("this", str(abs(to_py)))
2054                expr = Neg(this=expr)
2055        except Exception:
2056            pass
2057
2058        return expr
2059
2060    @classmethod
2061    def string(cls, string) -> Literal:
2062        return cls(this=str(string), is_string=True)
2063
2064    @property
2065    def output_name(self) -> str:
2066        return self.name
2067
2068    def to_py(self) -> int | str | Decimal:
2069        if self.is_number:
2070            try:
2071                return int(self.this)
2072            except ValueError:
2073                return Decimal(self.this)
2074        return self.this
arg_types = {'this': True, 'is_string': True}
@classmethod
def number(cls, number) -> Literal | Neg:
2045    @classmethod
2046    def number(cls, number) -> Literal | Neg:
2047        expr: Literal | Neg = cls(this=str(number), is_string=False)
2048
2049        try:
2050            to_py = expr.to_py()
2051
2052            if not isinstance(to_py, str) and to_py < 0:
2053                expr.set("this", str(abs(to_py)))
2054                expr = Neg(this=expr)
2055        except Exception:
2056            pass
2057
2058        return expr
@classmethod
def string(cls, string) -> Literal:
2060    @classmethod
2061    def string(cls, string) -> Literal:
2062        return cls(this=str(string), is_string=True)
output_name: str
2064    @property
2065    def output_name(self) -> str:
2066        return self.name
def to_py(self) -> int | str | decimal.Decimal:
2068    def to_py(self) -> int | str | Decimal:
2069        if self.is_number:
2070            try:
2071                return int(self.this)
2072            except ValueError:
2073                return Decimal(self.this)
2074        return self.this
key = 'literal'
required_args = {'is_string', 'this'}
class Join(Expression):
2077class Join(Expression):
2078    arg_types = {
2079        "this": True,
2080        "on": False,
2081        "side": False,
2082        "kind": False,
2083        "using": False,
2084        "method": False,
2085        "global_": False,
2086        "hint": False,
2087        "match_condition": False,  # Snowflake
2088        "directed": False,  # Snowflake
2089        "expressions": False,
2090        "pivots": False,
2091    }
2092
2093    @property
2094    def method(self) -> str:
2095        return self.text("method").upper()
2096
2097    @property
2098    def kind(self) -> str:
2099        return self.text("kind").upper()
2100
2101    @property
2102    def side(self) -> str:
2103        return self.text("side").upper()
2104
2105    @property
2106    def hint(self) -> str:
2107        return self.text("hint").upper()
2108
2109    @property
2110    def alias_or_name(self) -> str:
2111        return self.this.alias_or_name
2112
2113    @property
2114    def is_semi_or_anti_join(self) -> bool:
2115        return self.kind in ("SEMI", "ANTI")
2116
2117    def on(
2118        self,
2119        *expressions: t.Optional[ExpOrStr],
2120        append: bool = True,
2121        dialect: DialectType = None,
2122        copy: bool = True,
2123        **opts,
2124    ) -> Join:
2125        """
2126        Append to or set the ON expressions.
2127
2128        Example:
2129            >>> import sqlglot
2130            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2131            'JOIN x ON y = 1'
2132
2133        Args:
2134            *expressions: the SQL code strings to parse.
2135                If an `Expression` instance is passed, it will be used as-is.
2136                Multiple expressions are combined with an AND operator.
2137            append: if `True`, AND the new expressions to any existing expression.
2138                Otherwise, this resets the expression.
2139            dialect: the dialect used to parse the input expressions.
2140            copy: if `False`, modify this expression instance in-place.
2141            opts: other options to use to parse the input expressions.
2142
2143        Returns:
2144            The modified Join expression.
2145        """
2146        join = _apply_conjunction_builder(
2147            *expressions,
2148            instance=self,
2149            arg="on",
2150            append=append,
2151            dialect=dialect,
2152            copy=copy,
2153            **opts,
2154        )
2155
2156        if join.kind == "CROSS":
2157            join.set("kind", None)
2158
2159        return join
2160
2161    def using(
2162        self,
2163        *expressions: t.Optional[ExpOrStr],
2164        append: bool = True,
2165        dialect: DialectType = None,
2166        copy: bool = True,
2167        **opts,
2168    ) -> Join:
2169        """
2170        Append to or set the USING expressions.
2171
2172        Example:
2173            >>> import sqlglot
2174            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2175            'JOIN x USING (foo, bla)'
2176
2177        Args:
2178            *expressions: the SQL code strings to parse.
2179                If an `Expression` instance is passed, it will be used as-is.
2180            append: if `True`, concatenate the new expressions to the existing "using" list.
2181                Otherwise, this resets the expression.
2182            dialect: the dialect used to parse the input expressions.
2183            copy: if `False`, modify this expression instance in-place.
2184            opts: other options to use to parse the input expressions.
2185
2186        Returns:
2187            The modified Join expression.
2188        """
2189        join = _apply_list_builder(
2190            *expressions,
2191            instance=self,
2192            arg="using",
2193            append=append,
2194            dialect=dialect,
2195            copy=copy,
2196            **opts,
2197        )
2198
2199        if join.kind == "CROSS":
2200            join.set("kind", None)
2201
2202        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global_': False, 'hint': False, 'match_condition': False, 'directed': False, 'expressions': False, 'pivots': False}
method: str
2093    @property
2094    def method(self) -> str:
2095        return self.text("method").upper()
kind: str
2097    @property
2098    def kind(self) -> str:
2099        return self.text("kind").upper()
side: str
2101    @property
2102    def side(self) -> str:
2103        return self.text("side").upper()
hint: str
2105    @property
2106    def hint(self) -> str:
2107        return self.text("hint").upper()
alias_or_name: str
2109    @property
2110    def alias_or_name(self) -> str:
2111        return self.this.alias_or_name
is_semi_or_anti_join: bool
2113    @property
2114    def is_semi_or_anti_join(self) -> bool:
2115        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:
2117    def on(
2118        self,
2119        *expressions: t.Optional[ExpOrStr],
2120        append: bool = True,
2121        dialect: DialectType = None,
2122        copy: bool = True,
2123        **opts,
2124    ) -> Join:
2125        """
2126        Append to or set the ON expressions.
2127
2128        Example:
2129            >>> import sqlglot
2130            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
2131            'JOIN x ON y = 1'
2132
2133        Args:
2134            *expressions: the SQL code strings to parse.
2135                If an `Expression` instance is passed, it will be used as-is.
2136                Multiple expressions are combined with an AND operator.
2137            append: if `True`, AND the new expressions to any existing expression.
2138                Otherwise, this resets the expression.
2139            dialect: the dialect used to parse the input expressions.
2140            copy: if `False`, modify this expression instance in-place.
2141            opts: other options to use to parse the input expressions.
2142
2143        Returns:
2144            The modified Join expression.
2145        """
2146        join = _apply_conjunction_builder(
2147            *expressions,
2148            instance=self,
2149            arg="on",
2150            append=append,
2151            dialect=dialect,
2152            copy=copy,
2153            **opts,
2154        )
2155
2156        if join.kind == "CROSS":
2157            join.set("kind", None)
2158
2159        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:
2161    def using(
2162        self,
2163        *expressions: t.Optional[ExpOrStr],
2164        append: bool = True,
2165        dialect: DialectType = None,
2166        copy: bool = True,
2167        **opts,
2168    ) -> Join:
2169        """
2170        Append to or set the USING expressions.
2171
2172        Example:
2173            >>> import sqlglot
2174            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
2175            'JOIN x USING (foo, bla)'
2176
2177        Args:
2178            *expressions: the SQL code strings to parse.
2179                If an `Expression` instance is passed, it will be used as-is.
2180            append: if `True`, concatenate the new expressions to the existing "using" list.
2181                Otherwise, this resets the expression.
2182            dialect: the dialect used to parse the input expressions.
2183            copy: if `False`, modify this expression instance in-place.
2184            opts: other options to use to parse the input expressions.
2185
2186        Returns:
2187            The modified Join expression.
2188        """
2189        join = _apply_list_builder(
2190            *expressions,
2191            instance=self,
2192            arg="using",
2193            append=append,
2194            dialect=dialect,
2195            copy=copy,
2196            **opts,
2197        )
2198
2199        if join.kind == "CROSS":
2200            join.set("kind", None)
2201
2202        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'
required_args = {'this'}
class Lateral(UDTF):
2205class Lateral(UDTF):
2206    arg_types = {
2207        "this": True,
2208        "view": False,
2209        "outer": False,
2210        "alias": False,
2211        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
2212        "ordinality": False,
2213    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key = 'lateral'
required_args = {'this'}
class TableFromRows(UDTF):
2218class TableFromRows(UDTF):
2219    arg_types = {
2220        "this": True,
2221        "alias": False,
2222        "joins": False,
2223        "pivots": False,
2224        "sample": False,
2225    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key = 'tablefromrows'
required_args = {'this'}
class MatchRecognizeMeasure(Expression):
2228class MatchRecognizeMeasure(Expression):
2229    arg_types = {
2230        "this": True,
2231        "window_frame": False,
2232    }
arg_types = {'this': True, 'window_frame': False}
key = 'matchrecognizemeasure'
required_args = {'this'}
class MatchRecognize(Expression):
2235class MatchRecognize(Expression):
2236    arg_types = {
2237        "partition_by": False,
2238        "order": False,
2239        "measures": False,
2240        "rows": False,
2241        "after": False,
2242        "pattern": False,
2243        "define": False,
2244        "alias": False,
2245    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key = 'matchrecognize'
required_args = set()
class Final(Expression):
2250class Final(Expression):
2251    pass
key = 'final'
required_args = {'this'}
class Offset(Expression):
2254class Offset(Expression):
2255    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key = 'offset'
required_args = {'expression'}
class Order(Expression):
2258class Order(Expression):
2259    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key = 'order'
required_args = {'expressions'}
class WithFill(Expression):
2263class WithFill(Expression):
2264    arg_types = {
2265        "from_": False,
2266        "to": False,
2267        "step": False,
2268        "interpolate": False,
2269    }
arg_types = {'from_': False, 'to': False, 'step': False, 'interpolate': False}
key = 'withfill'
required_args = set()
class Cluster(Order):
2274class Cluster(Order):
2275    pass
key = 'cluster'
required_args = {'expressions'}
class Distribute(Order):
2278class Distribute(Order):
2279    pass
key = 'distribute'
required_args = {'expressions'}
class Sort(Order):
2282class Sort(Order):
2283    pass
key = 'sort'
required_args = {'expressions'}
class Ordered(Expression):
2286class Ordered(Expression):
2287    arg_types = {"this": True, "desc": False, "nulls_first": True, "with_fill": False}
2288
2289    @property
2290    def name(self) -> str:
2291        return self.this.name
arg_types = {'this': True, 'desc': False, 'nulls_first': True, 'with_fill': False}
name: str
2289    @property
2290    def name(self) -> str:
2291        return self.this.name
key = 'ordered'
required_args = {'this', 'nulls_first'}
class Property(Expression):
2294class Property(Expression):
2295    arg_types = {"this": True, "value": True}
arg_types = {'this': True, 'value': True}
key = 'property'
required_args = {'this', 'value'}
class GrantPrivilege(Expression):
2298class GrantPrivilege(Expression):
2299    arg_types = {"this": True, "expressions": False}
arg_types = {'this': True, 'expressions': False}
key = 'grantprivilege'
required_args = {'this'}
class GrantPrincipal(Expression):
2302class GrantPrincipal(Expression):
2303    arg_types = {"this": True, "kind": False}
arg_types = {'this': True, 'kind': False}
key = 'grantprincipal'
required_args = {'this'}
class AllowedValuesProperty(Expression):
2306class AllowedValuesProperty(Expression):
2307    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key = 'allowedvaluesproperty'
required_args = {'expressions'}
class AlgorithmProperty(Property):
2310class AlgorithmProperty(Property):
2311    arg_types = {"this": True}
arg_types = {'this': True}
key = 'algorithmproperty'
required_args = {'this'}