Edit on GitHub

sqlglot expressions query.

   1"""sqlglot expressions query."""
   2
   3from __future__ import annotations
   4
   5import typing as t
   6
   7from sqlglot.errors import ParseError
   8from sqlglot.helper import trait, ensure_list
   9from sqlglot.expressions.core import (
  10    Aliases,
  11    Column,
  12    Condition,
  13    Distinct,
  14    Dot,
  15    Expr,
  16    Expression,
  17    Func,
  18    Hint,
  19    Identifier,
  20    In,
  21    _apply_builder,
  22    _apply_child_list_builder,
  23    _apply_list_builder,
  24    _apply_conjunction_builder,
  25    _apply_set_operation,
  26    ExpOrStr,
  27    QUERY_MODIFIERS,
  28    maybe_parse,
  29    maybe_copy,
  30    to_identifier,
  31    convert,
  32    and_,
  33    alias_,
  34    column,
  35)
  36
  37if t.TYPE_CHECKING:
  38    from sqlglot.dialects.dialect import DialectType
  39    from sqlglot.expressions.datatypes import DataType
  40    from sqlglot.expressions.constraints import ColumnConstraint
  41    from sqlglot.expressions.ddl import Create
  42    from sqlglot.expressions.array import Unnest
  43    from sqlglot._typing import E, ParserArgs, ParserNoDialectArgs
  44    from typing_extensions import Unpack
  45
  46    S = t.TypeVar("S", bound="SetOperation")
  47    Q = t.TypeVar("Q", bound="Query")
  48
  49
  50def _apply_cte_builder(
  51    instance: E,
  52    alias: ExpOrStr,
  53    as_: ExpOrStr,
  54    recursive: bool | None = None,
  55    materialized: bool | None = None,
  56    append: bool = True,
  57    dialect: DialectType = None,
  58    copy: bool = True,
  59    scalar: bool | None = None,
  60    **opts: Unpack[ParserNoDialectArgs],
  61) -> E:
  62    alias_expression = maybe_parse(alias, dialect=dialect, into=TableAlias, **opts)
  63    as_expression = maybe_parse(as_, dialect=dialect, copy=copy, **opts)
  64    if scalar and not isinstance(as_expression, Subquery):
  65        # scalar CTE must be wrapped in a subquery
  66        as_expression = Subquery(this=as_expression)
  67    cte = CTE(this=as_expression, alias=alias_expression, materialized=materialized, scalar=scalar)
  68    return _apply_child_list_builder(
  69        cte,
  70        instance=instance,
  71        arg="with_",
  72        append=append,
  73        copy=copy,
  74        into=With,
  75        properties={"recursive": recursive} if recursive else {},
  76    )
  77
  78
  79@trait
  80class Selectable(Expr):
  81    @property
  82    def selects(self) -> list[Expr]:
  83        raise NotImplementedError("Subclasses must implement selects")
  84
  85    @property
  86    def named_selects(self) -> list[str]:
  87        return _named_selects(self)
  88
  89
  90def _named_selects(self: Expr) -> list[str]:
  91    selectable = t.cast(Selectable, self)
  92    return [select.output_name for select in selectable.selects]
  93
  94
  95@trait
  96class DerivedTable(Selectable):
  97    @property
  98    def selects(self) -> list[Expr]:
  99        this = self.this
 100        return this.selects if isinstance(this, Query) else []
 101
 102
 103@trait
 104class UDTF(DerivedTable):
 105    @property
 106    def selects(self) -> list[Expr]:
 107        alias = self.args.get("alias")
 108        return alias.columns if alias else []
 109
 110
 111@trait
 112class Query(Selectable):
 113    """Trait for any SELECT/UNION/etc. query expression."""
 114
 115    @property
 116    def ctes(self) -> list[CTE]:
 117        with_ = self.args.get("with_")
 118        return with_.expressions if with_ else []
 119
 120    def select(
 121        self: Q,
 122        *expressions: ExpOrStr | None,
 123        append: bool = True,
 124        dialect: DialectType = None,
 125        copy: bool = True,
 126        **opts: Unpack[ParserNoDialectArgs],
 127    ) -> Q:
 128        raise NotImplementedError("Query objects must implement `select`")
 129
 130    def subquery(self, alias: ExpOrStr | None = None, copy: bool = True) -> Subquery:
 131        """
 132        Returns a `Subquery` that wraps around this query.
 133
 134        Example:
 135            >>> subquery = Select().select("x").from_("tbl").subquery()
 136            >>> Select().select("x").from_(subquery).sql()
 137            'SELECT x FROM (SELECT x FROM tbl)'
 138
 139        Args:
 140            alias: an optional alias for the subquery.
 141            copy: if `False`, modify this expression instance in-place.
 142        """
 143        instance = maybe_copy(self, copy)
 144        if not isinstance(alias, Expr):
 145            alias = TableAlias(this=to_identifier(alias)) if alias else None
 146
 147        return Subquery(this=instance, alias=alias)
 148
 149    def limit(
 150        self: Q,
 151        expression: ExpOrStr | int,
 152        dialect: DialectType = None,
 153        copy: bool = True,
 154        **opts: Unpack[ParserNoDialectArgs],
 155    ) -> Q:
 156        """
 157        Adds a LIMIT clause to this query.
 158
 159        Example:
 160            >>> Select().select("1").union(Select().select("1")).limit(1).sql()
 161            'SELECT 1 UNION SELECT 1 LIMIT 1'
 162
 163        Args:
 164            expression: the SQL code string to parse.
 165                This can also be an integer.
 166                If a `Limit` instance is passed, it will be used as-is.
 167                If another `Expr` instance is passed, it will be wrapped in a `Limit`.
 168            dialect: the dialect used to parse the input expression.
 169            copy: if `False`, modify this expression instance in-place.
 170            opts: other options to use to parse the input expressions.
 171
 172        Returns:
 173            A limited Select expression.
 174        """
 175        return _apply_builder(
 176            expression=expression,
 177            instance=self,
 178            arg="limit",
 179            into=Limit,
 180            prefix="LIMIT",
 181            dialect=dialect,
 182            copy=copy,
 183            into_arg="expression",
 184            **opts,
 185        )
 186
 187    def offset(
 188        self: Q,
 189        expression: ExpOrStr | int,
 190        dialect: DialectType = None,
 191        copy: bool = True,
 192        **opts: Unpack[ParserNoDialectArgs],
 193    ) -> Q:
 194        """
 195        Set the OFFSET expression.
 196
 197        Example:
 198            >>> Select().from_("tbl").select("x").offset(10).sql()
 199            'SELECT x FROM tbl OFFSET 10'
 200
 201        Args:
 202            expression: the SQL code string to parse.
 203                This can also be an integer.
 204                If a `Offset` instance is passed, this is used as-is.
 205                If another `Expr` instance is passed, it will be wrapped in a `Offset`.
 206            dialect: the dialect used to parse the input expression.
 207            copy: if `False`, modify this expression instance in-place.
 208            opts: other options to use to parse the input expressions.
 209
 210        Returns:
 211            The modified Select expression.
 212        """
 213        return _apply_builder(
 214            expression=expression,
 215            instance=self,
 216            arg="offset",
 217            into=Offset,
 218            prefix="OFFSET",
 219            dialect=dialect,
 220            copy=copy,
 221            into_arg="expression",
 222            **opts,
 223        )
 224
 225    def order_by(
 226        self: Q,
 227        *expressions: ExpOrStr | None,
 228        append: bool = True,
 229        dialect: DialectType = None,
 230        copy: bool = True,
 231        **opts: Unpack[ParserNoDialectArgs],
 232    ) -> Q:
 233        """
 234        Set the ORDER BY expression.
 235
 236        Example:
 237            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
 238            'SELECT x FROM tbl ORDER BY x DESC'
 239
 240        Args:
 241            *expressions: the SQL code strings to parse.
 242                If a `Group` instance is passed, this is used as-is.
 243                If another `Expr` instance is passed, it will be wrapped in a `Order`.
 244            append: if `True`, add to any existing expressions.
 245                Otherwise, this flattens all the `Order` expression into a single expression.
 246            dialect: the dialect used to parse the input expression.
 247            copy: if `False`, modify this expression instance in-place.
 248            opts: other options to use to parse the input expressions.
 249
 250        Returns:
 251            The modified Select expression.
 252        """
 253        return _apply_child_list_builder(
 254            *expressions,
 255            instance=self,
 256            arg="order",
 257            append=append,
 258            copy=copy,
 259            prefix="ORDER BY",
 260            into=Order,
 261            dialect=dialect,
 262            **opts,
 263        )
 264
 265    def where(
 266        self: Q,
 267        *expressions: ExpOrStr | None,
 268        append: bool = True,
 269        dialect: DialectType = None,
 270        copy: bool = True,
 271        **opts: Unpack[ParserNoDialectArgs],
 272    ) -> Q:
 273        """
 274        Append to or set the WHERE expressions.
 275
 276        Examples:
 277            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
 278            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
 279
 280        Args:
 281            *expressions: the SQL code strings to parse.
 282                If an `Expr` instance is passed, it will be used as-is.
 283                Multiple expressions are combined with an AND operator.
 284            append: if `True`, AND the new expressions to any existing expression.
 285                Otherwise, this resets the expression.
 286            dialect: the dialect used to parse the input expressions.
 287            copy: if `False`, modify this expression instance in-place.
 288            opts: other options to use to parse the input expressions.
 289
 290        Returns:
 291            The modified expression.
 292        """
 293        return _apply_conjunction_builder(
 294            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
 295            instance=self,
 296            arg="where",
 297            append=append,
 298            into=Where,
 299            dialect=dialect,
 300            copy=copy,
 301            **opts,
 302        )
 303
 304    def with_(
 305        self: Q,
 306        alias: ExpOrStr,
 307        as_: ExpOrStr,
 308        recursive: bool | None = None,
 309        materialized: bool | None = None,
 310        append: bool = True,
 311        dialect: DialectType = None,
 312        copy: bool = True,
 313        scalar: bool | None = None,
 314        **opts: Unpack[ParserNoDialectArgs],
 315    ) -> Q:
 316        """
 317        Append to or set the common table expressions.
 318
 319        Example:
 320            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
 321            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
 322
 323        Args:
 324            alias: the SQL code string to parse as the table name.
 325                If an `Expr` instance is passed, this is used as-is.
 326            as_: the SQL code string to parse as the table expression.
 327                If an `Expr` instance is passed, it will be used as-is.
 328            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
 329            materialized: set the MATERIALIZED part of the expression.
 330            append: if `True`, add to any existing expressions.
 331                Otherwise, this resets the expressions.
 332            dialect: the dialect used to parse the input expression.
 333            copy: if `False`, modify this expression instance in-place.
 334            scalar: if `True`, this is a scalar common table expression.
 335            opts: other options to use to parse the input expressions.
 336
 337        Returns:
 338            The modified expression.
 339        """
 340        return _apply_cte_builder(
 341            self,
 342            alias,
 343            as_,
 344            recursive=recursive,
 345            materialized=materialized,
 346            append=append,
 347            dialect=dialect,
 348            copy=copy,
 349            scalar=scalar,
 350            **opts,
 351        )
 352
 353    def union(
 354        self,
 355        *expressions: ExpOrStr,
 356        distinct: bool = True,
 357        dialect: DialectType = None,
 358        copy: bool = True,
 359        **opts: Unpack[ParserNoDialectArgs],
 360    ) -> Union:
 361        """
 362        Builds a UNION expression.
 363
 364        Example:
 365            >>> import sqlglot
 366            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
 367            'SELECT * FROM foo UNION SELECT * FROM bla'
 368
 369        Args:
 370            expressions: the SQL code strings.
 371                If `Expr` instances are passed, they will be used as-is.
 372            distinct: set the DISTINCT flag if and only if this is true.
 373            dialect: the dialect used to parse the input expression.
 374            opts: other options to use to parse the input expressions.
 375
 376        Returns:
 377            The new Union expression.
 378        """
 379        return union(self, *expressions, distinct=distinct, dialect=dialect, copy=copy, **opts)
 380
 381    def intersect(
 382        self,
 383        *expressions: ExpOrStr,
 384        distinct: bool = True,
 385        dialect: DialectType = None,
 386        copy: bool = True,
 387        **opts: Unpack[ParserNoDialectArgs],
 388    ) -> Intersect:
 389        """
 390        Builds an INTERSECT expression.
 391
 392        Example:
 393            >>> import sqlglot
 394            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
 395            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
 396
 397        Args:
 398            expressions: the SQL code strings.
 399                If `Expr` instances are passed, they will be used as-is.
 400            distinct: set the DISTINCT flag if and only if this is true.
 401            dialect: the dialect used to parse the input expression.
 402            opts: other options to use to parse the input expressions.
 403
 404        Returns:
 405            The new Intersect expression.
 406        """
 407        return intersect(self, *expressions, distinct=distinct, dialect=dialect, copy=copy, **opts)
 408
 409    def except_(
 410        self,
 411        *expressions: ExpOrStr,
 412        distinct: bool = True,
 413        dialect: DialectType = None,
 414        copy: bool = True,
 415        **opts: Unpack[ParserNoDialectArgs],
 416    ) -> Except:
 417        """
 418        Builds an EXCEPT expression.
 419
 420        Example:
 421            >>> import sqlglot
 422            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
 423            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
 424
 425        Args:
 426            expressions: the SQL code strings.
 427                If `Expr` instance are passed, they will be used as-is.
 428            distinct: set the DISTINCT flag if and only if this is true.
 429            dialect: the dialect used to parse the input expression.
 430            opts: other options to use to parse the input expressions.
 431
 432        Returns:
 433            The new Except expression.
 434        """
 435        return except_(self, *expressions, distinct=distinct, dialect=dialect, copy=copy, **opts)
 436
 437
 438class QueryBand(Expression):
 439    arg_types = {"this": True, "scope": False, "update": False}
 440
 441
 442class RecursiveWithSearch(Expression):
 443    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
 444
 445
 446class With(Expression):
 447    arg_types = {"expressions": False, "recursive": False, "search": False, "udfs": False}
 448
 449    @property
 450    def recursive(self) -> bool:
 451        return bool(self.args.get("recursive"))
 452
 453
 454class CTE(Expression, DerivedTable):
 455    arg_types = {
 456        "this": True,
 457        "alias": True,
 458        "scalar": False,
 459        "materialized": False,
 460        "key_expressions": False,
 461    }
 462
 463
 464class ProjectionDef(Expression):
 465    arg_types = {"this": True, "expression": True}
 466
 467
 468class TableAlias(Expression):
 469    arg_types = {"this": False, "columns": False}
 470
 471    @property
 472    def columns(self) -> list[t.Any]:
 473        return self.args.get("columns") or []
 474
 475
 476class BitString(Expression, Condition):
 477    is_primitive = True
 478
 479
 480class HexString(Expression, Condition):
 481    arg_types = {"this": True, "is_integer": False}
 482    is_primitive = True
 483
 484
 485class ByteString(Expression, Condition):
 486    arg_types = {"this": True, "is_bytes": False}
 487    is_primitive = True
 488
 489
 490class RawString(Expression, Condition):
 491    is_primitive = True
 492
 493
 494class UnicodeString(Expression, Condition):
 495    arg_types = {"this": True, "escape": False}
 496
 497
 498class ColumnPosition(Expression):
 499    arg_types = {"this": False, "position": True}
 500
 501
 502class ColumnDef(Expression):
 503    arg_types = {
 504        "this": True,
 505        "kind": False,
 506        "constraints": False,
 507        "exists": False,
 508        "position": False,
 509        "default": False,
 510        "output": False,
 511    }
 512
 513    @property
 514    def constraints(self) -> list[ColumnConstraint]:
 515        return self.args.get("constraints") or []
 516
 517    @property
 518    def kind(self) -> DataType | None:
 519        return self.args.get("kind")
 520
 521
 522class Changes(Expression):
 523    arg_types = {"information": True, "at_before": False, "end": False}
 524
 525
 526class Connect(Expression):
 527    arg_types = {"start": False, "connect": True, "nocycle": False}
 528
 529
 530class Prior(Expression):
 531    pass
 532
 533
 534class Into(Expression):
 535    arg_types = {
 536        "this": False,
 537        "temporary": False,
 538        "unlogged": False,
 539        "bulk_collect": False,
 540        "expressions": False,
 541    }
 542
 543
 544class From(Expression):
 545    @property
 546    def name(self) -> str:
 547        return self.this.name
 548
 549    @property
 550    def alias_or_name(self) -> str:
 551        return self.this.alias_or_name
 552
 553
 554class Having(Expression):
 555    pass
 556
 557
 558class Index(Expression):
 559    arg_types = {
 560        "this": False,
 561        "table": False,
 562        "unique": False,
 563        "primary": False,
 564        "amp": False,  # teradata
 565        "params": False,
 566    }
 567
 568
 569class ConditionalInsert(Expression):
 570    arg_types = {"this": True, "expression": False, "else_": False}
 571
 572
 573class MultitableInserts(Expression):
 574    arg_types = {"expressions": True, "kind": True, "source": True}
 575
 576
 577class OnCondition(Expression):
 578    arg_types = {"error": False, "empty": False, "null": False}
 579
 580
 581class Introducer(Expression):
 582    arg_types = {"this": True, "expression": True}
 583
 584
 585class National(Expression):
 586    is_primitive = True
 587
 588
 589class Partition(Expression):
 590    arg_types = {"expressions": True, "subpartition": False}
 591
 592
 593class PartitionRange(Expression):
 594    arg_types = {"this": True, "expression": False, "expressions": False}
 595
 596
 597class PartitionId(Expression):
 598    pass
 599
 600
 601class Fetch(Expression):
 602    arg_types = {
 603        "direction": False,
 604        "count": False,
 605        "limit_options": False,
 606    }
 607
 608
 609class Grant(Expression):
 610    arg_types = {
 611        "privileges": True,
 612        "kind": False,
 613        "securable": True,
 614        "principals": True,
 615        "grant_option": False,
 616    }
 617
 618
 619class Revoke(Expression):
 620    arg_types = {**Grant.arg_types, "cascade": False}
 621
 622
 623class Group(Expression):
 624    arg_types = {
 625        "expressions": False,
 626        "grouping_sets": False,
 627        "grouping_sets_as_group_by_element": False,
 628        "cube": False,
 629        "rollup": False,
 630        "totals": False,
 631        "all": False,
 632    }
 633
 634
 635class Cube(Expression):
 636    arg_types = {"expressions": False}
 637
 638
 639class Rollup(Expression):
 640    arg_types = {"expressions": False}
 641
 642
 643class GroupingSets(Expression):
 644    arg_types = {"expressions": True}
 645
 646
 647class Lambda(Expression):
 648    arg_types = {"this": True, "expressions": True, "colon": False}
 649
 650
 651class Limit(Expression):
 652    arg_types = {
 653        "this": False,
 654        "expression": True,
 655        "offset": False,
 656        "limit_options": False,
 657        "expressions": False,
 658    }
 659
 660
 661class LimitOptions(Expression):
 662    arg_types = {
 663        "percent": False,
 664        "rows": False,
 665        "with_ties": False,
 666    }
 667
 668
 669class Join(Expression):
 670    arg_types = {
 671        "this": True,
 672        "on": False,
 673        "side": False,
 674        "kind": False,
 675        "using": False,
 676        "method": False,
 677        "global_": False,
 678        "hint": False,
 679        "match_condition": False,  # Snowflake
 680        "directed": False,  # Snowflake
 681        "expressions": False,
 682        "pivots": False,
 683    }
 684
 685    @property
 686    def method(self) -> str:
 687        return self.text("method").upper()
 688
 689    @property
 690    def kind(self) -> str:
 691        return self.text("kind").upper()
 692
 693    @property
 694    def side(self) -> str:
 695        return self.text("side").upper()
 696
 697    @property
 698    def hint(self) -> str:
 699        return self.text("hint").upper()
 700
 701    @property
 702    def alias_or_name(self) -> str:
 703        return self.this.alias_or_name
 704
 705    @property
 706    def is_semi_or_anti_join(self) -> bool:
 707        return self.kind in ("SEMI", "ANTI")
 708
 709    def on(
 710        self,
 711        *expressions: ExpOrStr | None,
 712        append: bool = True,
 713        dialect: DialectType = None,
 714        copy: bool = True,
 715        **opts: Unpack[ParserNoDialectArgs],
 716    ) -> Join:
 717        """
 718        Append to or set the ON expressions.
 719
 720        Example:
 721            >>> import sqlglot
 722            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
 723            'JOIN x ON y = 1'
 724
 725        Args:
 726            *expressions: the SQL code strings to parse.
 727                If an `Expr` instance is passed, it will be used as-is.
 728                Multiple expressions are combined with an AND operator.
 729            append: if `True`, AND the new expressions to any existing expression.
 730                Otherwise, this resets the expression.
 731            dialect: the dialect used to parse the input expressions.
 732            copy: if `False`, modify this expression instance in-place.
 733            opts: other options to use to parse the input expressions.
 734
 735        Returns:
 736            The modified Join expression.
 737        """
 738        join = _apply_conjunction_builder(
 739            *expressions,
 740            instance=self,
 741            arg="on",
 742            append=append,
 743            dialect=dialect,
 744            copy=copy,
 745            **opts,
 746        )
 747
 748        if join.kind == "CROSS":
 749            join.set("kind", None)
 750
 751        return join
 752
 753    def using(
 754        self,
 755        *expressions: ExpOrStr | None,
 756        append: bool = True,
 757        dialect: DialectType = None,
 758        copy: bool = True,
 759        **opts: Unpack[ParserNoDialectArgs],
 760    ) -> Join:
 761        """
 762        Append to or set the USING expressions.
 763
 764        Example:
 765            >>> import sqlglot
 766            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
 767            'JOIN x USING (foo, bla)'
 768
 769        Args:
 770            *expressions: the SQL code strings to parse.
 771                If an `Expr` instance is passed, it will be used as-is.
 772            append: if `True`, concatenate the new expressions to the existing "using" list.
 773                Otherwise, this resets the expression.
 774            dialect: the dialect used to parse the input expressions.
 775            copy: if `False`, modify this expression instance in-place.
 776            opts: other options to use to parse the input expressions.
 777
 778        Returns:
 779            The modified Join expression.
 780        """
 781        join = _apply_list_builder(
 782            *expressions,
 783            instance=self,
 784            arg="using",
 785            append=append,
 786            dialect=dialect,
 787            copy=copy,
 788            **opts,
 789        )
 790
 791        if join.kind == "CROSS":
 792            join.set("kind", None)
 793
 794        return join
 795
 796
 797class Lateral(Expression, UDTF):
 798    arg_types = {
 799        "this": True,
 800        "view": False,
 801        "outer": False,
 802        "alias": False,
 803        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
 804        "ordinality": False,
 805    }
 806
 807
 808class TableFromRows(Expression, UDTF):
 809    arg_types = {
 810        "this": True,
 811        "alias": False,
 812        "joins": False,
 813        "pivots": False,
 814        "sample": False,
 815    }
 816
 817
 818class MatchRecognizeMeasure(Expression):
 819    arg_types = {
 820        "this": True,
 821        "window_frame": False,
 822    }
 823
 824
 825class MatchRecognize(Expression):
 826    arg_types = {
 827        "partition_by": False,
 828        "order": False,
 829        "measures": False,
 830        "rows": False,
 831        "after": False,
 832        "pattern": False,
 833        "define": False,
 834        "alias": False,
 835    }
 836
 837
 838class Final(Expression):
 839    pass
 840
 841
 842class Offset(Expression):
 843    arg_types = {"this": False, "expression": True, "expressions": False}
 844
 845
 846class Order(Expression):
 847    arg_types = {"this": False, "expressions": True, "siblings": False}
 848
 849
 850class WithFill(Expression):
 851    arg_types = {
 852        "from_": False,
 853        "to": False,
 854        "step": False,
 855        "interpolate": False,
 856    }
 857
 858
 859class SkipJSONColumn(Expression):
 860    arg_types = {"regexp": False, "expression": True}
 861
 862
 863class Cluster(Expression):
 864    arg_types = {"expressions": True}
 865
 866
 867class Distribute(Order):
 868    pass
 869
 870
 871class Sort(Order):
 872    pass
 873
 874
 875class Qualify(Expression):
 876    pass
 877
 878
 879class InputOutputFormat(Expression):
 880    arg_types = {"input_format": False, "output_format": False}
 881
 882
 883class Return(Expression):
 884    pass
 885
 886
 887class Tuple(Expression):
 888    arg_types = {"expressions": False}
 889
 890    def isin(
 891        self,
 892        *expressions: t.Any,
 893        query: ExpOrStr | None = None,
 894        unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None,
 895        copy: bool = True,
 896        **opts: Unpack[ParserArgs],
 897    ) -> In:
 898        return In(
 899            this=maybe_copy(self, copy),
 900            expressions=[convert(e, copy=copy) for e in expressions],
 901            query=maybe_parse(query, copy=copy, **opts) if query else None,
 902            unnest=(
 903                Unnest(
 904                    expressions=[
 905                        maybe_parse(e, copy=copy, **opts)
 906                        for e in t.cast(list[ExpOrStr], ensure_list(unnest))
 907                    ]
 908                )
 909                if unnest
 910                else None
 911            ),
 912        )
 913
 914
 915class QueryOption(Expression):
 916    arg_types = {"this": True, "expression": False}
 917
 918
 919# FOR { XML | JSON } query modifier; `kind` is the discriminant ("XML" or "JSON").
 920class ForClause(Expression):
 921    arg_types = {"kind": True, "expressions": False}
 922
 923
 924class WithTableHint(Expression):
 925    arg_types = {"expressions": True}
 926
 927
 928class IndexTableHint(Expression):
 929    arg_types = {"this": True, "expressions": False, "target": False}
 930
 931
 932class HistoricalData(Expression):
 933    arg_types = {"this": True, "kind": True, "expression": True}
 934
 935
 936class Put(Expression):
 937    arg_types = {"this": True, "target": True, "properties": False}
 938
 939
 940class Get(Expression):
 941    arg_types = {"this": True, "target": True, "properties": False}
 942
 943
 944class Table(Expression, Selectable):
 945    arg_types = {
 946        "this": False,
 947        "alias": False,
 948        "db": False,
 949        "catalog": False,
 950        "laterals": False,
 951        "joins": False,
 952        "pivots": False,
 953        "hints": False,
 954        "system_time": False,
 955        "version": False,
 956        "format": False,
 957        "pattern": False,
 958        "ordinality": False,
 959        "when": False,
 960        "only": False,
 961        "partition": False,
 962        "changes": False,
 963        "rows_from": False,
 964        "sample": False,
 965        "indexed": False,
 966    }
 967
 968    @property
 969    def name(self) -> str:
 970        if not self.this or isinstance(self.this, Func):
 971            return ""
 972        return self.this.name
 973
 974    @property
 975    def db(self) -> str:
 976        return self.text("db")
 977
 978    @property
 979    def catalog(self) -> str:
 980        return self.text("catalog")
 981
 982    @property
 983    def selects(self) -> list[Expr]:
 984        return []
 985
 986    @property
 987    def named_selects(self) -> list[str]:
 988        return []
 989
 990    @property
 991    def parts(self) -> list[Expr]:
 992        """Return the parts of a table in order catalog, db, table."""
 993        parts: list[Expr] = []
 994
 995        for arg in ("catalog", "db", "this"):
 996            part = self.args.get(arg)
 997
 998            if isinstance(part, Dot):
 999                parts.extend(part.flatten())
1000            elif isinstance(part, Expr):
1001                parts.append(part)
1002
1003        return parts
1004
1005    def to_column(self, copy: bool = True) -> Expr:
1006        parts = self.parts
1007        last_part = parts[-1]
1008
1009        if isinstance(last_part, Identifier):
1010            col: Expr = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
1011        else:
1012            # This branch will be reached if a function or array is wrapped in a `Table`
1013            col = last_part
1014
1015        alias = self.args.get("alias")
1016        if alias:
1017            col = alias_(col, alias.this, copy=copy)
1018
1019        return col
1020
1021
1022class SetOperation(Expression, Query):
1023    arg_types = {
1024        "with_": False,
1025        "this": True,
1026        "expression": True,
1027        "distinct": False,
1028        "by_name": False,
1029        "side": False,
1030        "kind": False,
1031        "on": False,
1032        **QUERY_MODIFIERS,
1033    }
1034
1035    def select(
1036        self: S,
1037        *expressions: ExpOrStr | None,
1038        append: bool = True,
1039        dialect: DialectType = None,
1040        copy: bool = True,
1041        **opts: Unpack[ParserNoDialectArgs],
1042    ) -> S:
1043        this = maybe_copy(self, copy)
1044        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1045        this.expression.unnest().select(
1046            *expressions, append=append, dialect=dialect, copy=False, **opts
1047        )
1048        return this
1049
1050    @property
1051    def named_selects(self) -> list[str]:
1052        expr: Expr = self
1053        while isinstance(expr, SetOperation):
1054            if expr.args.get("by_name"):
1055                left = t.cast(Selectable, expr.this.unnest()).named_selects
1056                right = t.cast(Selectable, expr.expression.unnest()).named_selects
1057                return list(dict.fromkeys(left + right))
1058
1059            expr = expr.this.unnest()
1060        return _named_selects(expr)
1061
1062    @property
1063    def is_star(self) -> bool:
1064        return self.this.is_star or self.expression.is_star
1065
1066    @property
1067    def selects(self) -> list[Expr]:
1068        expr: Expr = self
1069        while isinstance(expr, SetOperation):
1070            expr = expr.this.unnest()
1071        return getattr(expr, "selects", [])
1072
1073    @property
1074    def left(self) -> Query:
1075        return self.this
1076
1077    @property
1078    def right(self) -> Query:
1079        return self.expression
1080
1081    @property
1082    def kind(self) -> str:
1083        return self.text("kind").upper()
1084
1085    @property
1086    def side(self) -> str:
1087        return self.text("side").upper()
1088
1089
1090class Union(SetOperation):
1091    pass
1092
1093
1094class Except(SetOperation):
1095    pass
1096
1097
1098class Intersect(SetOperation):
1099    pass
1100
1101
1102class Values(Expression, UDTF):
1103    arg_types = {
1104        "expressions": True,
1105        "alias": False,
1106        "order": False,
1107        "limit": False,
1108        "offset": False,
1109    }
1110
1111
1112class Version(Expression):
1113    """
1114    Time travel, iceberg, bigquery etc
1115    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
1116    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
1117    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
1118    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
1119    this is either TIMESTAMP or VERSION
1120    kind is ("AS OF", "BETWEEN")
1121    """
1122
1123    arg_types = {"this": True, "kind": True, "expression": False}
1124
1125
1126class Schema(Expression):
1127    arg_types = {"this": False, "expressions": False}
1128
1129
1130class Lock(Expression):
1131    arg_types = {"update": True, "expressions": False, "wait": False, "key": False}
1132
1133
1134class Select(Expression, Query):
1135    arg_types = {
1136        "with_": False,
1137        "kind": False,
1138        "expressions": False,
1139        "hint": False,
1140        "distinct": False,
1141        "into": False,
1142        "from_": False,
1143        "operation_modifiers": False,
1144        "exclude": False,
1145        **QUERY_MODIFIERS,
1146    }
1147
1148    def from_(
1149        self,
1150        expression: ExpOrStr,
1151        dialect: DialectType = None,
1152        copy: bool = True,
1153        **opts: Unpack[ParserNoDialectArgs],
1154    ) -> Select:
1155        """
1156        Set the FROM expression.
1157
1158        Example:
1159            >>> Select().from_("tbl").select("x").sql()
1160            'SELECT x FROM tbl'
1161
1162        Args:
1163            expression : the SQL code strings to parse.
1164                If a `From` instance is passed, this is used as-is.
1165                If another `Expr` instance is passed, it will be wrapped in a `From`.
1166            dialect: the dialect used to parse the input expression.
1167            copy: if `False`, modify this expression instance in-place.
1168            opts: other options to use to parse the input expressions.
1169
1170        Returns:
1171            The modified Select expression.
1172        """
1173        return _apply_builder(
1174            expression=expression,
1175            instance=self,
1176            arg="from_",
1177            into=From,
1178            prefix="FROM",
1179            dialect=dialect,
1180            copy=copy,
1181            **opts,
1182        )
1183
1184    def group_by(
1185        self,
1186        *expressions: ExpOrStr | None,
1187        append: bool = True,
1188        dialect: DialectType = None,
1189        copy: bool = True,
1190        **opts: Unpack[ParserNoDialectArgs],
1191    ) -> Select:
1192        """
1193        Set the GROUP BY expression.
1194
1195        Example:
1196            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
1197            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
1198
1199        Args:
1200            *expressions: the SQL code strings to parse.
1201                If a `Group` instance is passed, this is used as-is.
1202                If another `Expr` instance is passed, it will be wrapped in a `Group`.
1203                If nothing is passed in then a group by is not applied to the expression
1204            append: if `True`, add to any existing expressions.
1205                Otherwise, this flattens all the `Group` expression into a single expression.
1206            dialect: the dialect used to parse the input expression.
1207            copy: if `False`, modify this expression instance in-place.
1208            opts: other options to use to parse the input expressions.
1209
1210        Returns:
1211            The modified Select expression.
1212        """
1213        if not expressions:
1214            return self if not copy else self.copy()
1215
1216        return _apply_child_list_builder(
1217            *expressions,
1218            instance=self,
1219            arg="group",
1220            append=append,
1221            copy=copy,
1222            prefix="GROUP BY",
1223            into=Group,
1224            dialect=dialect,
1225            **opts,
1226        )
1227
1228    def sort_by(
1229        self,
1230        *expressions: ExpOrStr | None,
1231        append: bool = True,
1232        dialect: DialectType = None,
1233        copy: bool = True,
1234        **opts: Unpack[ParserNoDialectArgs],
1235    ) -> Select:
1236        """
1237        Set the SORT BY expression.
1238
1239        Example:
1240            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
1241            'SELECT x FROM tbl SORT BY x DESC'
1242
1243        Args:
1244            *expressions: the SQL code strings to parse.
1245                If a `Group` instance is passed, this is used as-is.
1246                If another `Expr` instance is passed, it will be wrapped in a `SORT`.
1247            append: if `True`, add to any existing expressions.
1248                Otherwise, this flattens all the `Order` expression into a single expression.
1249            dialect: the dialect used to parse the input expression.
1250            copy: if `False`, modify this expression instance in-place.
1251            opts: other options to use to parse the input expressions.
1252
1253        Returns:
1254            The modified Select expression.
1255        """
1256        return _apply_child_list_builder(
1257            *expressions,
1258            instance=self,
1259            arg="sort",
1260            append=append,
1261            copy=copy,
1262            prefix="SORT BY",
1263            into=Sort,
1264            dialect=dialect,
1265            **opts,
1266        )
1267
1268    def cluster_by(
1269        self,
1270        *expressions: ExpOrStr | None,
1271        append: bool = True,
1272        dialect: DialectType = None,
1273        copy: bool = True,
1274        **opts: Unpack[ParserNoDialectArgs],
1275    ) -> Select:
1276        """
1277        Set the CLUSTER BY expression.
1278
1279        Example:
1280            >>> Select().from_("tbl").select("x").cluster_by("x").sql(dialect="hive")
1281            'SELECT x FROM tbl CLUSTER BY x'
1282
1283        Args:
1284            *expressions: the SQL code strings to parse.
1285                If a `Group` instance is passed, this is used as-is.
1286                If another `Expr` instance is passed, it will be wrapped in a `Cluster`.
1287            append: if `True`, add to any existing expressions.
1288                Otherwise, this flattens all the `Order` expression into a single expression.
1289            dialect: the dialect used to parse the input expression.
1290            copy: if `False`, modify this expression instance in-place.
1291            opts: other options to use to parse the input expressions.
1292
1293        Returns:
1294            The modified Select expression.
1295        """
1296        return _apply_child_list_builder(
1297            *expressions,
1298            instance=self,
1299            arg="cluster",
1300            append=append,
1301            copy=copy,
1302            prefix="CLUSTER BY",
1303            into=Cluster,
1304            dialect=dialect,
1305            **opts,
1306        )
1307
1308    def select(
1309        self,
1310        *expressions: ExpOrStr | None,
1311        append: bool = True,
1312        dialect: DialectType = None,
1313        copy: bool = True,
1314        **opts: Unpack[ParserNoDialectArgs],
1315    ) -> Select:
1316        return _apply_list_builder(
1317            *expressions,
1318            instance=self,
1319            arg="expressions",
1320            append=append,
1321            dialect=dialect,
1322            into=Expr,
1323            copy=copy,
1324            **opts,
1325        )
1326
1327    def lateral(
1328        self,
1329        *expressions: ExpOrStr | None,
1330        append: bool = True,
1331        dialect: DialectType = None,
1332        copy: bool = True,
1333        **opts: Unpack[ParserNoDialectArgs],
1334    ) -> Select:
1335        """
1336        Append to or set the LATERAL expressions.
1337
1338        Example:
1339            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
1340            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
1341
1342        Args:
1343            *expressions: the SQL code strings to parse.
1344                If an `Expr` instance is passed, it will be used as-is.
1345            append: if `True`, add to any existing expressions.
1346                Otherwise, this resets the expressions.
1347            dialect: the dialect used to parse the input expressions.
1348            copy: if `False`, modify this expression instance in-place.
1349            opts: other options to use to parse the input expressions.
1350
1351        Returns:
1352            The modified Select expression.
1353        """
1354        return _apply_list_builder(
1355            *expressions,
1356            instance=self,
1357            arg="laterals",
1358            append=append,
1359            into=Lateral,
1360            prefix="LATERAL VIEW",
1361            dialect=dialect,
1362            copy=copy,
1363            **opts,
1364        )
1365
1366    def join(
1367        self,
1368        expression: ExpOrStr,
1369        on: ExpOrStr | list[ExpOrStr] | tuple[ExpOrStr, ...] | None = None,
1370        using: ExpOrStr | list[ExpOrStr] | tuple[ExpOrStr, ...] | None = None,
1371        append: bool = True,
1372        join_type: str | None = None,
1373        join_alias: Identifier | str | None = None,
1374        dialect: DialectType = None,
1375        copy: bool = True,
1376        **opts: Unpack[ParserNoDialectArgs],
1377    ) -> Select:
1378        """
1379        Append to or set the JOIN expressions.
1380
1381        Example:
1382            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
1383            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
1384
1385            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
1386            'SELECT 1 FROM a JOIN b USING (x, y, z)'
1387
1388            Use `join_type` to change the type of join:
1389
1390            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
1391            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
1392
1393        Args:
1394            expression: the SQL code string to parse.
1395                If an `Expr` instance is passed, it will be used as-is.
1396            on: optionally specify the join "on" criteria as a SQL string.
1397                If an `Expr` instance is passed, it will be used as-is.
1398            using: optionally specify the join "using" criteria as a SQL string.
1399                If an `Expr` instance is passed, it will be used as-is.
1400            append: if `True`, add to any existing expressions.
1401                Otherwise, this resets the expressions.
1402            join_type: if set, alter the parsed join type.
1403            join_alias: an optional alias for the joined source.
1404            dialect: the dialect used to parse the input expressions.
1405            copy: if `False`, modify this expression instance in-place.
1406            opts: other options to use to parse the input expressions.
1407
1408        Returns:
1409            Select: the modified expression.
1410        """
1411        parse_args: ParserArgs = {"dialect": dialect, **opts}
1412        try:
1413            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
1414        except ParseError:
1415            expression = maybe_parse(expression, into=(Join, Expr), **parse_args)
1416
1417        join = expression if isinstance(expression, Join) else Join(this=expression)
1418
1419        if isinstance(join.this, Select):
1420            join.this.replace(join.this.subquery())
1421
1422        if join_type:
1423            new_join: Join = maybe_parse(f"FROM _ {join_type} JOIN _", **parse_args).find(Join)
1424            method = new_join.method
1425            side = new_join.side
1426            kind = new_join.kind
1427
1428            if method:
1429                join.set("method", method)
1430            if side:
1431                join.set("side", side)
1432            if kind:
1433                join.set("kind", kind)
1434
1435        if on:
1436            on_exprs: list[ExpOrStr] = ensure_list(on)
1437            on = and_(*on_exprs, dialect=dialect, copy=copy, **opts)
1438            join.set("on", on)
1439
1440        if using:
1441            using_exprs: list[ExpOrStr] = ensure_list(using)
1442            join = _apply_list_builder(
1443                *using_exprs,
1444                instance=join,
1445                arg="using",
1446                append=append,
1447                copy=copy,
1448                into=Identifier,
1449                **opts,
1450            )
1451
1452        if join_alias:
1453            join.set("this", alias_(join.this, join_alias, table=True))
1454
1455        return _apply_list_builder(
1456            join,
1457            instance=self,
1458            arg="joins",
1459            append=append,
1460            copy=copy,
1461            **opts,
1462        )
1463
1464    def having(
1465        self,
1466        *expressions: ExpOrStr | None,
1467        append: bool = True,
1468        dialect: DialectType = None,
1469        copy: bool = True,
1470        **opts: Unpack[ParserNoDialectArgs],
1471    ) -> Select:
1472        """
1473        Append to or set the HAVING expressions.
1474
1475        Example:
1476            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
1477            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
1478
1479        Args:
1480            *expressions: the SQL code strings to parse.
1481                If an `Expr` instance is passed, it will be used as-is.
1482                Multiple expressions are combined with an AND operator.
1483            append: if `True`, AND the new expressions to any existing expression.
1484                Otherwise, this resets the expression.
1485            dialect: the dialect used to parse the input expressions.
1486            copy: if `False`, modify this expression instance in-place.
1487            opts: other options to use to parse the input expressions.
1488
1489        Returns:
1490            The modified Select expression.
1491        """
1492        return _apply_conjunction_builder(
1493            *expressions,
1494            instance=self,
1495            arg="having",
1496            append=append,
1497            into=Having,
1498            dialect=dialect,
1499            copy=copy,
1500            **opts,
1501        )
1502
1503    def window(
1504        self,
1505        *expressions: ExpOrStr | None,
1506        append: bool = True,
1507        dialect: DialectType = None,
1508        copy: bool = True,
1509        **opts: Unpack[ParserNoDialectArgs],
1510    ) -> Select:
1511        return _apply_list_builder(
1512            *expressions,
1513            instance=self,
1514            arg="windows",
1515            append=append,
1516            into=Window,
1517            dialect=dialect,
1518            copy=copy,
1519            **opts,
1520        )
1521
1522    def qualify(
1523        self,
1524        *expressions: ExpOrStr | None,
1525        append: bool = True,
1526        dialect: DialectType = None,
1527        copy: bool = True,
1528        **opts: Unpack[ParserNoDialectArgs],
1529    ) -> Select:
1530        return _apply_conjunction_builder(
1531            *expressions,
1532            instance=self,
1533            arg="qualify",
1534            append=append,
1535            into=Qualify,
1536            dialect=dialect,
1537            copy=copy,
1538            **opts,
1539        )
1540
1541    def distinct(self, *ons: ExpOrStr | None, distinct: bool = True, copy: bool = True) -> Select:
1542        """
1543        Set the OFFSET expression.
1544
1545        Example:
1546            >>> Select().from_("tbl").select("x").distinct().sql()
1547            'SELECT DISTINCT x FROM tbl'
1548
1549        Args:
1550            ons: the expressions to distinct on
1551            distinct: whether the Select should be distinct
1552            copy: if `False`, modify this expression instance in-place.
1553
1554        Returns:
1555            Select: the modified expression.
1556        """
1557        instance = maybe_copy(self, copy)
1558        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
1559        instance.set("distinct", Distinct(on=on) if distinct else None)
1560        return instance
1561
1562    def ctas(
1563        self,
1564        table: ExpOrStr,
1565        properties: dict | None = None,
1566        dialect: DialectType = None,
1567        copy: bool = True,
1568        **opts: Unpack[ParserNoDialectArgs],
1569    ) -> Create:
1570        """
1571        Convert this expression to a CREATE TABLE AS statement.
1572
1573        Example:
1574            >>> Select().select("*").from_("tbl").ctas("x").sql()
1575            'CREATE TABLE x AS SELECT * FROM tbl'
1576
1577        Args:
1578            table: the SQL code string to parse as the table name.
1579                If another `Expr` instance is passed, it will be used as-is.
1580            properties: an optional mapping of table properties
1581            dialect: the dialect used to parse the input table.
1582            copy: if `False`, modify this expression instance in-place.
1583            opts: other options to use to parse the input table.
1584
1585        Returns:
1586            The new Create expression.
1587        """
1588        instance = maybe_copy(self, copy)
1589        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
1590
1591        properties_expression = None
1592        if properties:
1593            from sqlglot.expressions.properties import Properties as _Properties
1594
1595            properties_expression = _Properties.from_dict(properties)
1596
1597        from sqlglot.expressions.ddl import Create as _Create
1598
1599        return _Create(
1600            this=table_expression,
1601            kind="TABLE",
1602            expression=instance,
1603            properties=properties_expression,
1604        )
1605
1606    def lock(self, update: bool = True, copy: bool = True) -> Select:
1607        """
1608        Set the locking read mode for this expression.
1609
1610        Examples:
1611            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
1612            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
1613
1614            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
1615            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
1616
1617        Args:
1618            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
1619            copy: if `False`, modify this expression instance in-place.
1620
1621        Returns:
1622            The modified expression.
1623        """
1624        inst = maybe_copy(self, copy)
1625        inst.set("locks", [Lock(update=update)])
1626
1627        return inst
1628
1629    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
1630        """
1631        Set hints for this expression.
1632
1633        Examples:
1634            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
1635            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
1636
1637        Args:
1638            hints: The SQL code strings to parse as the hints.
1639                If an `Expr` instance is passed, it will be used as-is.
1640            dialect: The dialect used to parse the hints.
1641            copy: If `False`, modify this expression instance in-place.
1642
1643        Returns:
1644            The modified expression.
1645        """
1646        inst = maybe_copy(self, copy)
1647        inst.set(
1648            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
1649        )
1650
1651        return inst
1652
1653    @property
1654    def named_selects(self) -> list[str]:
1655        selects = []
1656
1657        for e in self.expressions:
1658            if e.alias_or_name:
1659                selects.append(e.output_name)
1660            elif isinstance(e, Aliases):
1661                selects.extend([a.name for a in e.aliases])
1662        return selects
1663
1664    @property
1665    def is_star(self) -> bool:
1666        return any(expression.is_star for expression in self.expressions)
1667
1668    @property
1669    def selects(self) -> list[Expr]:
1670        return self.expressions
1671
1672
1673class Subquery(Expression, DerivedTable, Query):
1674    is_subquery: t.ClassVar[bool] = True
1675    arg_types = {
1676        "this": True,
1677        "alias": False,
1678        "with_": False,
1679        **QUERY_MODIFIERS,
1680    }
1681
1682    def unnest(self) -> Expr:
1683        """Returns the first non subquery."""
1684        expression: Expr = self
1685        while isinstance(expression, Subquery):
1686            expression = expression.this
1687        return expression
1688
1689    def unwrap(self) -> Subquery:
1690        expression = self
1691        while expression.same_parent and expression.is_wrapper:
1692            expression = t.cast(Subquery, expression.parent)
1693        return expression
1694
1695    def select(
1696        self,
1697        *expressions: ExpOrStr | None,
1698        append: bool = True,
1699        dialect: DialectType = None,
1700        copy: bool = True,
1701        **opts: Unpack[ParserNoDialectArgs],
1702    ) -> Subquery:
1703        this = maybe_copy(self, copy)
1704        inner = this.unnest()
1705        if hasattr(inner, "select"):
1706            inner.select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1707        return this
1708
1709    @property
1710    def is_wrapper(self) -> bool:
1711        """
1712        Whether this Subquery acts as a simple wrapper around another expression.
1713
1714        SELECT * FROM (((SELECT * FROM t)))
1715                      ^
1716                      This corresponds to a "wrapper" Subquery node
1717        """
1718        return all(v is None for k, v in self.args.items() if k != "this")
1719
1720    @property
1721    def is_star(self) -> bool:
1722        return self.this.is_star
1723
1724    @property
1725    def output_name(self) -> str:
1726        return self.alias
1727
1728
1729class TableSample(Expression):
1730    arg_types = {
1731        "expressions": False,
1732        "method": False,
1733        "bucket_numerator": False,
1734        "bucket_denominator": False,
1735        "bucket_field": False,
1736        "percent": False,
1737        "rows": False,
1738        "size": False,
1739        "seed": False,
1740    }
1741
1742
1743class Tag(Expression):
1744    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
1745
1746    arg_types = {
1747        "this": False,
1748        "prefix": False,
1749        "postfix": False,
1750    }
1751
1752
1753class Pivot(Expression):
1754    arg_types = {
1755        "this": False,
1756        "alias": False,
1757        "expressions": False,
1758        "fields": False,
1759        "unpivot": False,
1760        "using": False,
1761        "group": False,
1762        "columns": False,
1763        "include_nulls": False,
1764        "default_on_null": False,
1765        "into": False,
1766        "with_": False,
1767        "identify_pivot_strings": False,
1768        "prefixed_pivot_columns": False,
1769        "pivot_column_naming": False,
1770        "value_columns_first": False,
1771    }
1772
1773    @property
1774    def unpivot(self) -> bool:
1775        return bool(self.args.get("unpivot"))
1776
1777    @property
1778    def fields(self) -> list[Expr]:
1779        return self.args.get("fields", [])
1780
1781    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1782        """
1783        Returns an ordered map of post-rename output column name -> pre-rename
1784        source-side name, in the order the (UN)PIVOT produces them.
1785
1786        For callers that just want the names, iterate the dict (or call .keys()):
1787            >>> from sqlglot import parse_one, exp
1788            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1789            >>> list(piv.output_columns(["a", "b", "c"]))
1790            ['c', 'name', 'val']
1791
1792        AST shape:
1793            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1794                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1795                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1796                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1797
1798            UNPIVOT(val FOR name IN (a, b)):
1799                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1800                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1801                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1802                             are wrapped in PivotAlias(this=Column, alias=Literal).
1803
1804        Args:
1805            pre_pivot_columns: Columns visible to the operator before it runs
1806                (e.g. the source table or subquery's projections).
1807        """
1808        if self.unpivot:
1809            excluded: set[str] = set()
1810            name_columns: list[Identifier] = []
1811            for field in self.fields:
1812                if not isinstance(field, In):
1813                    continue
1814                if isinstance(field.this, Identifier):
1815                    name_columns.append(field.this)
1816                for e in field.expressions:
1817                    excluded.update(c.output_name for c in e.find_all(Column))
1818            value_columns = [
1819                ident
1820                for e in self.expressions
1821                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1822                if isinstance(ident, Identifier)
1823            ]
1824            # T-SQL emits the value column(s) ahead of the name column, everyone else emits them after it
1825            ordered = (
1826                value_columns + name_columns
1827                if self.args.get("value_columns_first")
1828                else name_columns + value_columns
1829            )
1830            outputs = [i.name for i in ordered]
1831        else:
1832            excluded = {c.output_name for c in self.find_all(Column)}
1833            outputs = [c.output_name for c in self.args.get("columns") or []]
1834            if not outputs:
1835                outputs = [c.alias_or_name for c in self.expressions]
1836
1837        if not excluded or not outputs:
1838            return {}
1839
1840        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1841
1842        alias = self.args.get("alias")
1843        renames = alias.args.get("columns") if alias else None
1844
1845        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1846        # positionally from the front (DuckDB, Snowflake): the user's names cover
1847        # the leading N output columns, remaining columns keep their auto names.
1848        if renames:
1849            rename_names = [r.name for r in renames]
1850            post_rename = rename_names + pre_rename[len(rename_names) :]
1851        else:
1852            post_rename = pre_rename
1853
1854        return dict(zip(post_rename, pre_rename))
1855
1856
1857class UnpivotColumns(Expression):
1858    arg_types = {"this": True, "expressions": True}
1859
1860
1861class Window(Expression, Condition):
1862    arg_types = {
1863        "this": True,
1864        "partition_by": False,
1865        "order": False,
1866        "spec": False,
1867        "alias": False,
1868        "over": False,
1869        "first": False,
1870    }
1871
1872
1873class WindowSpec(Expression):
1874    arg_types = {
1875        "kind": False,
1876        "start": False,
1877        "start_side": False,
1878        "end": False,
1879        "end_side": False,
1880        "exclude": False,
1881    }
1882
1883
1884class PreWhere(Expression):
1885    pass
1886
1887
1888class Where(Expression):
1889    pass
1890
1891
1892class Analyze(Expression):
1893    arg_types = {
1894        "kind": False,
1895        "tables": False,
1896        "options": False,
1897        "mode": False,
1898        "partition": False,
1899        "expression": False,
1900        "properties": False,
1901    }
1902
1903
1904class AnalyzeStatistics(Expression):
1905    arg_types = {
1906        "kind": True,
1907        "option": False,
1908        "this": False,
1909        "expressions": False,
1910    }
1911
1912
1913class AnalyzeHistogram(Expression):
1914    arg_types = {
1915        "this": True,
1916        "expressions": True,
1917        "expression": False,
1918        "update_options": False,
1919    }
1920
1921
1922class AnalyzeSample(Expression):
1923    arg_types = {"kind": True, "sample": True}
1924
1925
1926class AnalyzeListChainedRows(Expression):
1927    arg_types = {"expression": False}
1928
1929
1930class AnalyzeDelete(Expression):
1931    arg_types = {"kind": False}
1932
1933
1934class AnalyzeWith(Expression):
1935    arg_types = {"expressions": True}
1936
1937
1938class AnalyzeValidate(Expression):
1939    arg_types = {
1940        "kind": True,
1941        "this": False,
1942        "expression": False,
1943    }
1944
1945
1946class AnalyzeColumns(Expression):
1947    pass
1948
1949
1950class UsingData(Expression):
1951    pass
1952
1953
1954class AddPartition(Expression):
1955    arg_types = {"this": True, "exists": False, "location": False}
1956
1957
1958class AttachOption(Expression):
1959    arg_types = {"this": True, "expression": False}
1960
1961
1962class DropPartition(Expression):
1963    arg_types = {"expressions": True, "exists": False}
1964
1965
1966class ReplacePartition(Expression):
1967    arg_types = {"expression": True, "source": True}
1968
1969
1970class TranslateCharacters(Expression):
1971    arg_types = {"this": True, "expression": True, "with_error": False}
1972
1973
1974class OverflowTruncateBehavior(Expression):
1975    arg_types = {"this": False, "with_count": True}
1976
1977
1978class JSON(Expression):
1979    arg_types = {"this": False, "with_": False, "unique": False}
1980
1981
1982class JSONPath(Expression):
1983    arg_types = {"expressions": True}
1984
1985    @property
1986    def output_name(self) -> str:
1987        last_segment = self.expressions[-1].this
1988        return last_segment if isinstance(last_segment, str) else ""
1989
1990
1991class JSONPathPart(Expression):
1992    arg_types = {}
1993
1994
1995class JSONPathFilter(JSONPathPart):
1996    arg_types = {"this": True}
1997
1998
1999class JSONPathKey(JSONPathPart):
2000    arg_types = {"this": True, "quoted": False}
2001
2002
2003class JSONPathRecursive(JSONPathPart):
2004    arg_types = {"this": False}
2005
2006
2007class JSONPathRoot(JSONPathPart):
2008    pass
2009
2010
2011class JSONPathScript(JSONPathPart):
2012    arg_types = {"this": True}
2013
2014
2015class JSONPathSlice(JSONPathPart):
2016    arg_types = {"start": False, "end": False, "step": False}
2017
2018
2019class JSONPathSelector(JSONPathPart):
2020    arg_types = {"this": True}
2021
2022
2023class JSONPathSubscript(JSONPathPart):
2024    arg_types = {"this": True}
2025
2026
2027class JSONPathUnion(JSONPathPart):
2028    arg_types = {"expressions": True}
2029
2030
2031class JSONPathWildcard(JSONPathPart):
2032    pass
2033
2034
2035class FormatJson(Expression):
2036    pass
2037
2038
2039class JSONKeyValue(Expression):
2040    arg_types = {"this": True, "expression": True}
2041
2042
2043class JSONColumnDef(Expression):
2044    arg_types = {
2045        "this": False,
2046        "kind": False,
2047        "path": False,
2048        "nested_schema": False,
2049        "ordinality": False,
2050        "format_json": False,
2051    }
2052
2053
2054class JSONSchema(Expression):
2055    arg_types = {"expressions": True}
2056
2057
2058class JSONValue(Expression):
2059    arg_types = {
2060        "this": True,
2061        "path": True,
2062        "returning": False,
2063        "on_condition": False,
2064    }
2065
2066
2067class JSONValueArray(Expression, Func):
2068    arg_types = {"this": True, "expression": False}
2069
2070
2071class OpenJSONColumnDef(Expression):
2072    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
2073
2074
2075class JSONExtractQuote(Expression):
2076    arg_types = {
2077        "option": True,
2078        "scalar": False,
2079    }
2080
2081
2082class ScopeResolution(Expression):
2083    arg_types = {"this": False, "expression": True}
2084
2085
2086class Stream(Expression):
2087    pass
2088
2089
2090class ModelAttribute(Expression):
2091    arg_types = {"this": True, "expression": True}
2092
2093
2094class XMLNamespace(Expression):
2095    pass
2096
2097
2098class XMLKeyValueOption(Expression):
2099    arg_types = {"this": True, "expression": False}
2100
2101
2102class Semicolon(Expression):
2103    arg_types = {}
2104
2105
2106class TableColumn(Expression):
2107    @property
2108    def output_name(self) -> str:
2109        return self.name
2110
2111
2112class Variadic(Expression):
2113    pass
2114
2115
2116class StoredProcedure(Expression):
2117    arg_types = {"this": True, "expressions": False, "wrapped": False}
2118
2119
2120class Block(Expression):
2121    arg_types = {"expressions": True, "begin": False}
2122
2123
2124class IfBlock(Expression):
2125    arg_types = {"this": True, "true": True, "false": False}
2126
2127
2128class CaseStatement(Expression):
2129    arg_types = {"this": False, "ifs": True, "default": False}
2130
2131
2132class WhileBlock(Expression):
2133    arg_types = {"this": True, "body": True, "label": False}
2134
2135
2136class LoopBlock(Expression):
2137    arg_types = {"body": True, "label": False}
2138
2139
2140class RepeatBlock(Expression):
2141    arg_types = {"body": True, "until": True, "label": False}
2142
2143
2144class Leave(Expression):
2145    pass
2146
2147
2148class Iterate(Expression):
2149    pass
2150
2151
2152class EndStatement(Expression):
2153    arg_types = {}
2154
2155
2156# https://trino.io/docs/current/udf.html
2157class FunctionSpecification(Expression):
2158    arg_types = {
2159        "this": True,
2160        "characteristics": False,
2161        "properties": False,
2162        "expression": True,
2163    }
2164
2165
2166UNWRAPPED_QUERIES = (Select, SetOperation)
2167
2168
2169def union(
2170    *expressions: ExpOrStr,
2171    distinct: bool = True,
2172    dialect: DialectType = None,
2173    copy: bool = True,
2174    **opts: Unpack[ParserNoDialectArgs],
2175) -> Union:
2176    """
2177    Initializes a syntax tree for the `UNION` operation.
2178
2179    Example:
2180        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
2181        'SELECT * FROM foo UNION SELECT * FROM bla'
2182
2183    Args:
2184        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
2185            If `Expr` instances are passed, they will be used as-is.
2186        distinct: set the DISTINCT flag if and only if this is true.
2187        dialect: the dialect used to parse the input expression.
2188        copy: whether to copy the expression.
2189        opts: other options to use to parse the input expressions.
2190
2191    Returns:
2192        The new Union instance.
2193    """
2194    assert len(expressions) >= 2, "At least two expressions are required by `union`."
2195    return _apply_set_operation(
2196        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
2197    )
2198
2199
2200def intersect(
2201    *expressions: ExpOrStr,
2202    distinct: bool = True,
2203    dialect: DialectType = None,
2204    copy: bool = True,
2205    **opts: Unpack[ParserNoDialectArgs],
2206) -> Intersect:
2207    """
2208    Initializes a syntax tree for the `INTERSECT` operation.
2209
2210    Example:
2211        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
2212        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
2213
2214    Args:
2215        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
2216            If `Expr` instances are passed, they will be used as-is.
2217        distinct: set the DISTINCT flag if and only if this is true.
2218        dialect: the dialect used to parse the input expression.
2219        copy: whether to copy the expression.
2220        opts: other options to use to parse the input expressions.
2221
2222    Returns:
2223        The new Intersect instance.
2224    """
2225    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
2226    return _apply_set_operation(
2227        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
2228    )
2229
2230
2231def except_(
2232    *expressions: ExpOrStr,
2233    distinct: bool = True,
2234    dialect: DialectType = None,
2235    copy: bool = True,
2236    **opts: Unpack[ParserNoDialectArgs],
2237) -> Except:
2238    """
2239    Initializes a syntax tree for the `EXCEPT` operation.
2240
2241    Example:
2242        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
2243        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
2244
2245    Args:
2246        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
2247            If `Expr` instances are passed, they will be used as-is.
2248        distinct: set the DISTINCT flag if and only if this is true.
2249        dialect: the dialect used to parse the input expression.
2250        copy: whether to copy the expression.
2251        opts: other options to use to parse the input expressions.
2252
2253    Returns:
2254        The new Except instance.
2255    """
2256    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
2257    return _apply_set_operation(
2258        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
2259    )
@trait
class Selectable(sqlglot.expressions.core.Expr):
80@trait
81class Selectable(Expr):
82    @property
83    def selects(self) -> list[Expr]:
84        raise NotImplementedError("Subclasses must implement selects")
85
86    @property
87    def named_selects(self) -> list[str]:
88        return _named_selects(self)
selects: list[sqlglot.expressions.core.Expr]
82    @property
83    def selects(self) -> list[Expr]:
84        raise NotImplementedError("Subclasses must implement selects")
named_selects: list[str]
86    @property
87    def named_selects(self) -> list[str]:
88        return _named_selects(self)
key: ClassVar[str] = 'selectable'
required_args: 't.ClassVar[set[str]]' = {'this'}
@trait
class DerivedTable(Selectable):
 96@trait
 97class DerivedTable(Selectable):
 98    @property
 99    def selects(self) -> list[Expr]:
100        this = self.this
101        return this.selects if isinstance(this, Query) else []
selects: list[sqlglot.expressions.core.Expr]
 98    @property
 99    def selects(self) -> list[Expr]:
100        this = self.this
101        return this.selects if isinstance(this, Query) else []
key: ClassVar[str] = 'derivedtable'
required_args: 't.ClassVar[set[str]]' = {'this'}
@trait
class UDTF(DerivedTable):
104@trait
105class UDTF(DerivedTable):
106    @property
107    def selects(self) -> list[Expr]:
108        alias = self.args.get("alias")
109        return alias.columns if alias else []
selects: list[sqlglot.expressions.core.Expr]
106    @property
107    def selects(self) -> list[Expr]:
108        alias = self.args.get("alias")
109        return alias.columns if alias else []
key: ClassVar[str] = 'udtf'
required_args: 't.ClassVar[set[str]]' = {'this'}
@trait
class Query(Selectable):
112@trait
113class Query(Selectable):
114    """Trait for any SELECT/UNION/etc. query expression."""
115
116    @property
117    def ctes(self) -> list[CTE]:
118        with_ = self.args.get("with_")
119        return with_.expressions if with_ else []
120
121    def select(
122        self: Q,
123        *expressions: ExpOrStr | None,
124        append: bool = True,
125        dialect: DialectType = None,
126        copy: bool = True,
127        **opts: Unpack[ParserNoDialectArgs],
128    ) -> Q:
129        raise NotImplementedError("Query objects must implement `select`")
130
131    def subquery(self, alias: ExpOrStr | None = None, copy: bool = True) -> Subquery:
132        """
133        Returns a `Subquery` that wraps around this query.
134
135        Example:
136            >>> subquery = Select().select("x").from_("tbl").subquery()
137            >>> Select().select("x").from_(subquery).sql()
138            'SELECT x FROM (SELECT x FROM tbl)'
139
140        Args:
141            alias: an optional alias for the subquery.
142            copy: if `False`, modify this expression instance in-place.
143        """
144        instance = maybe_copy(self, copy)
145        if not isinstance(alias, Expr):
146            alias = TableAlias(this=to_identifier(alias)) if alias else None
147
148        return Subquery(this=instance, alias=alias)
149
150    def limit(
151        self: Q,
152        expression: ExpOrStr | int,
153        dialect: DialectType = None,
154        copy: bool = True,
155        **opts: Unpack[ParserNoDialectArgs],
156    ) -> Q:
157        """
158        Adds a LIMIT clause to this query.
159
160        Example:
161            >>> Select().select("1").union(Select().select("1")).limit(1).sql()
162            'SELECT 1 UNION SELECT 1 LIMIT 1'
163
164        Args:
165            expression: the SQL code string to parse.
166                This can also be an integer.
167                If a `Limit` instance is passed, it will be used as-is.
168                If another `Expr` instance is passed, it will be wrapped in a `Limit`.
169            dialect: the dialect used to parse the input expression.
170            copy: if `False`, modify this expression instance in-place.
171            opts: other options to use to parse the input expressions.
172
173        Returns:
174            A limited Select expression.
175        """
176        return _apply_builder(
177            expression=expression,
178            instance=self,
179            arg="limit",
180            into=Limit,
181            prefix="LIMIT",
182            dialect=dialect,
183            copy=copy,
184            into_arg="expression",
185            **opts,
186        )
187
188    def offset(
189        self: Q,
190        expression: ExpOrStr | int,
191        dialect: DialectType = None,
192        copy: bool = True,
193        **opts: Unpack[ParserNoDialectArgs],
194    ) -> Q:
195        """
196        Set the OFFSET expression.
197
198        Example:
199            >>> Select().from_("tbl").select("x").offset(10).sql()
200            'SELECT x FROM tbl OFFSET 10'
201
202        Args:
203            expression: the SQL code string to parse.
204                This can also be an integer.
205                If a `Offset` instance is passed, this is used as-is.
206                If another `Expr` instance is passed, it will be wrapped in a `Offset`.
207            dialect: the dialect used to parse the input expression.
208            copy: if `False`, modify this expression instance in-place.
209            opts: other options to use to parse the input expressions.
210
211        Returns:
212            The modified Select expression.
213        """
214        return _apply_builder(
215            expression=expression,
216            instance=self,
217            arg="offset",
218            into=Offset,
219            prefix="OFFSET",
220            dialect=dialect,
221            copy=copy,
222            into_arg="expression",
223            **opts,
224        )
225
226    def order_by(
227        self: Q,
228        *expressions: ExpOrStr | None,
229        append: bool = True,
230        dialect: DialectType = None,
231        copy: bool = True,
232        **opts: Unpack[ParserNoDialectArgs],
233    ) -> Q:
234        """
235        Set the ORDER BY expression.
236
237        Example:
238            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
239            'SELECT x FROM tbl ORDER BY x DESC'
240
241        Args:
242            *expressions: the SQL code strings to parse.
243                If a `Group` instance is passed, this is used as-is.
244                If another `Expr` instance is passed, it will be wrapped in a `Order`.
245            append: if `True`, add to any existing expressions.
246                Otherwise, this flattens all the `Order` expression into a single expression.
247            dialect: the dialect used to parse the input expression.
248            copy: if `False`, modify this expression instance in-place.
249            opts: other options to use to parse the input expressions.
250
251        Returns:
252            The modified Select expression.
253        """
254        return _apply_child_list_builder(
255            *expressions,
256            instance=self,
257            arg="order",
258            append=append,
259            copy=copy,
260            prefix="ORDER BY",
261            into=Order,
262            dialect=dialect,
263            **opts,
264        )
265
266    def where(
267        self: Q,
268        *expressions: ExpOrStr | None,
269        append: bool = True,
270        dialect: DialectType = None,
271        copy: bool = True,
272        **opts: Unpack[ParserNoDialectArgs],
273    ) -> Q:
274        """
275        Append to or set the WHERE expressions.
276
277        Examples:
278            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
279            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
280
281        Args:
282            *expressions: the SQL code strings to parse.
283                If an `Expr` instance is passed, it will be used as-is.
284                Multiple expressions are combined with an AND operator.
285            append: if `True`, AND the new expressions to any existing expression.
286                Otherwise, this resets the expression.
287            dialect: the dialect used to parse the input expressions.
288            copy: if `False`, modify this expression instance in-place.
289            opts: other options to use to parse the input expressions.
290
291        Returns:
292            The modified expression.
293        """
294        return _apply_conjunction_builder(
295            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
296            instance=self,
297            arg="where",
298            append=append,
299            into=Where,
300            dialect=dialect,
301            copy=copy,
302            **opts,
303        )
304
305    def with_(
306        self: Q,
307        alias: ExpOrStr,
308        as_: ExpOrStr,
309        recursive: bool | None = None,
310        materialized: bool | None = None,
311        append: bool = True,
312        dialect: DialectType = None,
313        copy: bool = True,
314        scalar: bool | None = None,
315        **opts: Unpack[ParserNoDialectArgs],
316    ) -> Q:
317        """
318        Append to or set the common table expressions.
319
320        Example:
321            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
322            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
323
324        Args:
325            alias: the SQL code string to parse as the table name.
326                If an `Expr` instance is passed, this is used as-is.
327            as_: the SQL code string to parse as the table expression.
328                If an `Expr` instance is passed, it will be used as-is.
329            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
330            materialized: set the MATERIALIZED part of the expression.
331            append: if `True`, add to any existing expressions.
332                Otherwise, this resets the expressions.
333            dialect: the dialect used to parse the input expression.
334            copy: if `False`, modify this expression instance in-place.
335            scalar: if `True`, this is a scalar common table expression.
336            opts: other options to use to parse the input expressions.
337
338        Returns:
339            The modified expression.
340        """
341        return _apply_cte_builder(
342            self,
343            alias,
344            as_,
345            recursive=recursive,
346            materialized=materialized,
347            append=append,
348            dialect=dialect,
349            copy=copy,
350            scalar=scalar,
351            **opts,
352        )
353
354    def union(
355        self,
356        *expressions: ExpOrStr,
357        distinct: bool = True,
358        dialect: DialectType = None,
359        copy: bool = True,
360        **opts: Unpack[ParserNoDialectArgs],
361    ) -> Union:
362        """
363        Builds a UNION expression.
364
365        Example:
366            >>> import sqlglot
367            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
368            'SELECT * FROM foo UNION SELECT * FROM bla'
369
370        Args:
371            expressions: the SQL code strings.
372                If `Expr` instances are passed, they will be used as-is.
373            distinct: set the DISTINCT flag if and only if this is true.
374            dialect: the dialect used to parse the input expression.
375            opts: other options to use to parse the input expressions.
376
377        Returns:
378            The new Union expression.
379        """
380        return union(self, *expressions, distinct=distinct, dialect=dialect, copy=copy, **opts)
381
382    def intersect(
383        self,
384        *expressions: ExpOrStr,
385        distinct: bool = True,
386        dialect: DialectType = None,
387        copy: bool = True,
388        **opts: Unpack[ParserNoDialectArgs],
389    ) -> Intersect:
390        """
391        Builds an INTERSECT expression.
392
393        Example:
394            >>> import sqlglot
395            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
396            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
397
398        Args:
399            expressions: the SQL code strings.
400                If `Expr` instances are passed, they will be used as-is.
401            distinct: set the DISTINCT flag if and only if this is true.
402            dialect: the dialect used to parse the input expression.
403            opts: other options to use to parse the input expressions.
404
405        Returns:
406            The new Intersect expression.
407        """
408        return intersect(self, *expressions, distinct=distinct, dialect=dialect, copy=copy, **opts)
409
410    def except_(
411        self,
412        *expressions: ExpOrStr,
413        distinct: bool = True,
414        dialect: DialectType = None,
415        copy: bool = True,
416        **opts: Unpack[ParserNoDialectArgs],
417    ) -> Except:
418        """
419        Builds an EXCEPT expression.
420
421        Example:
422            >>> import sqlglot
423            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
424            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
425
426        Args:
427            expressions: the SQL code strings.
428                If `Expr` instance are passed, they will be used as-is.
429            distinct: set the DISTINCT flag if and only if this is true.
430            dialect: the dialect used to parse the input expression.
431            opts: other options to use to parse the input expressions.
432
433        Returns:
434            The new Except expression.
435        """
436        return except_(self, *expressions, distinct=distinct, dialect=dialect, copy=copy, **opts)

Trait for any SELECT/UNION/etc. query expression.

ctes: list[CTE]
116    @property
117    def ctes(self) -> list[CTE]:
118        with_ = self.args.get("with_")
119        return with_.expressions if with_ else []
def select( self: ~Q, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> ~Q:
121    def select(
122        self: Q,
123        *expressions: ExpOrStr | None,
124        append: bool = True,
125        dialect: DialectType = None,
126        copy: bool = True,
127        **opts: Unpack[ParserNoDialectArgs],
128    ) -> Q:
129        raise NotImplementedError("Query objects must implement `select`")
def subquery( self, alias: Union[int, str, sqlglot.expressions.core.Expr, NoneType] = None, copy: bool = True) -> Subquery:
131    def subquery(self, alias: ExpOrStr | None = None, copy: bool = True) -> Subquery:
132        """
133        Returns a `Subquery` that wraps around this query.
134
135        Example:
136            >>> subquery = Select().select("x").from_("tbl").subquery()
137            >>> Select().select("x").from_(subquery).sql()
138            'SELECT x FROM (SELECT x FROM tbl)'
139
140        Args:
141            alias: an optional alias for the subquery.
142            copy: if `False`, modify this expression instance in-place.
143        """
144        instance = maybe_copy(self, copy)
145        if not isinstance(alias, Expr):
146            alias = TableAlias(this=to_identifier(alias)) if alias else None
147
148        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[int, str, sqlglot.expressions.core.Expr], dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> ~Q:
150    def limit(
151        self: Q,
152        expression: ExpOrStr | int,
153        dialect: DialectType = None,
154        copy: bool = True,
155        **opts: Unpack[ParserNoDialectArgs],
156    ) -> Q:
157        """
158        Adds a LIMIT clause to this query.
159
160        Example:
161            >>> Select().select("1").union(Select().select("1")).limit(1).sql()
162            'SELECT 1 UNION SELECT 1 LIMIT 1'
163
164        Args:
165            expression: the SQL code string to parse.
166                This can also be an integer.
167                If a `Limit` instance is passed, it will be used as-is.
168                If another `Expr` instance is passed, it will be wrapped in a `Limit`.
169            dialect: the dialect used to parse the input expression.
170            copy: if `False`, modify this expression instance in-place.
171            opts: other options to use to parse the input expressions.
172
173        Returns:
174            A limited Select expression.
175        """
176        return _apply_builder(
177            expression=expression,
178            instance=self,
179            arg="limit",
180            into=Limit,
181            prefix="LIMIT",
182            dialect=dialect,
183            copy=copy,
184            into_arg="expression",
185            **opts,
186        )

Adds a LIMIT clause to this query.

Example:
>>> Select().select("1").union(Select().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 Expr 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[int, str, sqlglot.expressions.core.Expr], dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> ~Q:
188    def offset(
189        self: Q,
190        expression: ExpOrStr | int,
191        dialect: DialectType = None,
192        copy: bool = True,
193        **opts: Unpack[ParserNoDialectArgs],
194    ) -> Q:
195        """
196        Set the OFFSET expression.
197
198        Example:
199            >>> Select().from_("tbl").select("x").offset(10).sql()
200            'SELECT x FROM tbl OFFSET 10'
201
202        Args:
203            expression: the SQL code string to parse.
204                This can also be an integer.
205                If a `Offset` instance is passed, this is used as-is.
206                If another `Expr` instance is passed, it will be wrapped in a `Offset`.
207            dialect: the dialect used to parse the input expression.
208            copy: if `False`, modify this expression instance in-place.
209            opts: other options to use to parse the input expressions.
210
211        Returns:
212            The modified Select expression.
213        """
214        return _apply_builder(
215            expression=expression,
216            instance=self,
217            arg="offset",
218            into=Offset,
219            prefix="OFFSET",
220            dialect=dialect,
221            copy=copy,
222            into_arg="expression",
223            **opts,
224        )

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 Expr 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[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> ~Q:
226    def order_by(
227        self: Q,
228        *expressions: ExpOrStr | None,
229        append: bool = True,
230        dialect: DialectType = None,
231        copy: bool = True,
232        **opts: Unpack[ParserNoDialectArgs],
233    ) -> Q:
234        """
235        Set the ORDER BY expression.
236
237        Example:
238            >>> Select().from_("tbl").select("x").order_by("x DESC").sql()
239            'SELECT x FROM tbl ORDER BY x DESC'
240
241        Args:
242            *expressions: the SQL code strings to parse.
243                If a `Group` instance is passed, this is used as-is.
244                If another `Expr` instance is passed, it will be wrapped in a `Order`.
245            append: if `True`, add to any existing expressions.
246                Otherwise, this flattens all the `Order` expression into a single expression.
247            dialect: the dialect used to parse the input expression.
248            copy: if `False`, modify this expression instance in-place.
249            opts: other options to use to parse the input expressions.
250
251        Returns:
252            The modified Select expression.
253        """
254        return _apply_child_list_builder(
255            *expressions,
256            instance=self,
257            arg="order",
258            append=append,
259            copy=copy,
260            prefix="ORDER BY",
261            into=Order,
262            dialect=dialect,
263            **opts,
264        )

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 Expr 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.

def where( self: ~Q, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> ~Q:
266    def where(
267        self: Q,
268        *expressions: ExpOrStr | None,
269        append: bool = True,
270        dialect: DialectType = None,
271        copy: bool = True,
272        **opts: Unpack[ParserNoDialectArgs],
273    ) -> Q:
274        """
275        Append to or set the WHERE expressions.
276
277        Examples:
278            >>> Select().select("x").from_("tbl").where("x = 'a' OR x < 'b'").sql()
279            "SELECT x FROM tbl WHERE x = 'a' OR x < 'b'"
280
281        Args:
282            *expressions: the SQL code strings to parse.
283                If an `Expr` instance is passed, it will be used as-is.
284                Multiple expressions are combined with an AND operator.
285            append: if `True`, AND the new expressions to any existing expression.
286                Otherwise, this resets the expression.
287            dialect: the dialect used to parse the input expressions.
288            copy: if `False`, modify this expression instance in-place.
289            opts: other options to use to parse the input expressions.
290
291        Returns:
292            The modified expression.
293        """
294        return _apply_conjunction_builder(
295            *[expr.this if isinstance(expr, Where) else expr for expr in expressions],
296            instance=self,
297            arg="where",
298            append=append,
299            into=Where,
300            dialect=dialect,
301            copy=copy,
302            **opts,
303        )

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 Expr 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[int, str, sqlglot.expressions.core.Expr], as_: Union[int, str, sqlglot.expressions.core.Expr], recursive: bool | None = None, materialized: bool | None = None, append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, scalar: bool | None = None, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> ~Q:
305    def with_(
306        self: Q,
307        alias: ExpOrStr,
308        as_: ExpOrStr,
309        recursive: bool | None = None,
310        materialized: bool | None = None,
311        append: bool = True,
312        dialect: DialectType = None,
313        copy: bool = True,
314        scalar: bool | None = None,
315        **opts: Unpack[ParserNoDialectArgs],
316    ) -> Q:
317        """
318        Append to or set the common table expressions.
319
320        Example:
321            >>> Select().with_("tbl2", as_="SELECT * FROM tbl").select("x").from_("tbl2").sql()
322            'WITH tbl2 AS (SELECT * FROM tbl) SELECT x FROM tbl2'
323
324        Args:
325            alias: the SQL code string to parse as the table name.
326                If an `Expr` instance is passed, this is used as-is.
327            as_: the SQL code string to parse as the table expression.
328                If an `Expr` instance is passed, it will be used as-is.
329            recursive: set the RECURSIVE part of the expression. Defaults to `False`.
330            materialized: set the MATERIALIZED part of the expression.
331            append: if `True`, add to any existing expressions.
332                Otherwise, this resets the expressions.
333            dialect: the dialect used to parse the input expression.
334            copy: if `False`, modify this expression instance in-place.
335            scalar: if `True`, this is a scalar common table expression.
336            opts: other options to use to parse the input expressions.
337
338        Returns:
339            The modified expression.
340        """
341        return _apply_cte_builder(
342            self,
343            alias,
344            as_,
345            recursive=recursive,
346            materialized=materialized,
347            append=append,
348            dialect=dialect,
349            copy=copy,
350            scalar=scalar,
351            **opts,
352        )

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 Expr instance is passed, this is used as-is.
  • as_: the SQL code string to parse as the table expression. If an Expr 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[int, str, sqlglot.expressions.core.Expr], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Union:
354    def union(
355        self,
356        *expressions: ExpOrStr,
357        distinct: bool = True,
358        dialect: DialectType = None,
359        copy: bool = True,
360        **opts: Unpack[ParserNoDialectArgs],
361    ) -> Union:
362        """
363        Builds a UNION expression.
364
365        Example:
366            >>> import sqlglot
367            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
368            'SELECT * FROM foo UNION SELECT * FROM bla'
369
370        Args:
371            expressions: the SQL code strings.
372                If `Expr` instances are passed, they will be used as-is.
373            distinct: set the DISTINCT flag if and only if this is true.
374            dialect: the dialect used to parse the input expression.
375            opts: other options to use to parse the input expressions.
376
377        Returns:
378            The new Union expression.
379        """
380        return union(self, *expressions, distinct=distinct, dialect=dialect, copy=copy, **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 Expr 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[int, str, sqlglot.expressions.core.Expr], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Intersect:
382    def intersect(
383        self,
384        *expressions: ExpOrStr,
385        distinct: bool = True,
386        dialect: DialectType = None,
387        copy: bool = True,
388        **opts: Unpack[ParserNoDialectArgs],
389    ) -> Intersect:
390        """
391        Builds an INTERSECT expression.
392
393        Example:
394            >>> import sqlglot
395            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
396            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
397
398        Args:
399            expressions: the SQL code strings.
400                If `Expr` instances are passed, they will be used as-is.
401            distinct: set the DISTINCT flag if and only if this is true.
402            dialect: the dialect used to parse the input expression.
403            opts: other options to use to parse the input expressions.
404
405        Returns:
406            The new Intersect expression.
407        """
408        return intersect(self, *expressions, distinct=distinct, dialect=dialect, copy=copy, **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 Expr 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[int, str, sqlglot.expressions.core.Expr], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Except:
410    def except_(
411        self,
412        *expressions: ExpOrStr,
413        distinct: bool = True,
414        dialect: DialectType = None,
415        copy: bool = True,
416        **opts: Unpack[ParserNoDialectArgs],
417    ) -> Except:
418        """
419        Builds an EXCEPT expression.
420
421        Example:
422            >>> import sqlglot
423            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
424            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
425
426        Args:
427            expressions: the SQL code strings.
428                If `Expr` instance are passed, they will be used as-is.
429            distinct: set the DISTINCT flag if and only if this is true.
430            dialect: the dialect used to parse the input expression.
431            opts: other options to use to parse the input expressions.
432
433        Returns:
434            The new Except expression.
435        """
436        return except_(self, *expressions, distinct=distinct, dialect=dialect, copy=copy, **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 Expr 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: ClassVar[str] = 'query'
required_args: 't.ClassVar[set[str]]' = {'this'}
class QueryBand(sqlglot.expressions.core.Expression):
439class QueryBand(Expression):
440    arg_types = {"this": True, "scope": False, "update": False}
arg_types = {'this': True, 'scope': False, 'update': False}
key: ClassVar[str] = 'queryband'
required_args: 't.ClassVar[set[str]]' = {'this'}
class RecursiveWithSearch(sqlglot.expressions.core.Expression):
443class RecursiveWithSearch(Expression):
444    arg_types = {"kind": True, "this": True, "expression": True, "using": False}
arg_types = {'kind': True, 'this': True, 'expression': True, 'using': False}
key: ClassVar[str] = 'recursivewithsearch'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this', 'kind'}
class With(sqlglot.expressions.core.Expression):
447class With(Expression):
448    arg_types = {"expressions": False, "recursive": False, "search": False, "udfs": False}
449
450    @property
451    def recursive(self) -> bool:
452        return bool(self.args.get("recursive"))
arg_types = {'expressions': False, 'recursive': False, 'search': False, 'udfs': False}
recursive: bool
450    @property
451    def recursive(self) -> bool:
452        return bool(self.args.get("recursive"))
key: ClassVar[str] = 'with'
required_args: 't.ClassVar[set[str]]' = set()
455class CTE(Expression, DerivedTable):
456    arg_types = {
457        "this": True,
458        "alias": True,
459        "scalar": False,
460        "materialized": False,
461        "key_expressions": False,
462    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False, 'key_expressions': False}
key: ClassVar[str] = 'cte'
required_args: 't.ClassVar[set[str]]' = {'alias', 'this'}
class ProjectionDef(sqlglot.expressions.core.Expression):
465class ProjectionDef(Expression):
466    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key: ClassVar[str] = 'projectiondef'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this'}
class TableAlias(sqlglot.expressions.core.Expression):
469class TableAlias(Expression):
470    arg_types = {"this": False, "columns": False}
471
472    @property
473    def columns(self) -> list[t.Any]:
474        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns: list[typing.Any]
472    @property
473    def columns(self) -> list[t.Any]:
474        return self.args.get("columns") or []
key: ClassVar[str] = 'tablealias'
required_args: 't.ClassVar[set[str]]' = set()
477class BitString(Expression, Condition):
478    is_primitive = True
is_primitive = True
key: ClassVar[str] = 'bitstring'
required_args: 't.ClassVar[set[str]]' = {'this'}
481class HexString(Expression, Condition):
482    arg_types = {"this": True, "is_integer": False}
483    is_primitive = True
arg_types = {'this': True, 'is_integer': False}
is_primitive = True
key: ClassVar[str] = 'hexstring'
required_args: 't.ClassVar[set[str]]' = {'this'}
486class ByteString(Expression, Condition):
487    arg_types = {"this": True, "is_bytes": False}
488    is_primitive = True
arg_types = {'this': True, 'is_bytes': False}
is_primitive = True
key: ClassVar[str] = 'bytestring'
required_args: 't.ClassVar[set[str]]' = {'this'}
491class RawString(Expression, Condition):
492    is_primitive = True
is_primitive = True
key: ClassVar[str] = 'rawstring'
required_args: 't.ClassVar[set[str]]' = {'this'}
495class UnicodeString(Expression, Condition):
496    arg_types = {"this": True, "escape": False}
arg_types = {'this': True, 'escape': False}
key: ClassVar[str] = 'unicodestring'
required_args: 't.ClassVar[set[str]]' = {'this'}
class ColumnPosition(sqlglot.expressions.core.Expression):
499class ColumnPosition(Expression):
500    arg_types = {"this": False, "position": True}
arg_types = {'this': False, 'position': True}
key: ClassVar[str] = 'columnposition'
required_args: 't.ClassVar[set[str]]' = {'position'}
class ColumnDef(sqlglot.expressions.core.Expression):
503class ColumnDef(Expression):
504    arg_types = {
505        "this": True,
506        "kind": False,
507        "constraints": False,
508        "exists": False,
509        "position": False,
510        "default": False,
511        "output": False,
512    }
513
514    @property
515    def constraints(self) -> list[ColumnConstraint]:
516        return self.args.get("constraints") or []
517
518    @property
519    def kind(self) -> DataType | None:
520        return self.args.get("kind")
arg_types = {'this': True, 'kind': False, 'constraints': False, 'exists': False, 'position': False, 'default': False, 'output': False}
constraints: list[sqlglot.expressions.constraints.ColumnConstraint]
514    @property
515    def constraints(self) -> list[ColumnConstraint]:
516        return self.args.get("constraints") or []
kind: sqlglot.expressions.datatypes.DataType | None
518    @property
519    def kind(self) -> DataType | None:
520        return self.args.get("kind")
key: ClassVar[str] = 'columndef'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Changes(sqlglot.expressions.core.Expression):
523class Changes(Expression):
524    arg_types = {"information": True, "at_before": False, "end": False}
arg_types = {'information': True, 'at_before': False, 'end': False}
key: ClassVar[str] = 'changes'
required_args: 't.ClassVar[set[str]]' = {'information'}
class Connect(sqlglot.expressions.core.Expression):
527class Connect(Expression):
528    arg_types = {"start": False, "connect": True, "nocycle": False}
arg_types = {'start': False, 'connect': True, 'nocycle': False}
key: ClassVar[str] = 'connect'
required_args: 't.ClassVar[set[str]]' = {'connect'}
class Prior(sqlglot.expressions.core.Expression):
531class Prior(Expression):
532    pass
key: ClassVar[str] = 'prior'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Into(sqlglot.expressions.core.Expression):
535class Into(Expression):
536    arg_types = {
537        "this": False,
538        "temporary": False,
539        "unlogged": False,
540        "bulk_collect": False,
541        "expressions": False,
542    }
arg_types = {'this': False, 'temporary': False, 'unlogged': False, 'bulk_collect': False, 'expressions': False}
key: ClassVar[str] = 'into'
required_args: 't.ClassVar[set[str]]' = set()
class From(sqlglot.expressions.core.Expression):
545class From(Expression):
546    @property
547    def name(self) -> str:
548        return self.this.name
549
550    @property
551    def alias_or_name(self) -> str:
552        return self.this.alias_or_name
name: str
546    @property
547    def name(self) -> str:
548        return self.this.name
alias_or_name: str
550    @property
551    def alias_or_name(self) -> str:
552        return self.this.alias_or_name
key: ClassVar[str] = 'from'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Having(sqlglot.expressions.core.Expression):
555class Having(Expression):
556    pass
key: ClassVar[str] = 'having'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Index(sqlglot.expressions.core.Expression):
559class Index(Expression):
560    arg_types = {
561        "this": False,
562        "table": False,
563        "unique": False,
564        "primary": False,
565        "amp": False,  # teradata
566        "params": False,
567    }
arg_types = {'this': False, 'table': False, 'unique': False, 'primary': False, 'amp': False, 'params': False}
key: ClassVar[str] = 'index'
required_args: 't.ClassVar[set[str]]' = set()
class ConditionalInsert(sqlglot.expressions.core.Expression):
570class ConditionalInsert(Expression):
571    arg_types = {"this": True, "expression": False, "else_": False}
arg_types = {'this': True, 'expression': False, 'else_': False}
key: ClassVar[str] = 'conditionalinsert'
required_args: 't.ClassVar[set[str]]' = {'this'}
class MultitableInserts(sqlglot.expressions.core.Expression):
574class MultitableInserts(Expression):
575    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key: ClassVar[str] = 'multitableinserts'
required_args: 't.ClassVar[set[str]]' = {'source', 'kind', 'expressions'}
class OnCondition(sqlglot.expressions.core.Expression):
578class OnCondition(Expression):
579    arg_types = {"error": False, "empty": False, "null": False}
arg_types = {'error': False, 'empty': False, 'null': False}
key: ClassVar[str] = 'oncondition'
required_args: 't.ClassVar[set[str]]' = set()
class Introducer(sqlglot.expressions.core.Expression):
582class Introducer(Expression):
583    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key: ClassVar[str] = 'introducer'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this'}
class National(sqlglot.expressions.core.Expression):
586class National(Expression):
587    is_primitive = True
is_primitive = True
key: ClassVar[str] = 'national'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Partition(sqlglot.expressions.core.Expression):
590class Partition(Expression):
591    arg_types = {"expressions": True, "subpartition": False}
arg_types = {'expressions': True, 'subpartition': False}
key: ClassVar[str] = 'partition'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class PartitionRange(sqlglot.expressions.core.Expression):
594class PartitionRange(Expression):
595    arg_types = {"this": True, "expression": False, "expressions": False}
arg_types = {'this': True, 'expression': False, 'expressions': False}
key: ClassVar[str] = 'partitionrange'
required_args: 't.ClassVar[set[str]]' = {'this'}
class PartitionId(sqlglot.expressions.core.Expression):
598class PartitionId(Expression):
599    pass
key: ClassVar[str] = 'partitionid'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Fetch(sqlglot.expressions.core.Expression):
602class Fetch(Expression):
603    arg_types = {
604        "direction": False,
605        "count": False,
606        "limit_options": False,
607    }
arg_types = {'direction': False, 'count': False, 'limit_options': False}
key: ClassVar[str] = 'fetch'
required_args: 't.ClassVar[set[str]]' = set()
class Grant(sqlglot.expressions.core.Expression):
610class Grant(Expression):
611    arg_types = {
612        "privileges": True,
613        "kind": False,
614        "securable": True,
615        "principals": True,
616        "grant_option": False,
617    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key: ClassVar[str] = 'grant'
required_args: 't.ClassVar[set[str]]' = {'securable', 'privileges', 'principals'}
class Revoke(sqlglot.expressions.core.Expression):
620class Revoke(Expression):
621    arg_types = {**Grant.arg_types, "cascade": False}
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False, 'cascade': False}
key: ClassVar[str] = 'revoke'
required_args: 't.ClassVar[set[str]]' = {'securable', 'privileges', 'principals'}
class Group(sqlglot.expressions.core.Expression):
624class Group(Expression):
625    arg_types = {
626        "expressions": False,
627        "grouping_sets": False,
628        "grouping_sets_as_group_by_element": False,
629        "cube": False,
630        "rollup": False,
631        "totals": False,
632        "all": False,
633    }
arg_types = {'expressions': False, 'grouping_sets': False, 'grouping_sets_as_group_by_element': False, 'cube': False, 'rollup': False, 'totals': False, 'all': False}
key: ClassVar[str] = 'group'
required_args: 't.ClassVar[set[str]]' = set()
class Cube(sqlglot.expressions.core.Expression):
636class Cube(Expression):
637    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key: ClassVar[str] = 'cube'
required_args: 't.ClassVar[set[str]]' = set()
class Rollup(sqlglot.expressions.core.Expression):
640class Rollup(Expression):
641    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key: ClassVar[str] = 'rollup'
required_args: 't.ClassVar[set[str]]' = set()
class GroupingSets(sqlglot.expressions.core.Expression):
644class GroupingSets(Expression):
645    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'groupingsets'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Lambda(sqlglot.expressions.core.Expression):
648class Lambda(Expression):
649    arg_types = {"this": True, "expressions": True, "colon": False}
arg_types = {'this': True, 'expressions': True, 'colon': False}
key: ClassVar[str] = 'lambda'
required_args: 't.ClassVar[set[str]]' = {'this', 'expressions'}
class Limit(sqlglot.expressions.core.Expression):
652class Limit(Expression):
653    arg_types = {
654        "this": False,
655        "expression": True,
656        "offset": False,
657        "limit_options": False,
658        "expressions": False,
659    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key: ClassVar[str] = 'limit'
required_args: 't.ClassVar[set[str]]' = {'expression'}
class LimitOptions(sqlglot.expressions.core.Expression):
662class LimitOptions(Expression):
663    arg_types = {
664        "percent": False,
665        "rows": False,
666        "with_ties": False,
667    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key: ClassVar[str] = 'limitoptions'
required_args: 't.ClassVar[set[str]]' = set()
class Join(sqlglot.expressions.core.Expression):
670class Join(Expression):
671    arg_types = {
672        "this": True,
673        "on": False,
674        "side": False,
675        "kind": False,
676        "using": False,
677        "method": False,
678        "global_": False,
679        "hint": False,
680        "match_condition": False,  # Snowflake
681        "directed": False,  # Snowflake
682        "expressions": False,
683        "pivots": False,
684    }
685
686    @property
687    def method(self) -> str:
688        return self.text("method").upper()
689
690    @property
691    def kind(self) -> str:
692        return self.text("kind").upper()
693
694    @property
695    def side(self) -> str:
696        return self.text("side").upper()
697
698    @property
699    def hint(self) -> str:
700        return self.text("hint").upper()
701
702    @property
703    def alias_or_name(self) -> str:
704        return self.this.alias_or_name
705
706    @property
707    def is_semi_or_anti_join(self) -> bool:
708        return self.kind in ("SEMI", "ANTI")
709
710    def on(
711        self,
712        *expressions: ExpOrStr | None,
713        append: bool = True,
714        dialect: DialectType = None,
715        copy: bool = True,
716        **opts: Unpack[ParserNoDialectArgs],
717    ) -> Join:
718        """
719        Append to or set the ON expressions.
720
721        Example:
722            >>> import sqlglot
723            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
724            'JOIN x ON y = 1'
725
726        Args:
727            *expressions: the SQL code strings to parse.
728                If an `Expr` instance is passed, it will be used as-is.
729                Multiple expressions are combined with an AND operator.
730            append: if `True`, AND the new expressions to any existing expression.
731                Otherwise, this resets the expression.
732            dialect: the dialect used to parse the input expressions.
733            copy: if `False`, modify this expression instance in-place.
734            opts: other options to use to parse the input expressions.
735
736        Returns:
737            The modified Join expression.
738        """
739        join = _apply_conjunction_builder(
740            *expressions,
741            instance=self,
742            arg="on",
743            append=append,
744            dialect=dialect,
745            copy=copy,
746            **opts,
747        )
748
749        if join.kind == "CROSS":
750            join.set("kind", None)
751
752        return join
753
754    def using(
755        self,
756        *expressions: ExpOrStr | None,
757        append: bool = True,
758        dialect: DialectType = None,
759        copy: bool = True,
760        **opts: Unpack[ParserNoDialectArgs],
761    ) -> Join:
762        """
763        Append to or set the USING expressions.
764
765        Example:
766            >>> import sqlglot
767            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
768            'JOIN x USING (foo, bla)'
769
770        Args:
771            *expressions: the SQL code strings to parse.
772                If an `Expr` instance is passed, it will be used as-is.
773            append: if `True`, concatenate the new expressions to the existing "using" list.
774                Otherwise, this resets the expression.
775            dialect: the dialect used to parse the input expressions.
776            copy: if `False`, modify this expression instance in-place.
777            opts: other options to use to parse the input expressions.
778
779        Returns:
780            The modified Join expression.
781        """
782        join = _apply_list_builder(
783            *expressions,
784            instance=self,
785            arg="using",
786            append=append,
787            dialect=dialect,
788            copy=copy,
789            **opts,
790        )
791
792        if join.kind == "CROSS":
793            join.set("kind", None)
794
795        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
686    @property
687    def method(self) -> str:
688        return self.text("method").upper()
kind: str
690    @property
691    def kind(self) -> str:
692        return self.text("kind").upper()
side: str
694    @property
695    def side(self) -> str:
696        return self.text("side").upper()
hint: str
698    @property
699    def hint(self) -> str:
700        return self.text("hint").upper()
alias_or_name: str
702    @property
703    def alias_or_name(self) -> str:
704        return self.this.alias_or_name
is_semi_or_anti_join: bool
706    @property
707    def is_semi_or_anti_join(self) -> bool:
708        return self.kind in ("SEMI", "ANTI")
def on( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Join:
710    def on(
711        self,
712        *expressions: ExpOrStr | None,
713        append: bool = True,
714        dialect: DialectType = None,
715        copy: bool = True,
716        **opts: Unpack[ParserNoDialectArgs],
717    ) -> Join:
718        """
719        Append to or set the ON expressions.
720
721        Example:
722            >>> import sqlglot
723            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
724            'JOIN x ON y = 1'
725
726        Args:
727            *expressions: the SQL code strings to parse.
728                If an `Expr` instance is passed, it will be used as-is.
729                Multiple expressions are combined with an AND operator.
730            append: if `True`, AND the new expressions to any existing expression.
731                Otherwise, this resets the expression.
732            dialect: the dialect used to parse the input expressions.
733            copy: if `False`, modify this expression instance in-place.
734            opts: other options to use to parse the input expressions.
735
736        Returns:
737            The modified Join expression.
738        """
739        join = _apply_conjunction_builder(
740            *expressions,
741            instance=self,
742            arg="on",
743            append=append,
744            dialect=dialect,
745            copy=copy,
746            **opts,
747        )
748
749        if join.kind == "CROSS":
750            join.set("kind", None)
751
752        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 Expr 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[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Join:
754    def using(
755        self,
756        *expressions: ExpOrStr | None,
757        append: bool = True,
758        dialect: DialectType = None,
759        copy: bool = True,
760        **opts: Unpack[ParserNoDialectArgs],
761    ) -> Join:
762        """
763        Append to or set the USING expressions.
764
765        Example:
766            >>> import sqlglot
767            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
768            'JOIN x USING (foo, bla)'
769
770        Args:
771            *expressions: the SQL code strings to parse.
772                If an `Expr` instance is passed, it will be used as-is.
773            append: if `True`, concatenate the new expressions to the existing "using" list.
774                Otherwise, this resets the expression.
775            dialect: the dialect used to parse the input expressions.
776            copy: if `False`, modify this expression instance in-place.
777            opts: other options to use to parse the input expressions.
778
779        Returns:
780            The modified Join expression.
781        """
782        join = _apply_list_builder(
783            *expressions,
784            instance=self,
785            arg="using",
786            append=append,
787            dialect=dialect,
788            copy=copy,
789            **opts,
790        )
791
792        if join.kind == "CROSS":
793            join.set("kind", None)
794
795        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 Expr 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: ClassVar[str] = 'join'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Lateral(sqlglot.expressions.core.Expression, UDTF):
798class Lateral(Expression, UDTF):
799    arg_types = {
800        "this": True,
801        "view": False,
802        "outer": False,
803        "alias": False,
804        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
805        "ordinality": False,
806    }
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
key: ClassVar[str] = 'lateral'
required_args: 't.ClassVar[set[str]]' = {'this'}
class TableFromRows(sqlglot.expressions.core.Expression, UDTF):
809class TableFromRows(Expression, UDTF):
810    arg_types = {
811        "this": True,
812        "alias": False,
813        "joins": False,
814        "pivots": False,
815        "sample": False,
816    }
arg_types = {'this': True, 'alias': False, 'joins': False, 'pivots': False, 'sample': False}
key: ClassVar[str] = 'tablefromrows'
required_args: 't.ClassVar[set[str]]' = {'this'}
class MatchRecognizeMeasure(sqlglot.expressions.core.Expression):
819class MatchRecognizeMeasure(Expression):
820    arg_types = {
821        "this": True,
822        "window_frame": False,
823    }
arg_types = {'this': True, 'window_frame': False}
key: ClassVar[str] = 'matchrecognizemeasure'
required_args: 't.ClassVar[set[str]]' = {'this'}
class MatchRecognize(sqlglot.expressions.core.Expression):
826class MatchRecognize(Expression):
827    arg_types = {
828        "partition_by": False,
829        "order": False,
830        "measures": False,
831        "rows": False,
832        "after": False,
833        "pattern": False,
834        "define": False,
835        "alias": False,
836    }
arg_types = {'partition_by': False, 'order': False, 'measures': False, 'rows': False, 'after': False, 'pattern': False, 'define': False, 'alias': False}
key: ClassVar[str] = 'matchrecognize'
required_args: 't.ClassVar[set[str]]' = set()
class Final(sqlglot.expressions.core.Expression):
839class Final(Expression):
840    pass
key: ClassVar[str] = 'final'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Offset(sqlglot.expressions.core.Expression):
843class Offset(Expression):
844    arg_types = {"this": False, "expression": True, "expressions": False}
arg_types = {'this': False, 'expression': True, 'expressions': False}
key: ClassVar[str] = 'offset'
required_args: 't.ClassVar[set[str]]' = {'expression'}
class Order(sqlglot.expressions.core.Expression):
847class Order(Expression):
848    arg_types = {"this": False, "expressions": True, "siblings": False}
arg_types = {'this': False, 'expressions': True, 'siblings': False}
key: ClassVar[str] = 'order'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class WithFill(sqlglot.expressions.core.Expression):
851class WithFill(Expression):
852    arg_types = {
853        "from_": False,
854        "to": False,
855        "step": False,
856        "interpolate": False,
857    }
arg_types = {'from_': False, 'to': False, 'step': False, 'interpolate': False}
key: ClassVar[str] = 'withfill'
required_args: 't.ClassVar[set[str]]' = set()
class SkipJSONColumn(sqlglot.expressions.core.Expression):
860class SkipJSONColumn(Expression):
861    arg_types = {"regexp": False, "expression": True}
arg_types = {'regexp': False, 'expression': True}
key: ClassVar[str] = 'skipjsoncolumn'
required_args: 't.ClassVar[set[str]]' = {'expression'}
class Cluster(sqlglot.expressions.core.Expression):
864class Cluster(Expression):
865    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'cluster'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Distribute(Order):
868class Distribute(Order):
869    pass
key: ClassVar[str] = 'distribute'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Sort(Order):
872class Sort(Order):
873    pass
key: ClassVar[str] = 'sort'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Qualify(sqlglot.expressions.core.Expression):
876class Qualify(Expression):
877    pass
key: ClassVar[str] = 'qualify'
required_args: 't.ClassVar[set[str]]' = {'this'}
class InputOutputFormat(sqlglot.expressions.core.Expression):
880class InputOutputFormat(Expression):
881    arg_types = {"input_format": False, "output_format": False}
arg_types = {'input_format': False, 'output_format': False}
key: ClassVar[str] = 'inputoutputformat'
required_args: 't.ClassVar[set[str]]' = set()
class Return(sqlglot.expressions.core.Expression):
884class Return(Expression):
885    pass
key: ClassVar[str] = 'return'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Tuple(sqlglot.expressions.core.Expression):
888class Tuple(Expression):
889    arg_types = {"expressions": False}
890
891    def isin(
892        self,
893        *expressions: t.Any,
894        query: ExpOrStr | None = None,
895        unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None,
896        copy: bool = True,
897        **opts: Unpack[ParserArgs],
898    ) -> In:
899        return In(
900            this=maybe_copy(self, copy),
901            expressions=[convert(e, copy=copy) for e in expressions],
902            query=maybe_parse(query, copy=copy, **opts) if query else None,
903            unnest=(
904                Unnest(
905                    expressions=[
906                        maybe_parse(e, copy=copy, **opts)
907                        for e in t.cast(list[ExpOrStr], ensure_list(unnest))
908                    ]
909                )
910                if unnest
911                else None
912            ),
913        )
arg_types = {'expressions': False}
def isin( self, *expressions: Any, query: Union[int, str, sqlglot.expressions.core.Expr, NoneType] = None, unnest: Union[int, str, sqlglot.expressions.core.Expr, NoneType, list[Union[int, str, sqlglot.expressions.core.Expr]], tuple[Union[int, str, sqlglot.expressions.core.Expr], ...]] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserArgs]) -> sqlglot.expressions.core.In:
891    def isin(
892        self,
893        *expressions: t.Any,
894        query: ExpOrStr | None = None,
895        unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None,
896        copy: bool = True,
897        **opts: Unpack[ParserArgs],
898    ) -> In:
899        return In(
900            this=maybe_copy(self, copy),
901            expressions=[convert(e, copy=copy) for e in expressions],
902            query=maybe_parse(query, copy=copy, **opts) if query else None,
903            unnest=(
904                Unnest(
905                    expressions=[
906                        maybe_parse(e, copy=copy, **opts)
907                        for e in t.cast(list[ExpOrStr], ensure_list(unnest))
908                    ]
909                )
910                if unnest
911                else None
912            ),
913        )
key: ClassVar[str] = 'tuple'
required_args: 't.ClassVar[set[str]]' = set()
class QueryOption(sqlglot.expressions.core.Expression):
916class QueryOption(Expression):
917    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key: ClassVar[str] = 'queryoption'
required_args: 't.ClassVar[set[str]]' = {'this'}
class ForClause(sqlglot.expressions.core.Expression):
921class ForClause(Expression):
922    arg_types = {"kind": True, "expressions": False}
arg_types = {'kind': True, 'expressions': False}
key: ClassVar[str] = 'forclause'
required_args: 't.ClassVar[set[str]]' = {'kind'}
class WithTableHint(sqlglot.expressions.core.Expression):
925class WithTableHint(Expression):
926    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'withtablehint'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class IndexTableHint(sqlglot.expressions.core.Expression):
929class IndexTableHint(Expression):
930    arg_types = {"this": True, "expressions": False, "target": False}
arg_types = {'this': True, 'expressions': False, 'target': False}
key: ClassVar[str] = 'indextablehint'
required_args: 't.ClassVar[set[str]]' = {'this'}
class HistoricalData(sqlglot.expressions.core.Expression):
933class HistoricalData(Expression):
934    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key: ClassVar[str] = 'historicaldata'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this', 'kind'}
class Put(sqlglot.expressions.core.Expression):
937class Put(Expression):
938    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key: ClassVar[str] = 'put'
required_args: 't.ClassVar[set[str]]' = {'target', 'this'}
class Get(sqlglot.expressions.core.Expression):
941class Get(Expression):
942    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key: ClassVar[str] = 'get'
required_args: 't.ClassVar[set[str]]' = {'target', 'this'}
class Table(sqlglot.expressions.core.Expression, Selectable):
 945class Table(Expression, Selectable):
 946    arg_types = {
 947        "this": False,
 948        "alias": False,
 949        "db": False,
 950        "catalog": False,
 951        "laterals": False,
 952        "joins": False,
 953        "pivots": False,
 954        "hints": False,
 955        "system_time": False,
 956        "version": False,
 957        "format": False,
 958        "pattern": False,
 959        "ordinality": False,
 960        "when": False,
 961        "only": False,
 962        "partition": False,
 963        "changes": False,
 964        "rows_from": False,
 965        "sample": False,
 966        "indexed": False,
 967    }
 968
 969    @property
 970    def name(self) -> str:
 971        if not self.this or isinstance(self.this, Func):
 972            return ""
 973        return self.this.name
 974
 975    @property
 976    def db(self) -> str:
 977        return self.text("db")
 978
 979    @property
 980    def catalog(self) -> str:
 981        return self.text("catalog")
 982
 983    @property
 984    def selects(self) -> list[Expr]:
 985        return []
 986
 987    @property
 988    def named_selects(self) -> list[str]:
 989        return []
 990
 991    @property
 992    def parts(self) -> list[Expr]:
 993        """Return the parts of a table in order catalog, db, table."""
 994        parts: list[Expr] = []
 995
 996        for arg in ("catalog", "db", "this"):
 997            part = self.args.get(arg)
 998
 999            if isinstance(part, Dot):
1000                parts.extend(part.flatten())
1001            elif isinstance(part, Expr):
1002                parts.append(part)
1003
1004        return parts
1005
1006    def to_column(self, copy: bool = True) -> Expr:
1007        parts = self.parts
1008        last_part = parts[-1]
1009
1010        if isinstance(last_part, Identifier):
1011            col: Expr = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
1012        else:
1013            # This branch will be reached if a function or array is wrapped in a `Table`
1014            col = last_part
1015
1016        alias = self.args.get("alias")
1017        if alias:
1018            col = alias_(col, alias.this, copy=copy)
1019
1020        return col
arg_types = {'this': False, 'alias': False, 'db': False, 'catalog': False, 'laterals': False, 'joins': False, 'pivots': False, 'hints': False, 'system_time': False, 'version': False, 'format': False, 'pattern': False, 'ordinality': False, 'when': False, 'only': False, 'partition': False, 'changes': False, 'rows_from': False, 'sample': False, 'indexed': False}
name: str
969    @property
970    def name(self) -> str:
971        if not self.this or isinstance(self.this, Func):
972            return ""
973        return self.this.name
db: str
975    @property
976    def db(self) -> str:
977        return self.text("db")
catalog: str
979    @property
980    def catalog(self) -> str:
981        return self.text("catalog")
selects: list[sqlglot.expressions.core.Expr]
983    @property
984    def selects(self) -> list[Expr]:
985        return []
named_selects: list[str]
987    @property
988    def named_selects(self) -> list[str]:
989        return []
parts: list[sqlglot.expressions.core.Expr]
 991    @property
 992    def parts(self) -> list[Expr]:
 993        """Return the parts of a table in order catalog, db, table."""
 994        parts: list[Expr] = []
 995
 996        for arg in ("catalog", "db", "this"):
 997            part = self.args.get(arg)
 998
 999            if isinstance(part, Dot):
1000                parts.extend(part.flatten())
1001            elif isinstance(part, Expr):
1002                parts.append(part)
1003
1004        return parts

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

def to_column(self, copy: bool = True) -> sqlglot.expressions.core.Expr:
1006    def to_column(self, copy: bool = True) -> Expr:
1007        parts = self.parts
1008        last_part = parts[-1]
1009
1010        if isinstance(last_part, Identifier):
1011            col: Expr = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
1012        else:
1013            # This branch will be reached if a function or array is wrapped in a `Table`
1014            col = last_part
1015
1016        alias = self.args.get("alias")
1017        if alias:
1018            col = alias_(col, alias.this, copy=copy)
1019
1020        return col
key: ClassVar[str] = 'table'
required_args: 't.ClassVar[set[str]]' = set()
class SetOperation(sqlglot.expressions.core.Expression, Query):
1023class SetOperation(Expression, Query):
1024    arg_types = {
1025        "with_": False,
1026        "this": True,
1027        "expression": True,
1028        "distinct": False,
1029        "by_name": False,
1030        "side": False,
1031        "kind": False,
1032        "on": False,
1033        **QUERY_MODIFIERS,
1034    }
1035
1036    def select(
1037        self: S,
1038        *expressions: ExpOrStr | None,
1039        append: bool = True,
1040        dialect: DialectType = None,
1041        copy: bool = True,
1042        **opts: Unpack[ParserNoDialectArgs],
1043    ) -> S:
1044        this = maybe_copy(self, copy)
1045        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1046        this.expression.unnest().select(
1047            *expressions, append=append, dialect=dialect, copy=False, **opts
1048        )
1049        return this
1050
1051    @property
1052    def named_selects(self) -> list[str]:
1053        expr: Expr = self
1054        while isinstance(expr, SetOperation):
1055            if expr.args.get("by_name"):
1056                left = t.cast(Selectable, expr.this.unnest()).named_selects
1057                right = t.cast(Selectable, expr.expression.unnest()).named_selects
1058                return list(dict.fromkeys(left + right))
1059
1060            expr = expr.this.unnest()
1061        return _named_selects(expr)
1062
1063    @property
1064    def is_star(self) -> bool:
1065        return self.this.is_star or self.expression.is_star
1066
1067    @property
1068    def selects(self) -> list[Expr]:
1069        expr: Expr = self
1070        while isinstance(expr, SetOperation):
1071            expr = expr.this.unnest()
1072        return getattr(expr, "selects", [])
1073
1074    @property
1075    def left(self) -> Query:
1076        return self.this
1077
1078    @property
1079    def right(self) -> Query:
1080        return self.expression
1081
1082    @property
1083    def kind(self) -> str:
1084        return self.text("kind").upper()
1085
1086    @property
1087    def side(self) -> str:
1088        return self.text("side").upper()
arg_types = {'with_': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'side': False, 'kind': False, 'on': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False, 'for_': False}
def select( self: ~S, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> ~S:
1036    def select(
1037        self: S,
1038        *expressions: ExpOrStr | None,
1039        append: bool = True,
1040        dialect: DialectType = None,
1041        copy: bool = True,
1042        **opts: Unpack[ParserNoDialectArgs],
1043    ) -> S:
1044        this = maybe_copy(self, copy)
1045        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1046        this.expression.unnest().select(
1047            *expressions, append=append, dialect=dialect, copy=False, **opts
1048        )
1049        return this
named_selects: list[str]
1051    @property
1052    def named_selects(self) -> list[str]:
1053        expr: Expr = self
1054        while isinstance(expr, SetOperation):
1055            if expr.args.get("by_name"):
1056                left = t.cast(Selectable, expr.this.unnest()).named_selects
1057                right = t.cast(Selectable, expr.expression.unnest()).named_selects
1058                return list(dict.fromkeys(left + right))
1059
1060            expr = expr.this.unnest()
1061        return _named_selects(expr)
is_star: bool
1063    @property
1064    def is_star(self) -> bool:
1065        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

selects: list[sqlglot.expressions.core.Expr]
1067    @property
1068    def selects(self) -> list[Expr]:
1069        expr: Expr = self
1070        while isinstance(expr, SetOperation):
1071            expr = expr.this.unnest()
1072        return getattr(expr, "selects", [])
left: Query
1074    @property
1075    def left(self) -> Query:
1076        return self.this
right: Query
1078    @property
1079    def right(self) -> Query:
1080        return self.expression
kind: str
1082    @property
1083    def kind(self) -> str:
1084        return self.text("kind").upper()
side: str
1086    @property
1087    def side(self) -> str:
1088        return self.text("side").upper()
key: ClassVar[str] = 'setoperation'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this'}
class Union(SetOperation):
1091class Union(SetOperation):
1092    pass
key: ClassVar[str] = 'union'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this'}
class Except(SetOperation):
1095class Except(SetOperation):
1096    pass
key: ClassVar[str] = 'except'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this'}
class Intersect(SetOperation):
1099class Intersect(SetOperation):
1100    pass
key: ClassVar[str] = 'intersect'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this'}
class Values(sqlglot.expressions.core.Expression, UDTF):
1103class Values(Expression, UDTF):
1104    arg_types = {
1105        "expressions": True,
1106        "alias": False,
1107        "order": False,
1108        "limit": False,
1109        "offset": False,
1110    }
arg_types = {'expressions': True, 'alias': False, 'order': False, 'limit': False, 'offset': False}
key: ClassVar[str] = 'values'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Version(sqlglot.expressions.core.Expression):
1113class Version(Expression):
1114    """
1115    Time travel, iceberg, bigquery etc
1116    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
1117    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
1118    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
1119    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
1120    this is either TIMESTAMP or VERSION
1121    kind is ("AS OF", "BETWEEN")
1122    """
1123
1124    arg_types = {"this": True, "kind": True, "expression": False}
arg_types = {'this': True, 'kind': True, 'expression': False}
key: ClassVar[str] = 'version'
required_args: 't.ClassVar[set[str]]' = {'this', 'kind'}
class Schema(sqlglot.expressions.core.Expression):
1127class Schema(Expression):
1128    arg_types = {"this": False, "expressions": False}
arg_types = {'this': False, 'expressions': False}
key: ClassVar[str] = 'schema'
required_args: 't.ClassVar[set[str]]' = set()
class Lock(sqlglot.expressions.core.Expression):
1131class Lock(Expression):
1132    arg_types = {"update": True, "expressions": False, "wait": False, "key": False}
arg_types = {'update': True, 'expressions': False, 'wait': False, 'key': False}
key: ClassVar[str] = 'lock'
required_args: 't.ClassVar[set[str]]' = {'update'}
class Select(sqlglot.expressions.core.Expression, Query):
1135class Select(Expression, Query):
1136    arg_types = {
1137        "with_": False,
1138        "kind": False,
1139        "expressions": False,
1140        "hint": False,
1141        "distinct": False,
1142        "into": False,
1143        "from_": False,
1144        "operation_modifiers": False,
1145        "exclude": False,
1146        **QUERY_MODIFIERS,
1147    }
1148
1149    def from_(
1150        self,
1151        expression: ExpOrStr,
1152        dialect: DialectType = None,
1153        copy: bool = True,
1154        **opts: Unpack[ParserNoDialectArgs],
1155    ) -> Select:
1156        """
1157        Set the FROM expression.
1158
1159        Example:
1160            >>> Select().from_("tbl").select("x").sql()
1161            'SELECT x FROM tbl'
1162
1163        Args:
1164            expression : the SQL code strings to parse.
1165                If a `From` instance is passed, this is used as-is.
1166                If another `Expr` instance is passed, it will be wrapped in a `From`.
1167            dialect: the dialect used to parse the input expression.
1168            copy: if `False`, modify this expression instance in-place.
1169            opts: other options to use to parse the input expressions.
1170
1171        Returns:
1172            The modified Select expression.
1173        """
1174        return _apply_builder(
1175            expression=expression,
1176            instance=self,
1177            arg="from_",
1178            into=From,
1179            prefix="FROM",
1180            dialect=dialect,
1181            copy=copy,
1182            **opts,
1183        )
1184
1185    def group_by(
1186        self,
1187        *expressions: ExpOrStr | None,
1188        append: bool = True,
1189        dialect: DialectType = None,
1190        copy: bool = True,
1191        **opts: Unpack[ParserNoDialectArgs],
1192    ) -> Select:
1193        """
1194        Set the GROUP BY expression.
1195
1196        Example:
1197            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
1198            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
1199
1200        Args:
1201            *expressions: the SQL code strings to parse.
1202                If a `Group` instance is passed, this is used as-is.
1203                If another `Expr` instance is passed, it will be wrapped in a `Group`.
1204                If nothing is passed in then a group by is not applied to the expression
1205            append: if `True`, add to any existing expressions.
1206                Otherwise, this flattens all the `Group` expression into a single expression.
1207            dialect: the dialect used to parse the input expression.
1208            copy: if `False`, modify this expression instance in-place.
1209            opts: other options to use to parse the input expressions.
1210
1211        Returns:
1212            The modified Select expression.
1213        """
1214        if not expressions:
1215            return self if not copy else self.copy()
1216
1217        return _apply_child_list_builder(
1218            *expressions,
1219            instance=self,
1220            arg="group",
1221            append=append,
1222            copy=copy,
1223            prefix="GROUP BY",
1224            into=Group,
1225            dialect=dialect,
1226            **opts,
1227        )
1228
1229    def sort_by(
1230        self,
1231        *expressions: ExpOrStr | None,
1232        append: bool = True,
1233        dialect: DialectType = None,
1234        copy: bool = True,
1235        **opts: Unpack[ParserNoDialectArgs],
1236    ) -> Select:
1237        """
1238        Set the SORT BY expression.
1239
1240        Example:
1241            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
1242            'SELECT x FROM tbl SORT BY x DESC'
1243
1244        Args:
1245            *expressions: the SQL code strings to parse.
1246                If a `Group` instance is passed, this is used as-is.
1247                If another `Expr` instance is passed, it will be wrapped in a `SORT`.
1248            append: if `True`, add to any existing expressions.
1249                Otherwise, this flattens all the `Order` expression into a single expression.
1250            dialect: the dialect used to parse the input expression.
1251            copy: if `False`, modify this expression instance in-place.
1252            opts: other options to use to parse the input expressions.
1253
1254        Returns:
1255            The modified Select expression.
1256        """
1257        return _apply_child_list_builder(
1258            *expressions,
1259            instance=self,
1260            arg="sort",
1261            append=append,
1262            copy=copy,
1263            prefix="SORT BY",
1264            into=Sort,
1265            dialect=dialect,
1266            **opts,
1267        )
1268
1269    def cluster_by(
1270        self,
1271        *expressions: ExpOrStr | None,
1272        append: bool = True,
1273        dialect: DialectType = None,
1274        copy: bool = True,
1275        **opts: Unpack[ParserNoDialectArgs],
1276    ) -> Select:
1277        """
1278        Set the CLUSTER BY expression.
1279
1280        Example:
1281            >>> Select().from_("tbl").select("x").cluster_by("x").sql(dialect="hive")
1282            'SELECT x FROM tbl CLUSTER BY x'
1283
1284        Args:
1285            *expressions: the SQL code strings to parse.
1286                If a `Group` instance is passed, this is used as-is.
1287                If another `Expr` instance is passed, it will be wrapped in a `Cluster`.
1288            append: if `True`, add to any existing expressions.
1289                Otherwise, this flattens all the `Order` expression into a single expression.
1290            dialect: the dialect used to parse the input expression.
1291            copy: if `False`, modify this expression instance in-place.
1292            opts: other options to use to parse the input expressions.
1293
1294        Returns:
1295            The modified Select expression.
1296        """
1297        return _apply_child_list_builder(
1298            *expressions,
1299            instance=self,
1300            arg="cluster",
1301            append=append,
1302            copy=copy,
1303            prefix="CLUSTER BY",
1304            into=Cluster,
1305            dialect=dialect,
1306            **opts,
1307        )
1308
1309    def select(
1310        self,
1311        *expressions: ExpOrStr | None,
1312        append: bool = True,
1313        dialect: DialectType = None,
1314        copy: bool = True,
1315        **opts: Unpack[ParserNoDialectArgs],
1316    ) -> Select:
1317        return _apply_list_builder(
1318            *expressions,
1319            instance=self,
1320            arg="expressions",
1321            append=append,
1322            dialect=dialect,
1323            into=Expr,
1324            copy=copy,
1325            **opts,
1326        )
1327
1328    def lateral(
1329        self,
1330        *expressions: ExpOrStr | None,
1331        append: bool = True,
1332        dialect: DialectType = None,
1333        copy: bool = True,
1334        **opts: Unpack[ParserNoDialectArgs],
1335    ) -> Select:
1336        """
1337        Append to or set the LATERAL expressions.
1338
1339        Example:
1340            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
1341            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
1342
1343        Args:
1344            *expressions: the SQL code strings to parse.
1345                If an `Expr` instance is passed, it will be used as-is.
1346            append: if `True`, add to any existing expressions.
1347                Otherwise, this resets the expressions.
1348            dialect: the dialect used to parse the input expressions.
1349            copy: if `False`, modify this expression instance in-place.
1350            opts: other options to use to parse the input expressions.
1351
1352        Returns:
1353            The modified Select expression.
1354        """
1355        return _apply_list_builder(
1356            *expressions,
1357            instance=self,
1358            arg="laterals",
1359            append=append,
1360            into=Lateral,
1361            prefix="LATERAL VIEW",
1362            dialect=dialect,
1363            copy=copy,
1364            **opts,
1365        )
1366
1367    def join(
1368        self,
1369        expression: ExpOrStr,
1370        on: ExpOrStr | list[ExpOrStr] | tuple[ExpOrStr, ...] | None = None,
1371        using: ExpOrStr | list[ExpOrStr] | tuple[ExpOrStr, ...] | None = None,
1372        append: bool = True,
1373        join_type: str | None = None,
1374        join_alias: Identifier | str | None = None,
1375        dialect: DialectType = None,
1376        copy: bool = True,
1377        **opts: Unpack[ParserNoDialectArgs],
1378    ) -> Select:
1379        """
1380        Append to or set the JOIN expressions.
1381
1382        Example:
1383            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
1384            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
1385
1386            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
1387            'SELECT 1 FROM a JOIN b USING (x, y, z)'
1388
1389            Use `join_type` to change the type of join:
1390
1391            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
1392            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
1393
1394        Args:
1395            expression: the SQL code string to parse.
1396                If an `Expr` instance is passed, it will be used as-is.
1397            on: optionally specify the join "on" criteria as a SQL string.
1398                If an `Expr` instance is passed, it will be used as-is.
1399            using: optionally specify the join "using" criteria as a SQL string.
1400                If an `Expr` instance is passed, it will be used as-is.
1401            append: if `True`, add to any existing expressions.
1402                Otherwise, this resets the expressions.
1403            join_type: if set, alter the parsed join type.
1404            join_alias: an optional alias for the joined source.
1405            dialect: the dialect used to parse the input expressions.
1406            copy: if `False`, modify this expression instance in-place.
1407            opts: other options to use to parse the input expressions.
1408
1409        Returns:
1410            Select: the modified expression.
1411        """
1412        parse_args: ParserArgs = {"dialect": dialect, **opts}
1413        try:
1414            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
1415        except ParseError:
1416            expression = maybe_parse(expression, into=(Join, Expr), **parse_args)
1417
1418        join = expression if isinstance(expression, Join) else Join(this=expression)
1419
1420        if isinstance(join.this, Select):
1421            join.this.replace(join.this.subquery())
1422
1423        if join_type:
1424            new_join: Join = maybe_parse(f"FROM _ {join_type} JOIN _", **parse_args).find(Join)
1425            method = new_join.method
1426            side = new_join.side
1427            kind = new_join.kind
1428
1429            if method:
1430                join.set("method", method)
1431            if side:
1432                join.set("side", side)
1433            if kind:
1434                join.set("kind", kind)
1435
1436        if on:
1437            on_exprs: list[ExpOrStr] = ensure_list(on)
1438            on = and_(*on_exprs, dialect=dialect, copy=copy, **opts)
1439            join.set("on", on)
1440
1441        if using:
1442            using_exprs: list[ExpOrStr] = ensure_list(using)
1443            join = _apply_list_builder(
1444                *using_exprs,
1445                instance=join,
1446                arg="using",
1447                append=append,
1448                copy=copy,
1449                into=Identifier,
1450                **opts,
1451            )
1452
1453        if join_alias:
1454            join.set("this", alias_(join.this, join_alias, table=True))
1455
1456        return _apply_list_builder(
1457            join,
1458            instance=self,
1459            arg="joins",
1460            append=append,
1461            copy=copy,
1462            **opts,
1463        )
1464
1465    def having(
1466        self,
1467        *expressions: ExpOrStr | None,
1468        append: bool = True,
1469        dialect: DialectType = None,
1470        copy: bool = True,
1471        **opts: Unpack[ParserNoDialectArgs],
1472    ) -> Select:
1473        """
1474        Append to or set the HAVING expressions.
1475
1476        Example:
1477            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
1478            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
1479
1480        Args:
1481            *expressions: the SQL code strings to parse.
1482                If an `Expr` instance is passed, it will be used as-is.
1483                Multiple expressions are combined with an AND operator.
1484            append: if `True`, AND the new expressions to any existing expression.
1485                Otherwise, this resets the expression.
1486            dialect: the dialect used to parse the input expressions.
1487            copy: if `False`, modify this expression instance in-place.
1488            opts: other options to use to parse the input expressions.
1489
1490        Returns:
1491            The modified Select expression.
1492        """
1493        return _apply_conjunction_builder(
1494            *expressions,
1495            instance=self,
1496            arg="having",
1497            append=append,
1498            into=Having,
1499            dialect=dialect,
1500            copy=copy,
1501            **opts,
1502        )
1503
1504    def window(
1505        self,
1506        *expressions: ExpOrStr | None,
1507        append: bool = True,
1508        dialect: DialectType = None,
1509        copy: bool = True,
1510        **opts: Unpack[ParserNoDialectArgs],
1511    ) -> Select:
1512        return _apply_list_builder(
1513            *expressions,
1514            instance=self,
1515            arg="windows",
1516            append=append,
1517            into=Window,
1518            dialect=dialect,
1519            copy=copy,
1520            **opts,
1521        )
1522
1523    def qualify(
1524        self,
1525        *expressions: ExpOrStr | None,
1526        append: bool = True,
1527        dialect: DialectType = None,
1528        copy: bool = True,
1529        **opts: Unpack[ParserNoDialectArgs],
1530    ) -> Select:
1531        return _apply_conjunction_builder(
1532            *expressions,
1533            instance=self,
1534            arg="qualify",
1535            append=append,
1536            into=Qualify,
1537            dialect=dialect,
1538            copy=copy,
1539            **opts,
1540        )
1541
1542    def distinct(self, *ons: ExpOrStr | None, distinct: bool = True, copy: bool = True) -> Select:
1543        """
1544        Set the OFFSET expression.
1545
1546        Example:
1547            >>> Select().from_("tbl").select("x").distinct().sql()
1548            'SELECT DISTINCT x FROM tbl'
1549
1550        Args:
1551            ons: the expressions to distinct on
1552            distinct: whether the Select should be distinct
1553            copy: if `False`, modify this expression instance in-place.
1554
1555        Returns:
1556            Select: the modified expression.
1557        """
1558        instance = maybe_copy(self, copy)
1559        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
1560        instance.set("distinct", Distinct(on=on) if distinct else None)
1561        return instance
1562
1563    def ctas(
1564        self,
1565        table: ExpOrStr,
1566        properties: dict | None = None,
1567        dialect: DialectType = None,
1568        copy: bool = True,
1569        **opts: Unpack[ParserNoDialectArgs],
1570    ) -> Create:
1571        """
1572        Convert this expression to a CREATE TABLE AS statement.
1573
1574        Example:
1575            >>> Select().select("*").from_("tbl").ctas("x").sql()
1576            'CREATE TABLE x AS SELECT * FROM tbl'
1577
1578        Args:
1579            table: the SQL code string to parse as the table name.
1580                If another `Expr` instance is passed, it will be used as-is.
1581            properties: an optional mapping of table properties
1582            dialect: the dialect used to parse the input table.
1583            copy: if `False`, modify this expression instance in-place.
1584            opts: other options to use to parse the input table.
1585
1586        Returns:
1587            The new Create expression.
1588        """
1589        instance = maybe_copy(self, copy)
1590        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
1591
1592        properties_expression = None
1593        if properties:
1594            from sqlglot.expressions.properties import Properties as _Properties
1595
1596            properties_expression = _Properties.from_dict(properties)
1597
1598        from sqlglot.expressions.ddl import Create as _Create
1599
1600        return _Create(
1601            this=table_expression,
1602            kind="TABLE",
1603            expression=instance,
1604            properties=properties_expression,
1605        )
1606
1607    def lock(self, update: bool = True, copy: bool = True) -> Select:
1608        """
1609        Set the locking read mode for this expression.
1610
1611        Examples:
1612            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
1613            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
1614
1615            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
1616            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
1617
1618        Args:
1619            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
1620            copy: if `False`, modify this expression instance in-place.
1621
1622        Returns:
1623            The modified expression.
1624        """
1625        inst = maybe_copy(self, copy)
1626        inst.set("locks", [Lock(update=update)])
1627
1628        return inst
1629
1630    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
1631        """
1632        Set hints for this expression.
1633
1634        Examples:
1635            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
1636            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
1637
1638        Args:
1639            hints: The SQL code strings to parse as the hints.
1640                If an `Expr` instance is passed, it will be used as-is.
1641            dialect: The dialect used to parse the hints.
1642            copy: If `False`, modify this expression instance in-place.
1643
1644        Returns:
1645            The modified expression.
1646        """
1647        inst = maybe_copy(self, copy)
1648        inst.set(
1649            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
1650        )
1651
1652        return inst
1653
1654    @property
1655    def named_selects(self) -> list[str]:
1656        selects = []
1657
1658        for e in self.expressions:
1659            if e.alias_or_name:
1660                selects.append(e.output_name)
1661            elif isinstance(e, Aliases):
1662                selects.extend([a.name for a in e.aliases])
1663        return selects
1664
1665    @property
1666    def is_star(self) -> bool:
1667        return any(expression.is_star for expression in self.expressions)
1668
1669    @property
1670    def selects(self) -> list[Expr]:
1671        return self.expressions
arg_types = {'with_': False, 'kind': False, 'expressions': False, 'hint': False, 'distinct': False, 'into': False, 'from_': False, 'operation_modifiers': False, 'exclude': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False, 'for_': False}
def from_( self, expression: Union[int, str, sqlglot.expressions.core.Expr], dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Select:
1149    def from_(
1150        self,
1151        expression: ExpOrStr,
1152        dialect: DialectType = None,
1153        copy: bool = True,
1154        **opts: Unpack[ParserNoDialectArgs],
1155    ) -> Select:
1156        """
1157        Set the FROM expression.
1158
1159        Example:
1160            >>> Select().from_("tbl").select("x").sql()
1161            'SELECT x FROM tbl'
1162
1163        Args:
1164            expression : the SQL code strings to parse.
1165                If a `From` instance is passed, this is used as-is.
1166                If another `Expr` instance is passed, it will be wrapped in a `From`.
1167            dialect: the dialect used to parse the input expression.
1168            copy: if `False`, modify this expression instance in-place.
1169            opts: other options to use to parse the input expressions.
1170
1171        Returns:
1172            The modified Select expression.
1173        """
1174        return _apply_builder(
1175            expression=expression,
1176            instance=self,
1177            arg="from_",
1178            into=From,
1179            prefix="FROM",
1180            dialect=dialect,
1181            copy=copy,
1182            **opts,
1183        )

Set the FROM expression.

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

The modified Select expression.

def group_by( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Select:
1185    def group_by(
1186        self,
1187        *expressions: ExpOrStr | None,
1188        append: bool = True,
1189        dialect: DialectType = None,
1190        copy: bool = True,
1191        **opts: Unpack[ParserNoDialectArgs],
1192    ) -> Select:
1193        """
1194        Set the GROUP BY expression.
1195
1196        Example:
1197            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
1198            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
1199
1200        Args:
1201            *expressions: the SQL code strings to parse.
1202                If a `Group` instance is passed, this is used as-is.
1203                If another `Expr` instance is passed, it will be wrapped in a `Group`.
1204                If nothing is passed in then a group by is not applied to the expression
1205            append: if `True`, add to any existing expressions.
1206                Otherwise, this flattens all the `Group` expression into a single expression.
1207            dialect: the dialect used to parse the input expression.
1208            copy: if `False`, modify this expression instance in-place.
1209            opts: other options to use to parse the input expressions.
1210
1211        Returns:
1212            The modified Select expression.
1213        """
1214        if not expressions:
1215            return self if not copy else self.copy()
1216
1217        return _apply_child_list_builder(
1218            *expressions,
1219            instance=self,
1220            arg="group",
1221            append=append,
1222            copy=copy,
1223            prefix="GROUP BY",
1224            into=Group,
1225            dialect=dialect,
1226            **opts,
1227        )

Set the GROUP BY expression.

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

The modified Select expression.

def sort_by( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Select:
1229    def sort_by(
1230        self,
1231        *expressions: ExpOrStr | None,
1232        append: bool = True,
1233        dialect: DialectType = None,
1234        copy: bool = True,
1235        **opts: Unpack[ParserNoDialectArgs],
1236    ) -> Select:
1237        """
1238        Set the SORT BY expression.
1239
1240        Example:
1241            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
1242            'SELECT x FROM tbl SORT BY x DESC'
1243
1244        Args:
1245            *expressions: the SQL code strings to parse.
1246                If a `Group` instance is passed, this is used as-is.
1247                If another `Expr` instance is passed, it will be wrapped in a `SORT`.
1248            append: if `True`, add to any existing expressions.
1249                Otherwise, this flattens all the `Order` expression into a single expression.
1250            dialect: the dialect used to parse the input expression.
1251            copy: if `False`, modify this expression instance in-place.
1252            opts: other options to use to parse the input expressions.
1253
1254        Returns:
1255            The modified Select expression.
1256        """
1257        return _apply_child_list_builder(
1258            *expressions,
1259            instance=self,
1260            arg="sort",
1261            append=append,
1262            copy=copy,
1263            prefix="SORT BY",
1264            into=Sort,
1265            dialect=dialect,
1266            **opts,
1267        )

Set the SORT BY expression.

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

The modified Select expression.

def cluster_by( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Select:
1269    def cluster_by(
1270        self,
1271        *expressions: ExpOrStr | None,
1272        append: bool = True,
1273        dialect: DialectType = None,
1274        copy: bool = True,
1275        **opts: Unpack[ParserNoDialectArgs],
1276    ) -> Select:
1277        """
1278        Set the CLUSTER BY expression.
1279
1280        Example:
1281            >>> Select().from_("tbl").select("x").cluster_by("x").sql(dialect="hive")
1282            'SELECT x FROM tbl CLUSTER BY x'
1283
1284        Args:
1285            *expressions: the SQL code strings to parse.
1286                If a `Group` instance is passed, this is used as-is.
1287                If another `Expr` instance is passed, it will be wrapped in a `Cluster`.
1288            append: if `True`, add to any existing expressions.
1289                Otherwise, this flattens all the `Order` expression into a single expression.
1290            dialect: the dialect used to parse the input expression.
1291            copy: if `False`, modify this expression instance in-place.
1292            opts: other options to use to parse the input expressions.
1293
1294        Returns:
1295            The modified Select expression.
1296        """
1297        return _apply_child_list_builder(
1298            *expressions,
1299            instance=self,
1300            arg="cluster",
1301            append=append,
1302            copy=copy,
1303            prefix="CLUSTER BY",
1304            into=Cluster,
1305            dialect=dialect,
1306            **opts,
1307        )

Set the CLUSTER BY expression.

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

The modified Select expression.

def select( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Select:
1309    def select(
1310        self,
1311        *expressions: ExpOrStr | None,
1312        append: bool = True,
1313        dialect: DialectType = None,
1314        copy: bool = True,
1315        **opts: Unpack[ParserNoDialectArgs],
1316    ) -> Select:
1317        return _apply_list_builder(
1318            *expressions,
1319            instance=self,
1320            arg="expressions",
1321            append=append,
1322            dialect=dialect,
1323            into=Expr,
1324            copy=copy,
1325            **opts,
1326        )
def lateral( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Select:
1328    def lateral(
1329        self,
1330        *expressions: ExpOrStr | None,
1331        append: bool = True,
1332        dialect: DialectType = None,
1333        copy: bool = True,
1334        **opts: Unpack[ParserNoDialectArgs],
1335    ) -> Select:
1336        """
1337        Append to or set the LATERAL expressions.
1338
1339        Example:
1340            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
1341            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
1342
1343        Args:
1344            *expressions: the SQL code strings to parse.
1345                If an `Expr` instance is passed, it will be used as-is.
1346            append: if `True`, add to any existing expressions.
1347                Otherwise, this resets the expressions.
1348            dialect: the dialect used to parse the input expressions.
1349            copy: if `False`, modify this expression instance in-place.
1350            opts: other options to use to parse the input expressions.
1351
1352        Returns:
1353            The modified Select expression.
1354        """
1355        return _apply_list_builder(
1356            *expressions,
1357            instance=self,
1358            arg="laterals",
1359            append=append,
1360            into=Lateral,
1361            prefix="LATERAL VIEW",
1362            dialect=dialect,
1363            copy=copy,
1364            **opts,
1365        )

Append to or set the LATERAL expressions.

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

The modified Select expression.

def join( self, expression: Union[int, str, sqlglot.expressions.core.Expr], on: Union[int, str, sqlglot.expressions.core.Expr, list[Union[int, str, sqlglot.expressions.core.Expr]], tuple[Union[int, str, sqlglot.expressions.core.Expr], ...], NoneType] = None, using: Union[int, str, sqlglot.expressions.core.Expr, list[Union[int, str, sqlglot.expressions.core.Expr]], tuple[Union[int, str, sqlglot.expressions.core.Expr], ...], NoneType] = None, append: bool = True, join_type: str | None = None, join_alias: sqlglot.expressions.core.Identifier | str | None = None, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Select:
1367    def join(
1368        self,
1369        expression: ExpOrStr,
1370        on: ExpOrStr | list[ExpOrStr] | tuple[ExpOrStr, ...] | None = None,
1371        using: ExpOrStr | list[ExpOrStr] | tuple[ExpOrStr, ...] | None = None,
1372        append: bool = True,
1373        join_type: str | None = None,
1374        join_alias: Identifier | str | None = None,
1375        dialect: DialectType = None,
1376        copy: bool = True,
1377        **opts: Unpack[ParserNoDialectArgs],
1378    ) -> Select:
1379        """
1380        Append to or set the JOIN expressions.
1381
1382        Example:
1383            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
1384            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
1385
1386            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
1387            'SELECT 1 FROM a JOIN b USING (x, y, z)'
1388
1389            Use `join_type` to change the type of join:
1390
1391            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
1392            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
1393
1394        Args:
1395            expression: the SQL code string to parse.
1396                If an `Expr` instance is passed, it will be used as-is.
1397            on: optionally specify the join "on" criteria as a SQL string.
1398                If an `Expr` instance is passed, it will be used as-is.
1399            using: optionally specify the join "using" criteria as a SQL string.
1400                If an `Expr` instance is passed, it will be used as-is.
1401            append: if `True`, add to any existing expressions.
1402                Otherwise, this resets the expressions.
1403            join_type: if set, alter the parsed join type.
1404            join_alias: an optional alias for the joined source.
1405            dialect: the dialect used to parse the input expressions.
1406            copy: if `False`, modify this expression instance in-place.
1407            opts: other options to use to parse the input expressions.
1408
1409        Returns:
1410            Select: the modified expression.
1411        """
1412        parse_args: ParserArgs = {"dialect": dialect, **opts}
1413        try:
1414            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
1415        except ParseError:
1416            expression = maybe_parse(expression, into=(Join, Expr), **parse_args)
1417
1418        join = expression if isinstance(expression, Join) else Join(this=expression)
1419
1420        if isinstance(join.this, Select):
1421            join.this.replace(join.this.subquery())
1422
1423        if join_type:
1424            new_join: Join = maybe_parse(f"FROM _ {join_type} JOIN _", **parse_args).find(Join)
1425            method = new_join.method
1426            side = new_join.side
1427            kind = new_join.kind
1428
1429            if method:
1430                join.set("method", method)
1431            if side:
1432                join.set("side", side)
1433            if kind:
1434                join.set("kind", kind)
1435
1436        if on:
1437            on_exprs: list[ExpOrStr] = ensure_list(on)
1438            on = and_(*on_exprs, dialect=dialect, copy=copy, **opts)
1439            join.set("on", on)
1440
1441        if using:
1442            using_exprs: list[ExpOrStr] = ensure_list(using)
1443            join = _apply_list_builder(
1444                *using_exprs,
1445                instance=join,
1446                arg="using",
1447                append=append,
1448                copy=copy,
1449                into=Identifier,
1450                **opts,
1451            )
1452
1453        if join_alias:
1454            join.set("this", alias_(join.this, join_alias, table=True))
1455
1456        return _apply_list_builder(
1457            join,
1458            instance=self,
1459            arg="joins",
1460            append=append,
1461            copy=copy,
1462            **opts,
1463        )

Append to or set the JOIN expressions.

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

Use join_type to change the type of join:

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

Select: the modified expression.

def having( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Select:
1465    def having(
1466        self,
1467        *expressions: ExpOrStr | None,
1468        append: bool = True,
1469        dialect: DialectType = None,
1470        copy: bool = True,
1471        **opts: Unpack[ParserNoDialectArgs],
1472    ) -> Select:
1473        """
1474        Append to or set the HAVING expressions.
1475
1476        Example:
1477            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
1478            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
1479
1480        Args:
1481            *expressions: the SQL code strings to parse.
1482                If an `Expr` instance is passed, it will be used as-is.
1483                Multiple expressions are combined with an AND operator.
1484            append: if `True`, AND the new expressions to any existing expression.
1485                Otherwise, this resets the expression.
1486            dialect: the dialect used to parse the input expressions.
1487            copy: if `False`, modify this expression instance in-place.
1488            opts: other options to use to parse the input expressions.
1489
1490        Returns:
1491            The modified Select expression.
1492        """
1493        return _apply_conjunction_builder(
1494            *expressions,
1495            instance=self,
1496            arg="having",
1497            append=append,
1498            into=Having,
1499            dialect=dialect,
1500            copy=copy,
1501            **opts,
1502        )

Append to or set the HAVING expressions.

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

The modified Select expression.

def window( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Select:
1504    def window(
1505        self,
1506        *expressions: ExpOrStr | None,
1507        append: bool = True,
1508        dialect: DialectType = None,
1509        copy: bool = True,
1510        **opts: Unpack[ParserNoDialectArgs],
1511    ) -> Select:
1512        return _apply_list_builder(
1513            *expressions,
1514            instance=self,
1515            arg="windows",
1516            append=append,
1517            into=Window,
1518            dialect=dialect,
1519            copy=copy,
1520            **opts,
1521        )
def qualify( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Select:
1523    def qualify(
1524        self,
1525        *expressions: ExpOrStr | None,
1526        append: bool = True,
1527        dialect: DialectType = None,
1528        copy: bool = True,
1529        **opts: Unpack[ParserNoDialectArgs],
1530    ) -> Select:
1531        return _apply_conjunction_builder(
1532            *expressions,
1533            instance=self,
1534            arg="qualify",
1535            append=append,
1536            into=Qualify,
1537            dialect=dialect,
1538            copy=copy,
1539            **opts,
1540        )
def distinct( self, *ons: Union[int, str, sqlglot.expressions.core.Expr, NoneType], distinct: bool = True, copy: bool = True) -> Select:
1542    def distinct(self, *ons: ExpOrStr | None, distinct: bool = True, copy: bool = True) -> Select:
1543        """
1544        Set the OFFSET expression.
1545
1546        Example:
1547            >>> Select().from_("tbl").select("x").distinct().sql()
1548            'SELECT DISTINCT x FROM tbl'
1549
1550        Args:
1551            ons: the expressions to distinct on
1552            distinct: whether the Select should be distinct
1553            copy: if `False`, modify this expression instance in-place.
1554
1555        Returns:
1556            Select: the modified expression.
1557        """
1558        instance = maybe_copy(self, copy)
1559        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
1560        instance.set("distinct", Distinct(on=on) if distinct else None)
1561        return instance

Set the OFFSET expression.

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

Select: the modified expression.

def ctas( self, table: Union[int, str, sqlglot.expressions.core.Expr], properties: dict | None = None, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> sqlglot.expressions.ddl.Create:
1563    def ctas(
1564        self,
1565        table: ExpOrStr,
1566        properties: dict | None = None,
1567        dialect: DialectType = None,
1568        copy: bool = True,
1569        **opts: Unpack[ParserNoDialectArgs],
1570    ) -> Create:
1571        """
1572        Convert this expression to a CREATE TABLE AS statement.
1573
1574        Example:
1575            >>> Select().select("*").from_("tbl").ctas("x").sql()
1576            'CREATE TABLE x AS SELECT * FROM tbl'
1577
1578        Args:
1579            table: the SQL code string to parse as the table name.
1580                If another `Expr` instance is passed, it will be used as-is.
1581            properties: an optional mapping of table properties
1582            dialect: the dialect used to parse the input table.
1583            copy: if `False`, modify this expression instance in-place.
1584            opts: other options to use to parse the input table.
1585
1586        Returns:
1587            The new Create expression.
1588        """
1589        instance = maybe_copy(self, copy)
1590        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
1591
1592        properties_expression = None
1593        if properties:
1594            from sqlglot.expressions.properties import Properties as _Properties
1595
1596            properties_expression = _Properties.from_dict(properties)
1597
1598        from sqlglot.expressions.ddl import Create as _Create
1599
1600        return _Create(
1601            this=table_expression,
1602            kind="TABLE",
1603            expression=instance,
1604            properties=properties_expression,
1605        )

Convert this expression to a CREATE TABLE AS statement.

Example:
>>> Select().select("*").from_("tbl").ctas("x").sql()
'CREATE TABLE x AS SELECT * FROM tbl'
Arguments:
  • table: the SQL code string to parse as the table name. If another Expr instance is passed, it will be used as-is.
  • properties: an optional mapping of table properties
  • dialect: the dialect used to parse the input table.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input table.
Returns:

The new Create expression.

def lock( self, update: bool = True, copy: bool = True) -> Select:
1607    def lock(self, update: bool = True, copy: bool = True) -> Select:
1608        """
1609        Set the locking read mode for this expression.
1610
1611        Examples:
1612            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
1613            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
1614
1615            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
1616            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
1617
1618        Args:
1619            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
1620            copy: if `False`, modify this expression instance in-place.
1621
1622        Returns:
1623            The modified expression.
1624        """
1625        inst = maybe_copy(self, copy)
1626        inst.set("locks", [Lock(update=update)])
1627
1628        return inst

Set the locking read mode for this expression.

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

The modified expression.

def hint( self, *hints: Union[int, str, sqlglot.expressions.core.Expr], dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True) -> Select:
1630    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
1631        """
1632        Set hints for this expression.
1633
1634        Examples:
1635            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
1636            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
1637
1638        Args:
1639            hints: The SQL code strings to parse as the hints.
1640                If an `Expr` instance is passed, it will be used as-is.
1641            dialect: The dialect used to parse the hints.
1642            copy: If `False`, modify this expression instance in-place.
1643
1644        Returns:
1645            The modified expression.
1646        """
1647        inst = maybe_copy(self, copy)
1648        inst.set(
1649            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
1650        )
1651
1652        return inst

Set hints for this expression.

Examples:
>>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
'SELECT /*+ BROADCAST(y) */ x FROM tbl'
Arguments:
  • hints: The SQL code strings to parse as the hints. If an Expr instance is passed, it will be used as-is.
  • dialect: The dialect used to parse the hints.
  • copy: If False, modify this expression instance in-place.
Returns:

The modified expression.

named_selects: list[str]
1654    @property
1655    def named_selects(self) -> list[str]:
1656        selects = []
1657
1658        for e in self.expressions:
1659            if e.alias_or_name:
1660                selects.append(e.output_name)
1661            elif isinstance(e, Aliases):
1662                selects.extend([a.name for a in e.aliases])
1663        return selects
is_star: bool
1665    @property
1666    def is_star(self) -> bool:
1667        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: list[sqlglot.expressions.core.Expr]
1669    @property
1670    def selects(self) -> list[Expr]:
1671        return self.expressions
key: ClassVar[str] = 'select'
required_args: 't.ClassVar[set[str]]' = set()
class Subquery(sqlglot.expressions.core.Expression, DerivedTable, Query):
1674class Subquery(Expression, DerivedTable, Query):
1675    is_subquery: t.ClassVar[bool] = True
1676    arg_types = {
1677        "this": True,
1678        "alias": False,
1679        "with_": False,
1680        **QUERY_MODIFIERS,
1681    }
1682
1683    def unnest(self) -> Expr:
1684        """Returns the first non subquery."""
1685        expression: Expr = self
1686        while isinstance(expression, Subquery):
1687            expression = expression.this
1688        return expression
1689
1690    def unwrap(self) -> Subquery:
1691        expression = self
1692        while expression.same_parent and expression.is_wrapper:
1693            expression = t.cast(Subquery, expression.parent)
1694        return expression
1695
1696    def select(
1697        self,
1698        *expressions: ExpOrStr | None,
1699        append: bool = True,
1700        dialect: DialectType = None,
1701        copy: bool = True,
1702        **opts: Unpack[ParserNoDialectArgs],
1703    ) -> Subquery:
1704        this = maybe_copy(self, copy)
1705        inner = this.unnest()
1706        if hasattr(inner, "select"):
1707            inner.select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1708        return this
1709
1710    @property
1711    def is_wrapper(self) -> bool:
1712        """
1713        Whether this Subquery acts as a simple wrapper around another expression.
1714
1715        SELECT * FROM (((SELECT * FROM t)))
1716                      ^
1717                      This corresponds to a "wrapper" Subquery node
1718        """
1719        return all(v is None for k, v in self.args.items() if k != "this")
1720
1721    @property
1722    def is_star(self) -> bool:
1723        return self.this.is_star
1724
1725    @property
1726    def output_name(self) -> str:
1727        return self.alias
is_subquery: ClassVar[bool] = True
arg_types = {'this': True, 'alias': False, 'with_': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False, 'for_': False}
def unnest(self) -> sqlglot.expressions.core.Expr:
1683    def unnest(self) -> Expr:
1684        """Returns the first non subquery."""
1685        expression: Expr = self
1686        while isinstance(expression, Subquery):
1687            expression = expression.this
1688        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
1690    def unwrap(self) -> Subquery:
1691        expression = self
1692        while expression.same_parent and expression.is_wrapper:
1693            expression = t.cast(Subquery, expression.parent)
1694        return expression
def select( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Subquery:
1696    def select(
1697        self,
1698        *expressions: ExpOrStr | None,
1699        append: bool = True,
1700        dialect: DialectType = None,
1701        copy: bool = True,
1702        **opts: Unpack[ParserNoDialectArgs],
1703    ) -> Subquery:
1704        this = maybe_copy(self, copy)
1705        inner = this.unnest()
1706        if hasattr(inner, "select"):
1707            inner.select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1708        return this
is_wrapper: bool
1710    @property
1711    def is_wrapper(self) -> bool:
1712        """
1713        Whether this Subquery acts as a simple wrapper around another expression.
1714
1715        SELECT * FROM (((SELECT * FROM t)))
1716                      ^
1717                      This corresponds to a "wrapper" Subquery node
1718        """
1719        return all(v is None for k, v in self.args.items() if k != "this")

Whether this Subquery acts as a simple wrapper around another expression.

SELECT * FROM (((SELECT * FROM t))) ^ This corresponds to a "wrapper" Subquery node

is_star: bool
1721    @property
1722    def is_star(self) -> bool:
1723        return self.this.is_star

Checks whether an expression is a star.

output_name: str
1725    @property
1726    def output_name(self) -> str:
1727        return self.alias

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a").expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c").expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2").expressions[0].output_name
''
key: ClassVar[str] = 'subquery'
required_args: 't.ClassVar[set[str]]' = {'this'}
class TableSample(sqlglot.expressions.core.Expression):
1730class TableSample(Expression):
1731    arg_types = {
1732        "expressions": False,
1733        "method": False,
1734        "bucket_numerator": False,
1735        "bucket_denominator": False,
1736        "bucket_field": False,
1737        "percent": False,
1738        "rows": False,
1739        "size": False,
1740        "seed": False,
1741    }
arg_types = {'expressions': False, 'method': False, 'bucket_numerator': False, 'bucket_denominator': False, 'bucket_field': False, 'percent': False, 'rows': False, 'size': False, 'seed': False}
key: ClassVar[str] = 'tablesample'
required_args: 't.ClassVar[set[str]]' = set()
class Tag(sqlglot.expressions.core.Expression):
1744class Tag(Expression):
1745    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
1746
1747    arg_types = {
1748        "this": False,
1749        "prefix": False,
1750        "postfix": False,
1751    }

Tags are used for generating arbitrary sql like SELECT x.

arg_types = {'this': False, 'prefix': False, 'postfix': False}
key: ClassVar[str] = 'tag'
required_args: 't.ClassVar[set[str]]' = set()
class Pivot(sqlglot.expressions.core.Expression):
1754class Pivot(Expression):
1755    arg_types = {
1756        "this": False,
1757        "alias": False,
1758        "expressions": False,
1759        "fields": False,
1760        "unpivot": False,
1761        "using": False,
1762        "group": False,
1763        "columns": False,
1764        "include_nulls": False,
1765        "default_on_null": False,
1766        "into": False,
1767        "with_": False,
1768        "identify_pivot_strings": False,
1769        "prefixed_pivot_columns": False,
1770        "pivot_column_naming": False,
1771        "value_columns_first": False,
1772    }
1773
1774    @property
1775    def unpivot(self) -> bool:
1776        return bool(self.args.get("unpivot"))
1777
1778    @property
1779    def fields(self) -> list[Expr]:
1780        return self.args.get("fields", [])
1781
1782    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1783        """
1784        Returns an ordered map of post-rename output column name -> pre-rename
1785        source-side name, in the order the (UN)PIVOT produces them.
1786
1787        For callers that just want the names, iterate the dict (or call .keys()):
1788            >>> from sqlglot import parse_one, exp
1789            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1790            >>> list(piv.output_columns(["a", "b", "c"]))
1791            ['c', 'name', 'val']
1792
1793        AST shape:
1794            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1795                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1796                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1797                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1798
1799            UNPIVOT(val FOR name IN (a, b)):
1800                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1801                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1802                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1803                             are wrapped in PivotAlias(this=Column, alias=Literal).
1804
1805        Args:
1806            pre_pivot_columns: Columns visible to the operator before it runs
1807                (e.g. the source table or subquery's projections).
1808        """
1809        if self.unpivot:
1810            excluded: set[str] = set()
1811            name_columns: list[Identifier] = []
1812            for field in self.fields:
1813                if not isinstance(field, In):
1814                    continue
1815                if isinstance(field.this, Identifier):
1816                    name_columns.append(field.this)
1817                for e in field.expressions:
1818                    excluded.update(c.output_name for c in e.find_all(Column))
1819            value_columns = [
1820                ident
1821                for e in self.expressions
1822                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1823                if isinstance(ident, Identifier)
1824            ]
1825            # T-SQL emits the value column(s) ahead of the name column, everyone else emits them after it
1826            ordered = (
1827                value_columns + name_columns
1828                if self.args.get("value_columns_first")
1829                else name_columns + value_columns
1830            )
1831            outputs = [i.name for i in ordered]
1832        else:
1833            excluded = {c.output_name for c in self.find_all(Column)}
1834            outputs = [c.output_name for c in self.args.get("columns") or []]
1835            if not outputs:
1836                outputs = [c.alias_or_name for c in self.expressions]
1837
1838        if not excluded or not outputs:
1839            return {}
1840
1841        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1842
1843        alias = self.args.get("alias")
1844        renames = alias.args.get("columns") if alias else None
1845
1846        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1847        # positionally from the front (DuckDB, Snowflake): the user's names cover
1848        # the leading N output columns, remaining columns keep their auto names.
1849        if renames:
1850            rename_names = [r.name for r in renames]
1851            post_rename = rename_names + pre_rename[len(rename_names) :]
1852        else:
1853            post_rename = pre_rename
1854
1855        return dict(zip(post_rename, pre_rename))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'fields': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False, 'into': False, 'with_': False, 'identify_pivot_strings': False, 'prefixed_pivot_columns': False, 'pivot_column_naming': False, 'value_columns_first': False}
unpivot: bool
1774    @property
1775    def unpivot(self) -> bool:
1776        return bool(self.args.get("unpivot"))
fields: list[sqlglot.expressions.core.Expr]
1778    @property
1779    def fields(self) -> list[Expr]:
1780        return self.args.get("fields", [])
def output_columns(self, pre_pivot_columns: Iterable[str]) -> dict[str, str]:
1782    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1783        """
1784        Returns an ordered map of post-rename output column name -> pre-rename
1785        source-side name, in the order the (UN)PIVOT produces them.
1786
1787        For callers that just want the names, iterate the dict (or call .keys()):
1788            >>> from sqlglot import parse_one, exp
1789            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1790            >>> list(piv.output_columns(["a", "b", "c"]))
1791            ['c', 'name', 'val']
1792
1793        AST shape:
1794            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1795                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1796                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1797                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1798
1799            UNPIVOT(val FOR name IN (a, b)):
1800                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1801                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1802                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1803                             are wrapped in PivotAlias(this=Column, alias=Literal).
1804
1805        Args:
1806            pre_pivot_columns: Columns visible to the operator before it runs
1807                (e.g. the source table or subquery's projections).
1808        """
1809        if self.unpivot:
1810            excluded: set[str] = set()
1811            name_columns: list[Identifier] = []
1812            for field in self.fields:
1813                if not isinstance(field, In):
1814                    continue
1815                if isinstance(field.this, Identifier):
1816                    name_columns.append(field.this)
1817                for e in field.expressions:
1818                    excluded.update(c.output_name for c in e.find_all(Column))
1819            value_columns = [
1820                ident
1821                for e in self.expressions
1822                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1823                if isinstance(ident, Identifier)
1824            ]
1825            # T-SQL emits the value column(s) ahead of the name column, everyone else emits them after it
1826            ordered = (
1827                value_columns + name_columns
1828                if self.args.get("value_columns_first")
1829                else name_columns + value_columns
1830            )
1831            outputs = [i.name for i in ordered]
1832        else:
1833            excluded = {c.output_name for c in self.find_all(Column)}
1834            outputs = [c.output_name for c in self.args.get("columns") or []]
1835            if not outputs:
1836                outputs = [c.alias_or_name for c in self.expressions]
1837
1838        if not excluded or not outputs:
1839            return {}
1840
1841        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1842
1843        alias = self.args.get("alias")
1844        renames = alias.args.get("columns") if alias else None
1845
1846        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1847        # positionally from the front (DuckDB, Snowflake): the user's names cover
1848        # the leading N output columns, remaining columns keep their auto names.
1849        if renames:
1850            rename_names = [r.name for r in renames]
1851            post_rename = rename_names + pre_rename[len(rename_names) :]
1852        else:
1853            post_rename = pre_rename
1854
1855        return dict(zip(post_rename, pre_rename))

Returns an ordered map of post-rename output column name -> pre-rename source-side name, in the order the (UN)PIVOT produces them.

For callers that just want the names, iterate the dict (or call .keys()):

from sqlglot import parse_one, exp piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot) list(piv.output_columns(["a", "b", "c"])) ['c', 'name', 'val']

AST shape:

PIVOT(SUM(val) FOR name IN ('a', 'b')): expressions: aggregate(s), e.g. [Sum(this=Column(val))] fields: [In(this=Column(name), expressions=[Literal('a'), Literal('b')])] columns: optional explicit output identifiers (e.g. set by Snowflake)

UNPIVOT(val FOR name IN (a, b)): expressions: value Identifier(s), or Tuple(Identifiers) for multi-value fields: [In(this=Identifier(name), expressions=[Column(a), Column(b)])] For literal-aliased entries (a AS 'x') the IN expressions are wrapped in PivotAlias(this=Column, alias=Literal).

Arguments:
  • pre_pivot_columns: Columns visible to the operator before it runs (e.g. the source table or subquery's projections).
key: ClassVar[str] = 'pivot'
required_args: 't.ClassVar[set[str]]' = set()
class UnpivotColumns(sqlglot.expressions.core.Expression):
1858class UnpivotColumns(Expression):
1859    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key: ClassVar[str] = 'unpivotcolumns'
required_args: 't.ClassVar[set[str]]' = {'this', 'expressions'}
1862class Window(Expression, Condition):
1863    arg_types = {
1864        "this": True,
1865        "partition_by": False,
1866        "order": False,
1867        "spec": False,
1868        "alias": False,
1869        "over": False,
1870        "first": False,
1871    }
arg_types = {'this': True, 'partition_by': False, 'order': False, 'spec': False, 'alias': False, 'over': False, 'first': False}
key: ClassVar[str] = 'window'
required_args: 't.ClassVar[set[str]]' = {'this'}
class WindowSpec(sqlglot.expressions.core.Expression):
1874class WindowSpec(Expression):
1875    arg_types = {
1876        "kind": False,
1877        "start": False,
1878        "start_side": False,
1879        "end": False,
1880        "end_side": False,
1881        "exclude": False,
1882    }
arg_types = {'kind': False, 'start': False, 'start_side': False, 'end': False, 'end_side': False, 'exclude': False}
key: ClassVar[str] = 'windowspec'
required_args: 't.ClassVar[set[str]]' = set()
class PreWhere(sqlglot.expressions.core.Expression):
1885class PreWhere(Expression):
1886    pass
key: ClassVar[str] = 'prewhere'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Where(sqlglot.expressions.core.Expression):
1889class Where(Expression):
1890    pass
key: ClassVar[str] = 'where'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Analyze(sqlglot.expressions.core.Expression):
1893class Analyze(Expression):
1894    arg_types = {
1895        "kind": False,
1896        "tables": False,
1897        "options": False,
1898        "mode": False,
1899        "partition": False,
1900        "expression": False,
1901        "properties": False,
1902    }
arg_types = {'kind': False, 'tables': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key: ClassVar[str] = 'analyze'
required_args: 't.ClassVar[set[str]]' = set()
class AnalyzeStatistics(sqlglot.expressions.core.Expression):
1905class AnalyzeStatistics(Expression):
1906    arg_types = {
1907        "kind": True,
1908        "option": False,
1909        "this": False,
1910        "expressions": False,
1911    }
arg_types = {'kind': True, 'option': False, 'this': False, 'expressions': False}
key: ClassVar[str] = 'analyzestatistics'
required_args: 't.ClassVar[set[str]]' = {'kind'}
class AnalyzeHistogram(sqlglot.expressions.core.Expression):
1914class AnalyzeHistogram(Expression):
1915    arg_types = {
1916        "this": True,
1917        "expressions": True,
1918        "expression": False,
1919        "update_options": False,
1920    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key: ClassVar[str] = 'analyzehistogram'
required_args: 't.ClassVar[set[str]]' = {'this', 'expressions'}
class AnalyzeSample(sqlglot.expressions.core.Expression):
1923class AnalyzeSample(Expression):
1924    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key: ClassVar[str] = 'analyzesample'
required_args: 't.ClassVar[set[str]]' = {'sample', 'kind'}
class AnalyzeListChainedRows(sqlglot.expressions.core.Expression):
1927class AnalyzeListChainedRows(Expression):
1928    arg_types = {"expression": False}
arg_types = {'expression': False}
key: ClassVar[str] = 'analyzelistchainedrows'
required_args: 't.ClassVar[set[str]]' = set()
class AnalyzeDelete(sqlglot.expressions.core.Expression):
1931class AnalyzeDelete(Expression):
1932    arg_types = {"kind": False}
arg_types = {'kind': False}
key: ClassVar[str] = 'analyzedelete'
required_args: 't.ClassVar[set[str]]' = set()
class AnalyzeWith(sqlglot.expressions.core.Expression):
1935class AnalyzeWith(Expression):
1936    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'analyzewith'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class AnalyzeValidate(sqlglot.expressions.core.Expression):
1939class AnalyzeValidate(Expression):
1940    arg_types = {
1941        "kind": True,
1942        "this": False,
1943        "expression": False,
1944    }
arg_types = {'kind': True, 'this': False, 'expression': False}
key: ClassVar[str] = 'analyzevalidate'
required_args: 't.ClassVar[set[str]]' = {'kind'}
class AnalyzeColumns(sqlglot.expressions.core.Expression):
1947class AnalyzeColumns(Expression):
1948    pass
key: ClassVar[str] = 'analyzecolumns'
required_args: 't.ClassVar[set[str]]' = {'this'}
class UsingData(sqlglot.expressions.core.Expression):
1951class UsingData(Expression):
1952    pass
key: ClassVar[str] = 'usingdata'
required_args: 't.ClassVar[set[str]]' = {'this'}
class AddPartition(sqlglot.expressions.core.Expression):
1955class AddPartition(Expression):
1956    arg_types = {"this": True, "exists": False, "location": False}
arg_types = {'this': True, 'exists': False, 'location': False}
key: ClassVar[str] = 'addpartition'
required_args: 't.ClassVar[set[str]]' = {'this'}
class AttachOption(sqlglot.expressions.core.Expression):
1959class AttachOption(Expression):
1960    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key: ClassVar[str] = 'attachoption'
required_args: 't.ClassVar[set[str]]' = {'this'}
class DropPartition(sqlglot.expressions.core.Expression):
1963class DropPartition(Expression):
1964    arg_types = {"expressions": True, "exists": False}
arg_types = {'expressions': True, 'exists': False}
key: ClassVar[str] = 'droppartition'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class ReplacePartition(sqlglot.expressions.core.Expression):
1967class ReplacePartition(Expression):
1968    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key: ClassVar[str] = 'replacepartition'
required_args: 't.ClassVar[set[str]]' = {'source', 'expression'}
class TranslateCharacters(sqlglot.expressions.core.Expression):
1971class TranslateCharacters(Expression):
1972    arg_types = {"this": True, "expression": True, "with_error": False}
arg_types = {'this': True, 'expression': True, 'with_error': False}
key: ClassVar[str] = 'translatecharacters'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this'}
class OverflowTruncateBehavior(sqlglot.expressions.core.Expression):
1975class OverflowTruncateBehavior(Expression):
1976    arg_types = {"this": False, "with_count": True}
arg_types = {'this': False, 'with_count': True}
key: ClassVar[str] = 'overflowtruncatebehavior'
required_args: 't.ClassVar[set[str]]' = {'with_count'}
class JSON(sqlglot.expressions.core.Expression):
1979class JSON(Expression):
1980    arg_types = {"this": False, "with_": False, "unique": False}
arg_types = {'this': False, 'with_': False, 'unique': False}
key: ClassVar[str] = 'json'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPath(sqlglot.expressions.core.Expression):
1983class JSONPath(Expression):
1984    arg_types = {"expressions": True}
1985
1986    @property
1987    def output_name(self) -> str:
1988        last_segment = self.expressions[-1].this
1989        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
1986    @property
1987    def output_name(self) -> str:
1988        last_segment = self.expressions[-1].this
1989        return last_segment if isinstance(last_segment, str) else ""

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a").expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c").expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2").expressions[0].output_name
''
key: ClassVar[str] = 'jsonpath'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class JSONPathPart(sqlglot.expressions.core.Expression):
1992class JSONPathPart(Expression):
1993    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'jsonpathpart'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathFilter(JSONPathPart):
1996class JSONPathFilter(JSONPathPart):
1997    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathfilter'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathKey(JSONPathPart):
2000class JSONPathKey(JSONPathPart):
2001    arg_types = {"this": True, "quoted": False}
arg_types = {'this': True, 'quoted': False}
key: ClassVar[str] = 'jsonpathkey'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathRecursive(JSONPathPart):
2004class JSONPathRecursive(JSONPathPart):
2005    arg_types = {"this": False}
arg_types = {'this': False}
key: ClassVar[str] = 'jsonpathrecursive'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathRoot(JSONPathPart):
2008class JSONPathRoot(JSONPathPart):
2009    pass
key: ClassVar[str] = 'jsonpathroot'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathScript(JSONPathPart):
2012class JSONPathScript(JSONPathPart):
2013    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathscript'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathSlice(JSONPathPart):
2016class JSONPathSlice(JSONPathPart):
2017    arg_types = {"start": False, "end": False, "step": False}
arg_types = {'start': False, 'end': False, 'step': False}
key: ClassVar[str] = 'jsonpathslice'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathSelector(JSONPathPart):
2020class JSONPathSelector(JSONPathPart):
2021    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathselector'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathSubscript(JSONPathPart):
2024class JSONPathSubscript(JSONPathPart):
2025    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathsubscript'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathUnion(JSONPathPart):
2028class JSONPathUnion(JSONPathPart):
2029    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'jsonpathunion'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class JSONPathWildcard(JSONPathPart):
2032class JSONPathWildcard(JSONPathPart):
2033    pass
key: ClassVar[str] = 'jsonpathwildcard'
required_args: 't.ClassVar[set[str]]' = set()
class FormatJson(sqlglot.expressions.core.Expression):
2036class FormatJson(Expression):
2037    pass
key: ClassVar[str] = 'formatjson'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONKeyValue(sqlglot.expressions.core.Expression):
2040class JSONKeyValue(Expression):
2041    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key: ClassVar[str] = 'jsonkeyvalue'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this'}
class JSONColumnDef(sqlglot.expressions.core.Expression):
2044class JSONColumnDef(Expression):
2045    arg_types = {
2046        "this": False,
2047        "kind": False,
2048        "path": False,
2049        "nested_schema": False,
2050        "ordinality": False,
2051        "format_json": False,
2052    }
arg_types = {'this': False, 'kind': False, 'path': False, 'nested_schema': False, 'ordinality': False, 'format_json': False}
key: ClassVar[str] = 'jsoncolumndef'
required_args: 't.ClassVar[set[str]]' = set()
class JSONSchema(sqlglot.expressions.core.Expression):
2055class JSONSchema(Expression):
2056    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'jsonschema'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class JSONValue(sqlglot.expressions.core.Expression):
2059class JSONValue(Expression):
2060    arg_types = {
2061        "this": True,
2062        "path": True,
2063        "returning": False,
2064        "on_condition": False,
2065    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key: ClassVar[str] = 'jsonvalue'
required_args: 't.ClassVar[set[str]]' = {'path', 'this'}
2068class JSONValueArray(Expression, Func):
2069    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key: ClassVar[str] = 'jsonvaluearray'
required_args: 't.ClassVar[set[str]]' = {'this'}
class OpenJSONColumnDef(sqlglot.expressions.core.Expression):
2072class OpenJSONColumnDef(Expression):
2073    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
arg_types = {'this': True, 'kind': True, 'path': False, 'as_json': False}
key: ClassVar[str] = 'openjsoncolumndef'
required_args: 't.ClassVar[set[str]]' = {'this', 'kind'}
class JSONExtractQuote(sqlglot.expressions.core.Expression):
2076class JSONExtractQuote(Expression):
2077    arg_types = {
2078        "option": True,
2079        "scalar": False,
2080    }
arg_types = {'option': True, 'scalar': False}
key: ClassVar[str] = 'jsonextractquote'
required_args: 't.ClassVar[set[str]]' = {'option'}
class ScopeResolution(sqlglot.expressions.core.Expression):
2083class ScopeResolution(Expression):
2084    arg_types = {"this": False, "expression": True}
arg_types = {'this': False, 'expression': True}
key: ClassVar[str] = 'scoperesolution'
required_args: 't.ClassVar[set[str]]' = {'expression'}
class Stream(sqlglot.expressions.core.Expression):
2087class Stream(Expression):
2088    pass
key: ClassVar[str] = 'stream'
required_args: 't.ClassVar[set[str]]' = {'this'}
class ModelAttribute(sqlglot.expressions.core.Expression):
2091class ModelAttribute(Expression):
2092    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key: ClassVar[str] = 'modelattribute'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this'}
class XMLNamespace(sqlglot.expressions.core.Expression):
2095class XMLNamespace(Expression):
2096    pass
key: ClassVar[str] = 'xmlnamespace'
required_args: 't.ClassVar[set[str]]' = {'this'}
class XMLKeyValueOption(sqlglot.expressions.core.Expression):
2099class XMLKeyValueOption(Expression):
2100    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key: ClassVar[str] = 'xmlkeyvalueoption'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Semicolon(sqlglot.expressions.core.Expression):
2103class Semicolon(Expression):
2104    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'semicolon'
required_args: 't.ClassVar[set[str]]' = set()
class TableColumn(sqlglot.expressions.core.Expression):
2107class TableColumn(Expression):
2108    @property
2109    def output_name(self) -> str:
2110        return self.name
output_name: str
2108    @property
2109    def output_name(self) -> str:
2110        return self.name

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

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

Example:
>>> from sqlglot import parse_one
>>> parse_one("SELECT a").expressions[0].output_name
'a'
>>> parse_one("SELECT b AS c").expressions[0].output_name
'c'
>>> parse_one("SELECT 1 + 2").expressions[0].output_name
''
key: ClassVar[str] = 'tablecolumn'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Variadic(sqlglot.expressions.core.Expression):
2113class Variadic(Expression):
2114    pass
key: ClassVar[str] = 'variadic'
required_args: 't.ClassVar[set[str]]' = {'this'}
class StoredProcedure(sqlglot.expressions.core.Expression):
2117class StoredProcedure(Expression):
2118    arg_types = {"this": True, "expressions": False, "wrapped": False}
arg_types = {'this': True, 'expressions': False, 'wrapped': False}
key: ClassVar[str] = 'storedprocedure'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Block(sqlglot.expressions.core.Expression):
2121class Block(Expression):
2122    arg_types = {"expressions": True, "begin": False}
arg_types = {'expressions': True, 'begin': False}
key: ClassVar[str] = 'block'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class IfBlock(sqlglot.expressions.core.Expression):
2125class IfBlock(Expression):
2126    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key: ClassVar[str] = 'ifblock'
required_args: 't.ClassVar[set[str]]' = {'true', 'this'}
class CaseStatement(sqlglot.expressions.core.Expression):
2129class CaseStatement(Expression):
2130    arg_types = {"this": False, "ifs": True, "default": False}
arg_types = {'this': False, 'ifs': True, 'default': False}
key: ClassVar[str] = 'casestatement'
required_args: 't.ClassVar[set[str]]' = {'ifs'}
class WhileBlock(sqlglot.expressions.core.Expression):
2133class WhileBlock(Expression):
2134    arg_types = {"this": True, "body": True, "label": False}
arg_types = {'this': True, 'body': True, 'label': False}
key: ClassVar[str] = 'whileblock'
required_args: 't.ClassVar[set[str]]' = {'body', 'this'}
class LoopBlock(sqlglot.expressions.core.Expression):
2137class LoopBlock(Expression):
2138    arg_types = {"body": True, "label": False}
arg_types = {'body': True, 'label': False}
key: ClassVar[str] = 'loopblock'
required_args: 't.ClassVar[set[str]]' = {'body'}
class RepeatBlock(sqlglot.expressions.core.Expression):
2141class RepeatBlock(Expression):
2142    arg_types = {"body": True, "until": True, "label": False}
arg_types = {'body': True, 'until': True, 'label': False}
key: ClassVar[str] = 'repeatblock'
required_args: 't.ClassVar[set[str]]' = {'body', 'until'}
class Leave(sqlglot.expressions.core.Expression):
2145class Leave(Expression):
2146    pass
key: ClassVar[str] = 'leave'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Iterate(sqlglot.expressions.core.Expression):
2149class Iterate(Expression):
2150    pass
key: ClassVar[str] = 'iterate'
required_args: 't.ClassVar[set[str]]' = {'this'}
class EndStatement(sqlglot.expressions.core.Expression):
2153class EndStatement(Expression):
2154    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'endstatement'
required_args: 't.ClassVar[set[str]]' = set()
class FunctionSpecification(sqlglot.expressions.core.Expression):
2158class FunctionSpecification(Expression):
2159    arg_types = {
2160        "this": True,
2161        "characteristics": False,
2162        "properties": False,
2163        "expression": True,
2164    }
arg_types = {'this': True, 'characteristics': False, 'properties': False, 'expression': True}
key: ClassVar[str] = 'functionspecification'
required_args: 't.ClassVar[set[str]]' = {'expression', 'this'}
UNWRAPPED_QUERIES = (<class 'Select'>, <class 'SetOperation'>)
def union( *expressions: Union[int, str, sqlglot.expressions.core.Expr], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Union:
2170def union(
2171    *expressions: ExpOrStr,
2172    distinct: bool = True,
2173    dialect: DialectType = None,
2174    copy: bool = True,
2175    **opts: Unpack[ParserNoDialectArgs],
2176) -> Union:
2177    """
2178    Initializes a syntax tree for the `UNION` operation.
2179
2180    Example:
2181        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
2182        'SELECT * FROM foo UNION SELECT * FROM bla'
2183
2184    Args:
2185        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
2186            If `Expr` instances are passed, they will be used as-is.
2187        distinct: set the DISTINCT flag if and only if this is true.
2188        dialect: the dialect used to parse the input expression.
2189        copy: whether to copy the expression.
2190        opts: other options to use to parse the input expressions.
2191
2192    Returns:
2193        The new Union instance.
2194    """
2195    assert len(expressions) >= 2, "At least two expressions are required by `union`."
2196    return _apply_set_operation(
2197        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
2198    )

Initializes a syntax tree for the UNION operation.

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

The new Union instance.

def intersect( *expressions: Union[int, str, sqlglot.expressions.core.Expr], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Intersect:
2201def intersect(
2202    *expressions: ExpOrStr,
2203    distinct: bool = True,
2204    dialect: DialectType = None,
2205    copy: bool = True,
2206    **opts: Unpack[ParserNoDialectArgs],
2207) -> Intersect:
2208    """
2209    Initializes a syntax tree for the `INTERSECT` operation.
2210
2211    Example:
2212        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
2213        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
2214
2215    Args:
2216        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
2217            If `Expr` instances are passed, they will be used as-is.
2218        distinct: set the DISTINCT flag if and only if this is true.
2219        dialect: the dialect used to parse the input expression.
2220        copy: whether to copy the expression.
2221        opts: other options to use to parse the input expressions.
2222
2223    Returns:
2224        The new Intersect instance.
2225    """
2226    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
2227    return _apply_set_operation(
2228        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
2229    )

Initializes a syntax tree for the INTERSECT operation.

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

The new Intersect instance.

def except_( *expressions: Union[int, str, sqlglot.expressions.core.Expr], distinct: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Except:
2232def except_(
2233    *expressions: ExpOrStr,
2234    distinct: bool = True,
2235    dialect: DialectType = None,
2236    copy: bool = True,
2237    **opts: Unpack[ParserNoDialectArgs],
2238) -> Except:
2239    """
2240    Initializes a syntax tree for the `EXCEPT` operation.
2241
2242    Example:
2243        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
2244        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
2245
2246    Args:
2247        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
2248            If `Expr` instances are passed, they will be used as-is.
2249        distinct: set the DISTINCT flag if and only if this is true.
2250        dialect: the dialect used to parse the input expression.
2251        copy: whether to copy the expression.
2252        opts: other options to use to parse the input expressions.
2253
2254    Returns:
2255        The new Except instance.
2256    """
2257    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
2258    return _apply_set_operation(
2259        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
2260    )

Initializes a syntax tree for the EXCEPT operation.

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

The new Except instance.