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        "cube": False,
 628        "rollup": False,
 629        "totals": False,
 630        "all": False,
 631    }
 632
 633
 634class Cube(Expression):
 635    arg_types = {"expressions": False}
 636
 637
 638class Rollup(Expression):
 639    arg_types = {"expressions": False}
 640
 641
 642class GroupingSets(Expression):
 643    arg_types = {"expressions": True}
 644
 645
 646class Lambda(Expression):
 647    arg_types = {"this": True, "expressions": True, "colon": False}
 648
 649
 650class Limit(Expression):
 651    arg_types = {
 652        "this": False,
 653        "expression": True,
 654        "offset": False,
 655        "limit_options": False,
 656        "expressions": False,
 657    }
 658
 659
 660class LimitOptions(Expression):
 661    arg_types = {
 662        "percent": False,
 663        "rows": False,
 664        "with_ties": False,
 665    }
 666
 667
 668class Join(Expression):
 669    arg_types = {
 670        "this": True,
 671        "on": False,
 672        "side": False,
 673        "kind": False,
 674        "using": False,
 675        "method": False,
 676        "global_": False,
 677        "hint": False,
 678        "match_condition": False,  # Snowflake
 679        "directed": False,  # Snowflake
 680        "expressions": False,
 681        "pivots": False,
 682    }
 683
 684    @property
 685    def method(self) -> str:
 686        return self.text("method").upper()
 687
 688    @property
 689    def kind(self) -> str:
 690        return self.text("kind").upper()
 691
 692    @property
 693    def side(self) -> str:
 694        return self.text("side").upper()
 695
 696    @property
 697    def hint(self) -> str:
 698        return self.text("hint").upper()
 699
 700    @property
 701    def alias_or_name(self) -> str:
 702        return self.this.alias_or_name
 703
 704    @property
 705    def is_semi_or_anti_join(self) -> bool:
 706        return self.kind in ("SEMI", "ANTI")
 707
 708    def on(
 709        self,
 710        *expressions: ExpOrStr | None,
 711        append: bool = True,
 712        dialect: DialectType = None,
 713        copy: bool = True,
 714        **opts: Unpack[ParserNoDialectArgs],
 715    ) -> Join:
 716        """
 717        Append to or set the ON expressions.
 718
 719        Example:
 720            >>> import sqlglot
 721            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
 722            'JOIN x ON y = 1'
 723
 724        Args:
 725            *expressions: the SQL code strings to parse.
 726                If an `Expr` instance is passed, it will be used as-is.
 727                Multiple expressions are combined with an AND operator.
 728            append: if `True`, AND the new expressions to any existing expression.
 729                Otherwise, this resets the expression.
 730            dialect: the dialect used to parse the input expressions.
 731            copy: if `False`, modify this expression instance in-place.
 732            opts: other options to use to parse the input expressions.
 733
 734        Returns:
 735            The modified Join expression.
 736        """
 737        join = _apply_conjunction_builder(
 738            *expressions,
 739            instance=self,
 740            arg="on",
 741            append=append,
 742            dialect=dialect,
 743            copy=copy,
 744            **opts,
 745        )
 746
 747        if join.kind == "CROSS":
 748            join.set("kind", None)
 749
 750        return join
 751
 752    def using(
 753        self,
 754        *expressions: ExpOrStr | None,
 755        append: bool = True,
 756        dialect: DialectType = None,
 757        copy: bool = True,
 758        **opts: Unpack[ParserNoDialectArgs],
 759    ) -> Join:
 760        """
 761        Append to or set the USING expressions.
 762
 763        Example:
 764            >>> import sqlglot
 765            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
 766            'JOIN x USING (foo, bla)'
 767
 768        Args:
 769            *expressions: the SQL code strings to parse.
 770                If an `Expr` instance is passed, it will be used as-is.
 771            append: if `True`, concatenate the new expressions to the existing "using" list.
 772                Otherwise, this resets the expression.
 773            dialect: the dialect used to parse the input expressions.
 774            copy: if `False`, modify this expression instance in-place.
 775            opts: other options to use to parse the input expressions.
 776
 777        Returns:
 778            The modified Join expression.
 779        """
 780        join = _apply_list_builder(
 781            *expressions,
 782            instance=self,
 783            arg="using",
 784            append=append,
 785            dialect=dialect,
 786            copy=copy,
 787            **opts,
 788        )
 789
 790        if join.kind == "CROSS":
 791            join.set("kind", None)
 792
 793        return join
 794
 795
 796class Lateral(Expression, UDTF):
 797    arg_types = {
 798        "this": True,
 799        "view": False,
 800        "outer": False,
 801        "alias": False,
 802        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
 803        "ordinality": False,
 804    }
 805
 806
 807class TableFromRows(Expression, UDTF):
 808    arg_types = {
 809        "this": True,
 810        "alias": False,
 811        "joins": False,
 812        "pivots": False,
 813        "sample": False,
 814    }
 815
 816
 817class MatchRecognizeMeasure(Expression):
 818    arg_types = {
 819        "this": True,
 820        "window_frame": False,
 821    }
 822
 823
 824class MatchRecognize(Expression):
 825    arg_types = {
 826        "partition_by": False,
 827        "order": False,
 828        "measures": False,
 829        "rows": False,
 830        "after": False,
 831        "pattern": False,
 832        "define": False,
 833        "alias": False,
 834    }
 835
 836
 837class Final(Expression):
 838    pass
 839
 840
 841class Offset(Expression):
 842    arg_types = {"this": False, "expression": True, "expressions": False}
 843
 844
 845class Order(Expression):
 846    arg_types = {"this": False, "expressions": True, "siblings": False}
 847
 848
 849class WithFill(Expression):
 850    arg_types = {
 851        "from_": False,
 852        "to": False,
 853        "step": False,
 854        "interpolate": False,
 855    }
 856
 857
 858class SkipJSONColumn(Expression):
 859    arg_types = {"regexp": False, "expression": True}
 860
 861
 862class Cluster(Expression):
 863    arg_types = {"expressions": True}
 864
 865
 866class Distribute(Order):
 867    pass
 868
 869
 870class Sort(Order):
 871    pass
 872
 873
 874class Qualify(Expression):
 875    pass
 876
 877
 878class InputOutputFormat(Expression):
 879    arg_types = {"input_format": False, "output_format": False}
 880
 881
 882class Return(Expression):
 883    pass
 884
 885
 886class Tuple(Expression):
 887    arg_types = {"expressions": False}
 888
 889    def isin(
 890        self,
 891        *expressions: t.Any,
 892        query: ExpOrStr | None = None,
 893        unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None,
 894        copy: bool = True,
 895        **opts: Unpack[ParserArgs],
 896    ) -> In:
 897        return In(
 898            this=maybe_copy(self, copy),
 899            expressions=[convert(e, copy=copy) for e in expressions],
 900            query=maybe_parse(query, copy=copy, **opts) if query else None,
 901            unnest=(
 902                Unnest(
 903                    expressions=[
 904                        maybe_parse(e, copy=copy, **opts)
 905                        for e in t.cast(list[ExpOrStr], ensure_list(unnest))
 906                    ]
 907                )
 908                if unnest
 909                else None
 910            ),
 911        )
 912
 913
 914class QueryOption(Expression):
 915    arg_types = {"this": True, "expression": False}
 916
 917
 918# FOR { XML | JSON } query modifier; `kind` is the discriminant ("XML" or "JSON").
 919class ForClause(Expression):
 920    arg_types = {"kind": True, "expressions": False}
 921
 922
 923class WithTableHint(Expression):
 924    arg_types = {"expressions": True}
 925
 926
 927class IndexTableHint(Expression):
 928    arg_types = {"this": True, "expressions": False, "target": False}
 929
 930
 931class HistoricalData(Expression):
 932    arg_types = {"this": True, "kind": True, "expression": True}
 933
 934
 935class Put(Expression):
 936    arg_types = {"this": True, "target": True, "properties": False}
 937
 938
 939class Get(Expression):
 940    arg_types = {"this": True, "target": True, "properties": False}
 941
 942
 943class Table(Expression, Selectable):
 944    arg_types = {
 945        "this": False,
 946        "alias": False,
 947        "db": False,
 948        "catalog": False,
 949        "laterals": False,
 950        "joins": False,
 951        "pivots": False,
 952        "hints": False,
 953        "system_time": False,
 954        "version": False,
 955        "format": False,
 956        "pattern": False,
 957        "ordinality": False,
 958        "when": False,
 959        "only": False,
 960        "partition": False,
 961        "changes": False,
 962        "rows_from": False,
 963        "sample": False,
 964        "indexed": False,
 965    }
 966
 967    @property
 968    def name(self) -> str:
 969        if not self.this or isinstance(self.this, Func):
 970            return ""
 971        return self.this.name
 972
 973    @property
 974    def db(self) -> str:
 975        return self.text("db")
 976
 977    @property
 978    def catalog(self) -> str:
 979        return self.text("catalog")
 980
 981    @property
 982    def selects(self) -> list[Expr]:
 983        return []
 984
 985    @property
 986    def named_selects(self) -> list[str]:
 987        return []
 988
 989    @property
 990    def parts(self) -> list[Expr]:
 991        """Return the parts of a table in order catalog, db, table."""
 992        parts: list[Expr] = []
 993
 994        for arg in ("catalog", "db", "this"):
 995            part = self.args.get(arg)
 996
 997            if isinstance(part, Dot):
 998                parts.extend(part.flatten())
 999            elif isinstance(part, Expr):
1000                parts.append(part)
1001
1002        return parts
1003
1004    def to_column(self, copy: bool = True) -> Expr:
1005        parts = self.parts
1006        last_part = parts[-1]
1007
1008        if isinstance(last_part, Identifier):
1009            col: Expr = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
1010        else:
1011            # This branch will be reached if a function or array is wrapped in a `Table`
1012            col = last_part
1013
1014        alias = self.args.get("alias")
1015        if alias:
1016            col = alias_(col, alias.this, copy=copy)
1017
1018        return col
1019
1020
1021class SetOperation(Expression, Query):
1022    arg_types = {
1023        "with_": False,
1024        "this": True,
1025        "expression": True,
1026        "distinct": False,
1027        "by_name": False,
1028        "side": False,
1029        "kind": False,
1030        "on": False,
1031        **QUERY_MODIFIERS,
1032    }
1033
1034    def select(
1035        self: S,
1036        *expressions: ExpOrStr | None,
1037        append: bool = True,
1038        dialect: DialectType = None,
1039        copy: bool = True,
1040        **opts: Unpack[ParserNoDialectArgs],
1041    ) -> S:
1042        this = maybe_copy(self, copy)
1043        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1044        this.expression.unnest().select(
1045            *expressions, append=append, dialect=dialect, copy=False, **opts
1046        )
1047        return this
1048
1049    @property
1050    def named_selects(self) -> list[str]:
1051        expr: Expr = self
1052        while isinstance(expr, SetOperation):
1053            expr = expr.this.unnest()
1054        return _named_selects(expr)
1055
1056    @property
1057    def is_star(self) -> bool:
1058        return self.this.is_star or self.expression.is_star
1059
1060    @property
1061    def selects(self) -> list[Expr]:
1062        expr: Expr = self
1063        while isinstance(expr, SetOperation):
1064            expr = expr.this.unnest()
1065        return getattr(expr, "selects", [])
1066
1067    @property
1068    def left(self) -> Query:
1069        return self.this
1070
1071    @property
1072    def right(self) -> Query:
1073        return self.expression
1074
1075    @property
1076    def kind(self) -> str:
1077        return self.text("kind").upper()
1078
1079    @property
1080    def side(self) -> str:
1081        return self.text("side").upper()
1082
1083
1084class Union(SetOperation):
1085    pass
1086
1087
1088class Except(SetOperation):
1089    pass
1090
1091
1092class Intersect(SetOperation):
1093    pass
1094
1095
1096class Values(Expression, UDTF):
1097    arg_types = {
1098        "expressions": True,
1099        "alias": False,
1100        "order": False,
1101        "limit": False,
1102        "offset": False,
1103    }
1104
1105
1106class Version(Expression):
1107    """
1108    Time travel, iceberg, bigquery etc
1109    https://trino.io/docs/current/connector/iceberg.html?highlight=snapshot#using-snapshots
1110    https://www.databricks.com/blog/2019/02/04/introducing-delta-time-travel-for-large-scale-data-lakes.html
1111    https://cloud.google.com/bigquery/docs/reference/standard-sql/query-syntax#for_system_time_as_of
1112    https://learn.microsoft.com/en-us/sql/relational-databases/tables/querying-data-in-a-system-versioned-temporal-table?view=sql-server-ver16
1113    this is either TIMESTAMP or VERSION
1114    kind is ("AS OF", "BETWEEN")
1115    """
1116
1117    arg_types = {"this": True, "kind": True, "expression": False}
1118
1119
1120class Schema(Expression):
1121    arg_types = {"this": False, "expressions": False}
1122
1123
1124class Lock(Expression):
1125    arg_types = {"update": True, "expressions": False, "wait": False, "key": False}
1126
1127
1128class Select(Expression, Query):
1129    arg_types = {
1130        "with_": False,
1131        "kind": False,
1132        "expressions": False,
1133        "hint": False,
1134        "distinct": False,
1135        "into": False,
1136        "from_": False,
1137        "operation_modifiers": False,
1138        "exclude": False,
1139        **QUERY_MODIFIERS,
1140    }
1141
1142    def from_(
1143        self,
1144        expression: ExpOrStr,
1145        dialect: DialectType = None,
1146        copy: bool = True,
1147        **opts: Unpack[ParserNoDialectArgs],
1148    ) -> Select:
1149        """
1150        Set the FROM expression.
1151
1152        Example:
1153            >>> Select().from_("tbl").select("x").sql()
1154            'SELECT x FROM tbl'
1155
1156        Args:
1157            expression : the SQL code strings to parse.
1158                If a `From` instance is passed, this is used as-is.
1159                If another `Expr` instance is passed, it will be wrapped in a `From`.
1160            dialect: the dialect used to parse the input expression.
1161            copy: if `False`, modify this expression instance in-place.
1162            opts: other options to use to parse the input expressions.
1163
1164        Returns:
1165            The modified Select expression.
1166        """
1167        return _apply_builder(
1168            expression=expression,
1169            instance=self,
1170            arg="from_",
1171            into=From,
1172            prefix="FROM",
1173            dialect=dialect,
1174            copy=copy,
1175            **opts,
1176        )
1177
1178    def group_by(
1179        self,
1180        *expressions: ExpOrStr | None,
1181        append: bool = True,
1182        dialect: DialectType = None,
1183        copy: bool = True,
1184        **opts: Unpack[ParserNoDialectArgs],
1185    ) -> Select:
1186        """
1187        Set the GROUP BY expression.
1188
1189        Example:
1190            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
1191            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
1192
1193        Args:
1194            *expressions: the SQL code strings to parse.
1195                If a `Group` instance is passed, this is used as-is.
1196                If another `Expr` instance is passed, it will be wrapped in a `Group`.
1197                If nothing is passed in then a group by is not applied to the expression
1198            append: if `True`, add to any existing expressions.
1199                Otherwise, this flattens all the `Group` expression into a single expression.
1200            dialect: the dialect used to parse the input expression.
1201            copy: if `False`, modify this expression instance in-place.
1202            opts: other options to use to parse the input expressions.
1203
1204        Returns:
1205            The modified Select expression.
1206        """
1207        if not expressions:
1208            return self if not copy else self.copy()
1209
1210        return _apply_child_list_builder(
1211            *expressions,
1212            instance=self,
1213            arg="group",
1214            append=append,
1215            copy=copy,
1216            prefix="GROUP BY",
1217            into=Group,
1218            dialect=dialect,
1219            **opts,
1220        )
1221
1222    def sort_by(
1223        self,
1224        *expressions: ExpOrStr | None,
1225        append: bool = True,
1226        dialect: DialectType = None,
1227        copy: bool = True,
1228        **opts: Unpack[ParserNoDialectArgs],
1229    ) -> Select:
1230        """
1231        Set the SORT BY expression.
1232
1233        Example:
1234            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
1235            'SELECT x FROM tbl SORT BY x DESC'
1236
1237        Args:
1238            *expressions: the SQL code strings to parse.
1239                If a `Group` instance is passed, this is used as-is.
1240                If another `Expr` instance is passed, it will be wrapped in a `SORT`.
1241            append: if `True`, add to any existing expressions.
1242                Otherwise, this flattens all the `Order` expression into a single expression.
1243            dialect: the dialect used to parse the input expression.
1244            copy: if `False`, modify this expression instance in-place.
1245            opts: other options to use to parse the input expressions.
1246
1247        Returns:
1248            The modified Select expression.
1249        """
1250        return _apply_child_list_builder(
1251            *expressions,
1252            instance=self,
1253            arg="sort",
1254            append=append,
1255            copy=copy,
1256            prefix="SORT BY",
1257            into=Sort,
1258            dialect=dialect,
1259            **opts,
1260        )
1261
1262    def cluster_by(
1263        self,
1264        *expressions: ExpOrStr | None,
1265        append: bool = True,
1266        dialect: DialectType = None,
1267        copy: bool = True,
1268        **opts: Unpack[ParserNoDialectArgs],
1269    ) -> Select:
1270        """
1271        Set the CLUSTER BY expression.
1272
1273        Example:
1274            >>> Select().from_("tbl").select("x").cluster_by("x").sql(dialect="hive")
1275            'SELECT x FROM tbl CLUSTER BY x'
1276
1277        Args:
1278            *expressions: the SQL code strings to parse.
1279                If a `Group` instance is passed, this is used as-is.
1280                If another `Expr` instance is passed, it will be wrapped in a `Cluster`.
1281            append: if `True`, add to any existing expressions.
1282                Otherwise, this flattens all the `Order` expression into a single expression.
1283            dialect: the dialect used to parse the input expression.
1284            copy: if `False`, modify this expression instance in-place.
1285            opts: other options to use to parse the input expressions.
1286
1287        Returns:
1288            The modified Select expression.
1289        """
1290        return _apply_child_list_builder(
1291            *expressions,
1292            instance=self,
1293            arg="cluster",
1294            append=append,
1295            copy=copy,
1296            prefix="CLUSTER BY",
1297            into=Cluster,
1298            dialect=dialect,
1299            **opts,
1300        )
1301
1302    def select(
1303        self,
1304        *expressions: ExpOrStr | None,
1305        append: bool = True,
1306        dialect: DialectType = None,
1307        copy: bool = True,
1308        **opts: Unpack[ParserNoDialectArgs],
1309    ) -> Select:
1310        return _apply_list_builder(
1311            *expressions,
1312            instance=self,
1313            arg="expressions",
1314            append=append,
1315            dialect=dialect,
1316            into=Expr,
1317            copy=copy,
1318            **opts,
1319        )
1320
1321    def lateral(
1322        self,
1323        *expressions: ExpOrStr | None,
1324        append: bool = True,
1325        dialect: DialectType = None,
1326        copy: bool = True,
1327        **opts: Unpack[ParserNoDialectArgs],
1328    ) -> Select:
1329        """
1330        Append to or set the LATERAL expressions.
1331
1332        Example:
1333            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
1334            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
1335
1336        Args:
1337            *expressions: the SQL code strings to parse.
1338                If an `Expr` instance is passed, it will be used as-is.
1339            append: if `True`, add to any existing expressions.
1340                Otherwise, this resets the expressions.
1341            dialect: the dialect used to parse the input expressions.
1342            copy: if `False`, modify this expression instance in-place.
1343            opts: other options to use to parse the input expressions.
1344
1345        Returns:
1346            The modified Select expression.
1347        """
1348        return _apply_list_builder(
1349            *expressions,
1350            instance=self,
1351            arg="laterals",
1352            append=append,
1353            into=Lateral,
1354            prefix="LATERAL VIEW",
1355            dialect=dialect,
1356            copy=copy,
1357            **opts,
1358        )
1359
1360    def join(
1361        self,
1362        expression: ExpOrStr,
1363        on: ExpOrStr | list[ExpOrStr] | tuple[ExpOrStr, ...] | None = None,
1364        using: ExpOrStr | list[ExpOrStr] | tuple[ExpOrStr, ...] | None = None,
1365        append: bool = True,
1366        join_type: str | None = None,
1367        join_alias: Identifier | str | None = None,
1368        dialect: DialectType = None,
1369        copy: bool = True,
1370        **opts: Unpack[ParserNoDialectArgs],
1371    ) -> Select:
1372        """
1373        Append to or set the JOIN expressions.
1374
1375        Example:
1376            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
1377            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
1378
1379            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
1380            'SELECT 1 FROM a JOIN b USING (x, y, z)'
1381
1382            Use `join_type` to change the type of join:
1383
1384            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
1385            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
1386
1387        Args:
1388            expression: the SQL code string to parse.
1389                If an `Expr` instance is passed, it will be used as-is.
1390            on: optionally specify the join "on" criteria as a SQL string.
1391                If an `Expr` instance is passed, it will be used as-is.
1392            using: optionally specify the join "using" criteria as a SQL string.
1393                If an `Expr` instance is passed, it will be used as-is.
1394            append: if `True`, add to any existing expressions.
1395                Otherwise, this resets the expressions.
1396            join_type: if set, alter the parsed join type.
1397            join_alias: an optional alias for the joined source.
1398            dialect: the dialect used to parse the input expressions.
1399            copy: if `False`, modify this expression instance in-place.
1400            opts: other options to use to parse the input expressions.
1401
1402        Returns:
1403            Select: the modified expression.
1404        """
1405        parse_args: ParserArgs = {"dialect": dialect, **opts}
1406        try:
1407            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
1408        except ParseError:
1409            expression = maybe_parse(expression, into=(Join, Expr), **parse_args)
1410
1411        join = expression if isinstance(expression, Join) else Join(this=expression)
1412
1413        if isinstance(join.this, Select):
1414            join.this.replace(join.this.subquery())
1415
1416        if join_type:
1417            new_join: Join = maybe_parse(f"FROM _ {join_type} JOIN _", **parse_args).find(Join)
1418            method = new_join.method
1419            side = new_join.side
1420            kind = new_join.kind
1421
1422            if method:
1423                join.set("method", method)
1424            if side:
1425                join.set("side", side)
1426            if kind:
1427                join.set("kind", kind)
1428
1429        if on:
1430            on_exprs: list[ExpOrStr] = ensure_list(on)
1431            on = and_(*on_exprs, dialect=dialect, copy=copy, **opts)
1432            join.set("on", on)
1433
1434        if using:
1435            using_exprs: list[ExpOrStr] = ensure_list(using)
1436            join = _apply_list_builder(
1437                *using_exprs,
1438                instance=join,
1439                arg="using",
1440                append=append,
1441                copy=copy,
1442                into=Identifier,
1443                **opts,
1444            )
1445
1446        if join_alias:
1447            join.set("this", alias_(join.this, join_alias, table=True))
1448
1449        return _apply_list_builder(
1450            join,
1451            instance=self,
1452            arg="joins",
1453            append=append,
1454            copy=copy,
1455            **opts,
1456        )
1457
1458    def having(
1459        self,
1460        *expressions: ExpOrStr | None,
1461        append: bool = True,
1462        dialect: DialectType = None,
1463        copy: bool = True,
1464        **opts: Unpack[ParserNoDialectArgs],
1465    ) -> Select:
1466        """
1467        Append to or set the HAVING expressions.
1468
1469        Example:
1470            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
1471            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
1472
1473        Args:
1474            *expressions: the SQL code strings to parse.
1475                If an `Expr` instance is passed, it will be used as-is.
1476                Multiple expressions are combined with an AND operator.
1477            append: if `True`, AND the new expressions to any existing expression.
1478                Otherwise, this resets the expression.
1479            dialect: the dialect used to parse the input expressions.
1480            copy: if `False`, modify this expression instance in-place.
1481            opts: other options to use to parse the input expressions.
1482
1483        Returns:
1484            The modified Select expression.
1485        """
1486        return _apply_conjunction_builder(
1487            *expressions,
1488            instance=self,
1489            arg="having",
1490            append=append,
1491            into=Having,
1492            dialect=dialect,
1493            copy=copy,
1494            **opts,
1495        )
1496
1497    def window(
1498        self,
1499        *expressions: ExpOrStr | None,
1500        append: bool = True,
1501        dialect: DialectType = None,
1502        copy: bool = True,
1503        **opts: Unpack[ParserNoDialectArgs],
1504    ) -> Select:
1505        return _apply_list_builder(
1506            *expressions,
1507            instance=self,
1508            arg="windows",
1509            append=append,
1510            into=Window,
1511            dialect=dialect,
1512            copy=copy,
1513            **opts,
1514        )
1515
1516    def qualify(
1517        self,
1518        *expressions: ExpOrStr | None,
1519        append: bool = True,
1520        dialect: DialectType = None,
1521        copy: bool = True,
1522        **opts: Unpack[ParserNoDialectArgs],
1523    ) -> Select:
1524        return _apply_conjunction_builder(
1525            *expressions,
1526            instance=self,
1527            arg="qualify",
1528            append=append,
1529            into=Qualify,
1530            dialect=dialect,
1531            copy=copy,
1532            **opts,
1533        )
1534
1535    def distinct(self, *ons: ExpOrStr | None, distinct: bool = True, copy: bool = True) -> Select:
1536        """
1537        Set the OFFSET expression.
1538
1539        Example:
1540            >>> Select().from_("tbl").select("x").distinct().sql()
1541            'SELECT DISTINCT x FROM tbl'
1542
1543        Args:
1544            ons: the expressions to distinct on
1545            distinct: whether the Select should be distinct
1546            copy: if `False`, modify this expression instance in-place.
1547
1548        Returns:
1549            Select: the modified expression.
1550        """
1551        instance = maybe_copy(self, copy)
1552        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
1553        instance.set("distinct", Distinct(on=on) if distinct else None)
1554        return instance
1555
1556    def ctas(
1557        self,
1558        table: ExpOrStr,
1559        properties: dict | None = None,
1560        dialect: DialectType = None,
1561        copy: bool = True,
1562        **opts: Unpack[ParserNoDialectArgs],
1563    ) -> Create:
1564        """
1565        Convert this expression to a CREATE TABLE AS statement.
1566
1567        Example:
1568            >>> Select().select("*").from_("tbl").ctas("x").sql()
1569            'CREATE TABLE x AS SELECT * FROM tbl'
1570
1571        Args:
1572            table: the SQL code string to parse as the table name.
1573                If another `Expr` instance is passed, it will be used as-is.
1574            properties: an optional mapping of table properties
1575            dialect: the dialect used to parse the input table.
1576            copy: if `False`, modify this expression instance in-place.
1577            opts: other options to use to parse the input table.
1578
1579        Returns:
1580            The new Create expression.
1581        """
1582        instance = maybe_copy(self, copy)
1583        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
1584
1585        properties_expression = None
1586        if properties:
1587            from sqlglot.expressions.properties import Properties as _Properties
1588
1589            properties_expression = _Properties.from_dict(properties)
1590
1591        from sqlglot.expressions.ddl import Create as _Create
1592
1593        return _Create(
1594            this=table_expression,
1595            kind="TABLE",
1596            expression=instance,
1597            properties=properties_expression,
1598        )
1599
1600    def lock(self, update: bool = True, copy: bool = True) -> Select:
1601        """
1602        Set the locking read mode for this expression.
1603
1604        Examples:
1605            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
1606            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
1607
1608            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
1609            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
1610
1611        Args:
1612            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
1613            copy: if `False`, modify this expression instance in-place.
1614
1615        Returns:
1616            The modified expression.
1617        """
1618        inst = maybe_copy(self, copy)
1619        inst.set("locks", [Lock(update=update)])
1620
1621        return inst
1622
1623    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
1624        """
1625        Set hints for this expression.
1626
1627        Examples:
1628            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
1629            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
1630
1631        Args:
1632            hints: The SQL code strings to parse as the hints.
1633                If an `Expr` instance is passed, it will be used as-is.
1634            dialect: The dialect used to parse the hints.
1635            copy: If `False`, modify this expression instance in-place.
1636
1637        Returns:
1638            The modified expression.
1639        """
1640        inst = maybe_copy(self, copy)
1641        inst.set(
1642            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
1643        )
1644
1645        return inst
1646
1647    @property
1648    def named_selects(self) -> list[str]:
1649        selects = []
1650
1651        for e in self.expressions:
1652            if e.alias_or_name:
1653                selects.append(e.output_name)
1654            elif isinstance(e, Aliases):
1655                selects.extend([a.name for a in e.aliases])
1656        return selects
1657
1658    @property
1659    def is_star(self) -> bool:
1660        return any(expression.is_star for expression in self.expressions)
1661
1662    @property
1663    def selects(self) -> list[Expr]:
1664        return self.expressions
1665
1666
1667class Subquery(Expression, DerivedTable, Query):
1668    is_subquery: t.ClassVar[bool] = True
1669    arg_types = {
1670        "this": True,
1671        "alias": False,
1672        "with_": False,
1673        **QUERY_MODIFIERS,
1674    }
1675
1676    def unnest(self) -> Expr:
1677        """Returns the first non subquery."""
1678        expression: Expr = self
1679        while isinstance(expression, Subquery):
1680            expression = expression.this
1681        return expression
1682
1683    def unwrap(self) -> Subquery:
1684        expression = self
1685        while expression.same_parent and expression.is_wrapper:
1686            expression = t.cast(Subquery, expression.parent)
1687        return expression
1688
1689    def select(
1690        self,
1691        *expressions: ExpOrStr | None,
1692        append: bool = True,
1693        dialect: DialectType = None,
1694        copy: bool = True,
1695        **opts: Unpack[ParserNoDialectArgs],
1696    ) -> Subquery:
1697        this = maybe_copy(self, copy)
1698        inner = this.unnest()
1699        if hasattr(inner, "select"):
1700            inner.select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1701        return this
1702
1703    @property
1704    def is_wrapper(self) -> bool:
1705        """
1706        Whether this Subquery acts as a simple wrapper around another expression.
1707
1708        SELECT * FROM (((SELECT * FROM t)))
1709                      ^
1710                      This corresponds to a "wrapper" Subquery node
1711        """
1712        return all(v is None for k, v in self.args.items() if k != "this")
1713
1714    @property
1715    def is_star(self) -> bool:
1716        return self.this.is_star
1717
1718    @property
1719    def output_name(self) -> str:
1720        return self.alias
1721
1722
1723class TableSample(Expression):
1724    arg_types = {
1725        "expressions": False,
1726        "method": False,
1727        "bucket_numerator": False,
1728        "bucket_denominator": False,
1729        "bucket_field": False,
1730        "percent": False,
1731        "rows": False,
1732        "size": False,
1733        "seed": False,
1734    }
1735
1736
1737class Tag(Expression):
1738    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
1739
1740    arg_types = {
1741        "this": False,
1742        "prefix": False,
1743        "postfix": False,
1744    }
1745
1746
1747class Pivot(Expression):
1748    arg_types = {
1749        "this": False,
1750        "alias": False,
1751        "expressions": False,
1752        "fields": False,
1753        "unpivot": False,
1754        "using": False,
1755        "group": False,
1756        "columns": False,
1757        "include_nulls": False,
1758        "default_on_null": False,
1759        "into": False,
1760        "with_": False,
1761        "identify_pivot_strings": False,
1762        "prefixed_pivot_columns": False,
1763        "pivot_column_naming": False,
1764        "value_columns_first": False,
1765    }
1766
1767    @property
1768    def unpivot(self) -> bool:
1769        return bool(self.args.get("unpivot"))
1770
1771    @property
1772    def fields(self) -> list[Expr]:
1773        return self.args.get("fields", [])
1774
1775    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1776        """
1777        Returns an ordered map of post-rename output column name -> pre-rename
1778        source-side name, in the order the (UN)PIVOT produces them.
1779
1780        For callers that just want the names, iterate the dict (or call .keys()):
1781            >>> from sqlglot import parse_one, exp
1782            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1783            >>> list(piv.output_columns(["a", "b", "c"]))
1784            ['c', 'name', 'val']
1785
1786        AST shape:
1787            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1788                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1789                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1790                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1791
1792            UNPIVOT(val FOR name IN (a, b)):
1793                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1794                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1795                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1796                             are wrapped in PivotAlias(this=Column, alias=Literal).
1797
1798        Args:
1799            pre_pivot_columns: Columns visible to the operator before it runs
1800                (e.g. the source table or subquery's projections).
1801        """
1802        if self.unpivot:
1803            excluded: set[str] = set()
1804            name_columns: list[Identifier] = []
1805            for field in self.fields:
1806                if not isinstance(field, In):
1807                    continue
1808                if isinstance(field.this, Identifier):
1809                    name_columns.append(field.this)
1810                for e in field.expressions:
1811                    excluded.update(c.output_name for c in e.find_all(Column))
1812            value_columns = [
1813                ident
1814                for e in self.expressions
1815                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1816                if isinstance(ident, Identifier)
1817            ]
1818            # T-SQL emits the value column(s) ahead of the name column, everyone else emits them after it
1819            ordered = (
1820                value_columns + name_columns
1821                if self.args.get("value_columns_first")
1822                else name_columns + value_columns
1823            )
1824            outputs = [i.name for i in ordered]
1825        else:
1826            excluded = {c.output_name for c in self.find_all(Column)}
1827            outputs = [c.output_name for c in self.args.get("columns") or []]
1828            if not outputs:
1829                outputs = [c.alias_or_name for c in self.expressions]
1830
1831        if not excluded or not outputs:
1832            return {}
1833
1834        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1835
1836        alias = self.args.get("alias")
1837        renames = alias.args.get("columns") if alias else None
1838
1839        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1840        # positionally from the front (DuckDB, Snowflake): the user's names cover
1841        # the leading N output columns, remaining columns keep their auto names.
1842        if renames:
1843            rename_names = [r.name for r in renames]
1844            post_rename = rename_names + pre_rename[len(rename_names) :]
1845        else:
1846            post_rename = pre_rename
1847
1848        return dict(zip(post_rename, pre_rename))
1849
1850
1851class UnpivotColumns(Expression):
1852    arg_types = {"this": True, "expressions": True}
1853
1854
1855class Window(Expression, Condition):
1856    arg_types = {
1857        "this": True,
1858        "partition_by": False,
1859        "order": False,
1860        "spec": False,
1861        "alias": False,
1862        "over": False,
1863        "first": False,
1864    }
1865
1866
1867class WindowSpec(Expression):
1868    arg_types = {
1869        "kind": False,
1870        "start": False,
1871        "start_side": False,
1872        "end": False,
1873        "end_side": False,
1874        "exclude": False,
1875    }
1876
1877
1878class PreWhere(Expression):
1879    pass
1880
1881
1882class Where(Expression):
1883    pass
1884
1885
1886class Analyze(Expression):
1887    arg_types = {
1888        "kind": False,
1889        "this": False,
1890        "options": False,
1891        "mode": False,
1892        "partition": False,
1893        "expression": False,
1894        "properties": False,
1895    }
1896
1897
1898class AnalyzeStatistics(Expression):
1899    arg_types = {
1900        "kind": True,
1901        "option": False,
1902        "this": False,
1903        "expressions": False,
1904    }
1905
1906
1907class AnalyzeHistogram(Expression):
1908    arg_types = {
1909        "this": True,
1910        "expressions": True,
1911        "expression": False,
1912        "update_options": False,
1913    }
1914
1915
1916class AnalyzeSample(Expression):
1917    arg_types = {"kind": True, "sample": True}
1918
1919
1920class AnalyzeListChainedRows(Expression):
1921    arg_types = {"expression": False}
1922
1923
1924class AnalyzeDelete(Expression):
1925    arg_types = {"kind": False}
1926
1927
1928class AnalyzeWith(Expression):
1929    arg_types = {"expressions": True}
1930
1931
1932class AnalyzeValidate(Expression):
1933    arg_types = {
1934        "kind": True,
1935        "this": False,
1936        "expression": False,
1937    }
1938
1939
1940class AnalyzeColumns(Expression):
1941    pass
1942
1943
1944class UsingData(Expression):
1945    pass
1946
1947
1948class AddPartition(Expression):
1949    arg_types = {"this": True, "exists": False, "location": False}
1950
1951
1952class AttachOption(Expression):
1953    arg_types = {"this": True, "expression": False}
1954
1955
1956class DropPartition(Expression):
1957    arg_types = {"expressions": True, "exists": False}
1958
1959
1960class ReplacePartition(Expression):
1961    arg_types = {"expression": True, "source": True}
1962
1963
1964class TranslateCharacters(Expression):
1965    arg_types = {"this": True, "expression": True, "with_error": False}
1966
1967
1968class OverflowTruncateBehavior(Expression):
1969    arg_types = {"this": False, "with_count": True}
1970
1971
1972class JSON(Expression):
1973    arg_types = {"this": False, "with_": False, "unique": False}
1974
1975
1976class JSONPath(Expression):
1977    arg_types = {"expressions": True}
1978
1979    @property
1980    def output_name(self) -> str:
1981        last_segment = self.expressions[-1].this
1982        return last_segment if isinstance(last_segment, str) else ""
1983
1984
1985class JSONPathPart(Expression):
1986    arg_types = {}
1987
1988
1989class JSONPathFilter(JSONPathPart):
1990    arg_types = {"this": True}
1991
1992
1993class JSONPathKey(JSONPathPart):
1994    arg_types = {"this": True, "quoted": False}
1995
1996
1997class JSONPathRecursive(JSONPathPart):
1998    arg_types = {"this": False}
1999
2000
2001class JSONPathRoot(JSONPathPart):
2002    pass
2003
2004
2005class JSONPathScript(JSONPathPart):
2006    arg_types = {"this": True}
2007
2008
2009class JSONPathSlice(JSONPathPart):
2010    arg_types = {"start": False, "end": False, "step": False}
2011
2012
2013class JSONPathSelector(JSONPathPart):
2014    arg_types = {"this": True}
2015
2016
2017class JSONPathSubscript(JSONPathPart):
2018    arg_types = {"this": True}
2019
2020
2021class JSONPathUnion(JSONPathPart):
2022    arg_types = {"expressions": True}
2023
2024
2025class JSONPathWildcard(JSONPathPart):
2026    pass
2027
2028
2029class FormatJson(Expression):
2030    pass
2031
2032
2033class JSONKeyValue(Expression):
2034    arg_types = {"this": True, "expression": True}
2035
2036
2037class JSONColumnDef(Expression):
2038    arg_types = {
2039        "this": False,
2040        "kind": False,
2041        "path": False,
2042        "nested_schema": False,
2043        "ordinality": False,
2044        "format_json": False,
2045    }
2046
2047
2048class JSONSchema(Expression):
2049    arg_types = {"expressions": True}
2050
2051
2052class JSONValue(Expression):
2053    arg_types = {
2054        "this": True,
2055        "path": True,
2056        "returning": False,
2057        "on_condition": False,
2058    }
2059
2060
2061class JSONValueArray(Expression, Func):
2062    arg_types = {"this": True, "expression": False}
2063
2064
2065class OpenJSONColumnDef(Expression):
2066    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
2067
2068
2069class JSONExtractQuote(Expression):
2070    arg_types = {
2071        "option": True,
2072        "scalar": False,
2073    }
2074
2075
2076class ScopeResolution(Expression):
2077    arg_types = {"this": False, "expression": True}
2078
2079
2080class Stream(Expression):
2081    pass
2082
2083
2084class ModelAttribute(Expression):
2085    arg_types = {"this": True, "expression": True}
2086
2087
2088class XMLNamespace(Expression):
2089    pass
2090
2091
2092class XMLKeyValueOption(Expression):
2093    arg_types = {"this": True, "expression": False}
2094
2095
2096class Semicolon(Expression):
2097    arg_types = {}
2098
2099
2100class TableColumn(Expression):
2101    @property
2102    def output_name(self) -> str:
2103        return self.name
2104
2105
2106class Variadic(Expression):
2107    pass
2108
2109
2110class StoredProcedure(Expression):
2111    arg_types = {"this": True, "expressions": False, "wrapped": False}
2112
2113
2114class Block(Expression):
2115    arg_types = {"expressions": True, "begin": False}
2116
2117
2118class IfBlock(Expression):
2119    arg_types = {"this": True, "true": True, "false": False}
2120
2121
2122class WhileBlock(Expression):
2123    arg_types = {"this": True, "body": True}
2124
2125
2126class EndStatement(Expression):
2127    arg_types = {}
2128
2129
2130# https://trino.io/docs/current/udf.html
2131class FunctionSpecification(Expression):
2132    arg_types = {
2133        "this": True,
2134        "characteristics": False,
2135        "properties": False,
2136        "expression": True,
2137    }
2138
2139
2140UNWRAPPED_QUERIES = (Select, SetOperation)
2141
2142
2143def union(
2144    *expressions: ExpOrStr,
2145    distinct: bool = True,
2146    dialect: DialectType = None,
2147    copy: bool = True,
2148    **opts: Unpack[ParserNoDialectArgs],
2149) -> Union:
2150    """
2151    Initializes a syntax tree for the `UNION` operation.
2152
2153    Example:
2154        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
2155        'SELECT * FROM foo UNION SELECT * FROM bla'
2156
2157    Args:
2158        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
2159            If `Expr` instances are passed, they will be used as-is.
2160        distinct: set the DISTINCT flag if and only if this is true.
2161        dialect: the dialect used to parse the input expression.
2162        copy: whether to copy the expression.
2163        opts: other options to use to parse the input expressions.
2164
2165    Returns:
2166        The new Union instance.
2167    """
2168    assert len(expressions) >= 2, "At least two expressions are required by `union`."
2169    return _apply_set_operation(
2170        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
2171    )
2172
2173
2174def intersect(
2175    *expressions: ExpOrStr,
2176    distinct: bool = True,
2177    dialect: DialectType = None,
2178    copy: bool = True,
2179    **opts: Unpack[ParserNoDialectArgs],
2180) -> Intersect:
2181    """
2182    Initializes a syntax tree for the `INTERSECT` operation.
2183
2184    Example:
2185        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
2186        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
2187
2188    Args:
2189        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
2190            If `Expr` instances are passed, they will be used as-is.
2191        distinct: set the DISTINCT flag if and only if this is true.
2192        dialect: the dialect used to parse the input expression.
2193        copy: whether to copy the expression.
2194        opts: other options to use to parse the input expressions.
2195
2196    Returns:
2197        The new Intersect instance.
2198    """
2199    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
2200    return _apply_set_operation(
2201        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
2202    )
2203
2204
2205def except_(
2206    *expressions: ExpOrStr,
2207    distinct: bool = True,
2208    dialect: DialectType = None,
2209    copy: bool = True,
2210    **opts: Unpack[ParserNoDialectArgs],
2211) -> Except:
2212    """
2213    Initializes a syntax tree for the `EXCEPT` operation.
2214
2215    Example:
2216        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
2217        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
2218
2219    Args:
2220        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
2221            If `Expr` instances are passed, they will be used as-is.
2222        distinct: set the DISTINCT flag if and only if this is true.
2223        dialect: the dialect used to parse the input expression.
2224        copy: whether to copy the expression.
2225        opts: other options to use to parse the input expressions.
2226
2227    Returns:
2228        The new Except instance.
2229    """
2230    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
2231    return _apply_set_operation(
2232        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
2233    )
@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]]' = {'kind', 'expression', 'this'}
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]]' = {'kind', 'source', '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', 'principals', 'privileges'}
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', 'principals', 'privileges'}
class Group(sqlglot.expressions.core.Expression):
624class Group(Expression):
625    arg_types = {
626        "expressions": False,
627        "grouping_sets": False,
628        "cube": False,
629        "rollup": False,
630        "totals": False,
631        "all": False,
632    }
arg_types = {'expressions': False, 'grouping_sets': 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):
635class Cube(Expression):
636    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):
639class Rollup(Expression):
640    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):
643class GroupingSets(Expression):
644    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):
647class Lambda(Expression):
648    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]]' = {'expressions', 'this'}
class Limit(sqlglot.expressions.core.Expression):
651class Limit(Expression):
652    arg_types = {
653        "this": False,
654        "expression": True,
655        "offset": False,
656        "limit_options": False,
657        "expressions": False,
658    }
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):
661class LimitOptions(Expression):
662    arg_types = {
663        "percent": False,
664        "rows": False,
665        "with_ties": False,
666    }
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):
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
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
685    @property
686    def method(self) -> str:
687        return self.text("method").upper()
kind: str
689    @property
690    def kind(self) -> str:
691        return self.text("kind").upper()
side: str
693    @property
694    def side(self) -> str:
695        return self.text("side").upper()
hint: str
697    @property
698    def hint(self) -> str:
699        return self.text("hint").upper()
alias_or_name: str
701    @property
702    def alias_or_name(self) -> str:
703        return self.this.alias_or_name
is_semi_or_anti_join: bool
705    @property
706    def is_semi_or_anti_join(self) -> bool:
707        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:
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

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:
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

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):
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    }
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):
808class TableFromRows(Expression, UDTF):
809    arg_types = {
810        "this": True,
811        "alias": False,
812        "joins": False,
813        "pivots": False,
814        "sample": False,
815    }
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):
818class MatchRecognizeMeasure(Expression):
819    arg_types = {
820        "this": True,
821        "window_frame": False,
822    }
arg_types = {'this': True, 'window_frame': False}
key: ClassVar[str] = 'matchrecognizemeasure'
required_args: 't.ClassVar[set[str]]' = {'this'}
class MatchRecognize(sqlglot.expressions.core.Expression):
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    }
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):
838class Final(Expression):
839    pass
key: ClassVar[str] = 'final'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Offset(sqlglot.expressions.core.Expression):
842class Offset(Expression):
843    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):
846class Order(Expression):
847    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):
850class WithFill(Expression):
851    arg_types = {
852        "from_": False,
853        "to": False,
854        "step": False,
855        "interpolate": False,
856    }
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):
859class SkipJSONColumn(Expression):
860    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):
863class Cluster(Expression):
864    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'cluster'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Distribute(Order):
867class Distribute(Order):
868    pass
key: ClassVar[str] = 'distribute'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Sort(Order):
871class Sort(Order):
872    pass
key: ClassVar[str] = 'sort'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Qualify(sqlglot.expressions.core.Expression):
875class Qualify(Expression):
876    pass
key: ClassVar[str] = 'qualify'
required_args: 't.ClassVar[set[str]]' = {'this'}
class InputOutputFormat(sqlglot.expressions.core.Expression):
879class InputOutputFormat(Expression):
880    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):
883class Return(Expression):
884    pass
key: ClassVar[str] = 'return'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Tuple(sqlglot.expressions.core.Expression):
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        )
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:
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        )
key: ClassVar[str] = 'tuple'
required_args: 't.ClassVar[set[str]]' = set()
class QueryOption(sqlglot.expressions.core.Expression):
915class QueryOption(Expression):
916    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):
920class ForClause(Expression):
921    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):
924class WithTableHint(Expression):
925    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):
928class IndexTableHint(Expression):
929    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):
932class HistoricalData(Expression):
933    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]]' = {'kind', 'expression', 'this'}
class Put(sqlglot.expressions.core.Expression):
936class Put(Expression):
937    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):
940class Get(Expression):
941    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):
 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
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
968    @property
969    def name(self) -> str:
970        if not self.this or isinstance(self.this, Func):
971            return ""
972        return self.this.name
db: str
974    @property
975    def db(self) -> str:
976        return self.text("db")
catalog: str
978    @property
979    def catalog(self) -> str:
980        return self.text("catalog")
selects: list[sqlglot.expressions.core.Expr]
982    @property
983    def selects(self) -> list[Expr]:
984        return []
named_selects: list[str]
986    @property
987    def named_selects(self) -> list[str]:
988        return []
parts: list[sqlglot.expressions.core.Expr]
 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

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

def to_column(self, copy: bool = True) -> sqlglot.expressions.core.Expr:
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
key: ClassVar[str] = 'table'
required_args: 't.ClassVar[set[str]]' = set()
class SetOperation(sqlglot.expressions.core.Expression, Query):
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            expr = expr.this.unnest()
1055        return _named_selects(expr)
1056
1057    @property
1058    def is_star(self) -> bool:
1059        return self.this.is_star or self.expression.is_star
1060
1061    @property
1062    def selects(self) -> list[Expr]:
1063        expr: Expr = self
1064        while isinstance(expr, SetOperation):
1065            expr = expr.this.unnest()
1066        return getattr(expr, "selects", [])
1067
1068    @property
1069    def left(self) -> Query:
1070        return self.this
1071
1072    @property
1073    def right(self) -> Query:
1074        return self.expression
1075
1076    @property
1077    def kind(self) -> str:
1078        return self.text("kind").upper()
1079
1080    @property
1081    def side(self) -> str:
1082        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:
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
named_selects: list[str]
1050    @property
1051    def named_selects(self) -> list[str]:
1052        expr: Expr = self
1053        while isinstance(expr, SetOperation):
1054            expr = expr.this.unnest()
1055        return _named_selects(expr)
is_star: bool
1057    @property
1058    def is_star(self) -> bool:
1059        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

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

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

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

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

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

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

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

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:
1498    def window(
1499        self,
1500        *expressions: ExpOrStr | None,
1501        append: bool = True,
1502        dialect: DialectType = None,
1503        copy: bool = True,
1504        **opts: Unpack[ParserNoDialectArgs],
1505    ) -> Select:
1506        return _apply_list_builder(
1507            *expressions,
1508            instance=self,
1509            arg="windows",
1510            append=append,
1511            into=Window,
1512            dialect=dialect,
1513            copy=copy,
1514            **opts,
1515        )
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:
1517    def qualify(
1518        self,
1519        *expressions: ExpOrStr | None,
1520        append: bool = True,
1521        dialect: DialectType = None,
1522        copy: bool = True,
1523        **opts: Unpack[ParserNoDialectArgs],
1524    ) -> Select:
1525        return _apply_conjunction_builder(
1526            *expressions,
1527            instance=self,
1528            arg="qualify",
1529            append=append,
1530            into=Qualify,
1531            dialect=dialect,
1532            copy=copy,
1533            **opts,
1534        )
def distinct( self, *ons: Union[int, str, sqlglot.expressions.core.Expr, NoneType], distinct: bool = True, copy: bool = True) -> Select:
1536    def distinct(self, *ons: ExpOrStr | None, distinct: bool = True, copy: bool = True) -> Select:
1537        """
1538        Set the OFFSET expression.
1539
1540        Example:
1541            >>> Select().from_("tbl").select("x").distinct().sql()
1542            'SELECT DISTINCT x FROM tbl'
1543
1544        Args:
1545            ons: the expressions to distinct on
1546            distinct: whether the Select should be distinct
1547            copy: if `False`, modify this expression instance in-place.
1548
1549        Returns:
1550            Select: the modified expression.
1551        """
1552        instance = maybe_copy(self, copy)
1553        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
1554        instance.set("distinct", Distinct(on=on) if distinct else None)
1555        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:
1557    def ctas(
1558        self,
1559        table: ExpOrStr,
1560        properties: dict | None = None,
1561        dialect: DialectType = None,
1562        copy: bool = True,
1563        **opts: Unpack[ParserNoDialectArgs],
1564    ) -> Create:
1565        """
1566        Convert this expression to a CREATE TABLE AS statement.
1567
1568        Example:
1569            >>> Select().select("*").from_("tbl").ctas("x").sql()
1570            'CREATE TABLE x AS SELECT * FROM tbl'
1571
1572        Args:
1573            table: the SQL code string to parse as the table name.
1574                If another `Expr` instance is passed, it will be used as-is.
1575            properties: an optional mapping of table properties
1576            dialect: the dialect used to parse the input table.
1577            copy: if `False`, modify this expression instance in-place.
1578            opts: other options to use to parse the input table.
1579
1580        Returns:
1581            The new Create expression.
1582        """
1583        instance = maybe_copy(self, copy)
1584        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
1585
1586        properties_expression = None
1587        if properties:
1588            from sqlglot.expressions.properties import Properties as _Properties
1589
1590            properties_expression = _Properties.from_dict(properties)
1591
1592        from sqlglot.expressions.ddl import Create as _Create
1593
1594        return _Create(
1595            this=table_expression,
1596            kind="TABLE",
1597            expression=instance,
1598            properties=properties_expression,
1599        )

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:
1601    def lock(self, update: bool = True, copy: bool = True) -> Select:
1602        """
1603        Set the locking read mode for this expression.
1604
1605        Examples:
1606            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
1607            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
1608
1609            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
1610            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
1611
1612        Args:
1613            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
1614            copy: if `False`, modify this expression instance in-place.
1615
1616        Returns:
1617            The modified expression.
1618        """
1619        inst = maybe_copy(self, copy)
1620        inst.set("locks", [Lock(update=update)])
1621
1622        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:
1624    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
1625        """
1626        Set hints for this expression.
1627
1628        Examples:
1629            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
1630            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
1631
1632        Args:
1633            hints: The SQL code strings to parse as the hints.
1634                If an `Expr` instance is passed, it will be used as-is.
1635            dialect: The dialect used to parse the hints.
1636            copy: If `False`, modify this expression instance in-place.
1637
1638        Returns:
1639            The modified expression.
1640        """
1641        inst = maybe_copy(self, copy)
1642        inst.set(
1643            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
1644        )
1645
1646        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]
1648    @property
1649    def named_selects(self) -> list[str]:
1650        selects = []
1651
1652        for e in self.expressions:
1653            if e.alias_or_name:
1654                selects.append(e.output_name)
1655            elif isinstance(e, Aliases):
1656                selects.extend([a.name for a in e.aliases])
1657        return selects
is_star: bool
1659    @property
1660    def is_star(self) -> bool:
1661        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: list[sqlglot.expressions.core.Expr]
1663    @property
1664    def selects(self) -> list[Expr]:
1665        return self.expressions
key: ClassVar[str] = 'select'
required_args: 't.ClassVar[set[str]]' = set()
class Subquery(sqlglot.expressions.core.Expression, DerivedTable, Query):
1668class Subquery(Expression, DerivedTable, Query):
1669    is_subquery: t.ClassVar[bool] = True
1670    arg_types = {
1671        "this": True,
1672        "alias": False,
1673        "with_": False,
1674        **QUERY_MODIFIERS,
1675    }
1676
1677    def unnest(self) -> Expr:
1678        """Returns the first non subquery."""
1679        expression: Expr = self
1680        while isinstance(expression, Subquery):
1681            expression = expression.this
1682        return expression
1683
1684    def unwrap(self) -> Subquery:
1685        expression = self
1686        while expression.same_parent and expression.is_wrapper:
1687            expression = t.cast(Subquery, expression.parent)
1688        return expression
1689
1690    def select(
1691        self,
1692        *expressions: ExpOrStr | None,
1693        append: bool = True,
1694        dialect: DialectType = None,
1695        copy: bool = True,
1696        **opts: Unpack[ParserNoDialectArgs],
1697    ) -> Subquery:
1698        this = maybe_copy(self, copy)
1699        inner = this.unnest()
1700        if hasattr(inner, "select"):
1701            inner.select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1702        return this
1703
1704    @property
1705    def is_wrapper(self) -> bool:
1706        """
1707        Whether this Subquery acts as a simple wrapper around another expression.
1708
1709        SELECT * FROM (((SELECT * FROM t)))
1710                      ^
1711                      This corresponds to a "wrapper" Subquery node
1712        """
1713        return all(v is None for k, v in self.args.items() if k != "this")
1714
1715    @property
1716    def is_star(self) -> bool:
1717        return self.this.is_star
1718
1719    @property
1720    def output_name(self) -> str:
1721        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:
1677    def unnest(self) -> Expr:
1678        """Returns the first non subquery."""
1679        expression: Expr = self
1680        while isinstance(expression, Subquery):
1681            expression = expression.this
1682        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
1684    def unwrap(self) -> Subquery:
1685        expression = self
1686        while expression.same_parent and expression.is_wrapper:
1687            expression = t.cast(Subquery, expression.parent)
1688        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:
1690    def select(
1691        self,
1692        *expressions: ExpOrStr | None,
1693        append: bool = True,
1694        dialect: DialectType = None,
1695        copy: bool = True,
1696        **opts: Unpack[ParserNoDialectArgs],
1697    ) -> Subquery:
1698        this = maybe_copy(self, copy)
1699        inner = this.unnest()
1700        if hasattr(inner, "select"):
1701            inner.select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1702        return this
is_wrapper: bool
1704    @property
1705    def is_wrapper(self) -> bool:
1706        """
1707        Whether this Subquery acts as a simple wrapper around another expression.
1708
1709        SELECT * FROM (((SELECT * FROM t)))
1710                      ^
1711                      This corresponds to a "wrapper" Subquery node
1712        """
1713        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
1715    @property
1716    def is_star(self) -> bool:
1717        return self.this.is_star

Checks whether an expression is a star.

output_name: str
1719    @property
1720    def output_name(self) -> str:
1721        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):
1724class TableSample(Expression):
1725    arg_types = {
1726        "expressions": False,
1727        "method": False,
1728        "bucket_numerator": False,
1729        "bucket_denominator": False,
1730        "bucket_field": False,
1731        "percent": False,
1732        "rows": False,
1733        "size": False,
1734        "seed": False,
1735    }
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):
1738class Tag(Expression):
1739    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
1740
1741    arg_types = {
1742        "this": False,
1743        "prefix": False,
1744        "postfix": False,
1745    }

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):
1748class Pivot(Expression):
1749    arg_types = {
1750        "this": False,
1751        "alias": False,
1752        "expressions": False,
1753        "fields": False,
1754        "unpivot": False,
1755        "using": False,
1756        "group": False,
1757        "columns": False,
1758        "include_nulls": False,
1759        "default_on_null": False,
1760        "into": False,
1761        "with_": False,
1762        "identify_pivot_strings": False,
1763        "prefixed_pivot_columns": False,
1764        "pivot_column_naming": False,
1765        "value_columns_first": False,
1766    }
1767
1768    @property
1769    def unpivot(self) -> bool:
1770        return bool(self.args.get("unpivot"))
1771
1772    @property
1773    def fields(self) -> list[Expr]:
1774        return self.args.get("fields", [])
1775
1776    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1777        """
1778        Returns an ordered map of post-rename output column name -> pre-rename
1779        source-side name, in the order the (UN)PIVOT produces them.
1780
1781        For callers that just want the names, iterate the dict (or call .keys()):
1782            >>> from sqlglot import parse_one, exp
1783            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1784            >>> list(piv.output_columns(["a", "b", "c"]))
1785            ['c', 'name', 'val']
1786
1787        AST shape:
1788            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1789                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1790                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1791                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1792
1793            UNPIVOT(val FOR name IN (a, b)):
1794                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1795                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1796                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1797                             are wrapped in PivotAlias(this=Column, alias=Literal).
1798
1799        Args:
1800            pre_pivot_columns: Columns visible to the operator before it runs
1801                (e.g. the source table or subquery's projections).
1802        """
1803        if self.unpivot:
1804            excluded: set[str] = set()
1805            name_columns: list[Identifier] = []
1806            for field in self.fields:
1807                if not isinstance(field, In):
1808                    continue
1809                if isinstance(field.this, Identifier):
1810                    name_columns.append(field.this)
1811                for e in field.expressions:
1812                    excluded.update(c.output_name for c in e.find_all(Column))
1813            value_columns = [
1814                ident
1815                for e in self.expressions
1816                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1817                if isinstance(ident, Identifier)
1818            ]
1819            # T-SQL emits the value column(s) ahead of the name column, everyone else emits them after it
1820            ordered = (
1821                value_columns + name_columns
1822                if self.args.get("value_columns_first")
1823                else name_columns + value_columns
1824            )
1825            outputs = [i.name for i in ordered]
1826        else:
1827            excluded = {c.output_name for c in self.find_all(Column)}
1828            outputs = [c.output_name for c in self.args.get("columns") or []]
1829            if not outputs:
1830                outputs = [c.alias_or_name for c in self.expressions]
1831
1832        if not excluded or not outputs:
1833            return {}
1834
1835        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1836
1837        alias = self.args.get("alias")
1838        renames = alias.args.get("columns") if alias else None
1839
1840        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1841        # positionally from the front (DuckDB, Snowflake): the user's names cover
1842        # the leading N output columns, remaining columns keep their auto names.
1843        if renames:
1844            rename_names = [r.name for r in renames]
1845            post_rename = rename_names + pre_rename[len(rename_names) :]
1846        else:
1847            post_rename = pre_rename
1848
1849        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
1768    @property
1769    def unpivot(self) -> bool:
1770        return bool(self.args.get("unpivot"))
fields: list[sqlglot.expressions.core.Expr]
1772    @property
1773    def fields(self) -> list[Expr]:
1774        return self.args.get("fields", [])
def output_columns(self, pre_pivot_columns: Iterable[str]) -> dict[str, str]:
1776    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1777        """
1778        Returns an ordered map of post-rename output column name -> pre-rename
1779        source-side name, in the order the (UN)PIVOT produces them.
1780
1781        For callers that just want the names, iterate the dict (or call .keys()):
1782            >>> from sqlglot import parse_one, exp
1783            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1784            >>> list(piv.output_columns(["a", "b", "c"]))
1785            ['c', 'name', 'val']
1786
1787        AST shape:
1788            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1789                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1790                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1791                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1792
1793            UNPIVOT(val FOR name IN (a, b)):
1794                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1795                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1796                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1797                             are wrapped in PivotAlias(this=Column, alias=Literal).
1798
1799        Args:
1800            pre_pivot_columns: Columns visible to the operator before it runs
1801                (e.g. the source table or subquery's projections).
1802        """
1803        if self.unpivot:
1804            excluded: set[str] = set()
1805            name_columns: list[Identifier] = []
1806            for field in self.fields:
1807                if not isinstance(field, In):
1808                    continue
1809                if isinstance(field.this, Identifier):
1810                    name_columns.append(field.this)
1811                for e in field.expressions:
1812                    excluded.update(c.output_name for c in e.find_all(Column))
1813            value_columns = [
1814                ident
1815                for e in self.expressions
1816                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1817                if isinstance(ident, Identifier)
1818            ]
1819            # T-SQL emits the value column(s) ahead of the name column, everyone else emits them after it
1820            ordered = (
1821                value_columns + name_columns
1822                if self.args.get("value_columns_first")
1823                else name_columns + value_columns
1824            )
1825            outputs = [i.name for i in ordered]
1826        else:
1827            excluded = {c.output_name for c in self.find_all(Column)}
1828            outputs = [c.output_name for c in self.args.get("columns") or []]
1829            if not outputs:
1830                outputs = [c.alias_or_name for c in self.expressions]
1831
1832        if not excluded or not outputs:
1833            return {}
1834
1835        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1836
1837        alias = self.args.get("alias")
1838        renames = alias.args.get("columns") if alias else None
1839
1840        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1841        # positionally from the front (DuckDB, Snowflake): the user's names cover
1842        # the leading N output columns, remaining columns keep their auto names.
1843        if renames:
1844            rename_names = [r.name for r in renames]
1845            post_rename = rename_names + pre_rename[len(rename_names) :]
1846        else:
1847            post_rename = pre_rename
1848
1849        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):
1852class UnpivotColumns(Expression):
1853    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key: ClassVar[str] = 'unpivotcolumns'
required_args: 't.ClassVar[set[str]]' = {'expressions', 'this'}
1856class Window(Expression, Condition):
1857    arg_types = {
1858        "this": True,
1859        "partition_by": False,
1860        "order": False,
1861        "spec": False,
1862        "alias": False,
1863        "over": False,
1864        "first": False,
1865    }
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):
1868class WindowSpec(Expression):
1869    arg_types = {
1870        "kind": False,
1871        "start": False,
1872        "start_side": False,
1873        "end": False,
1874        "end_side": False,
1875        "exclude": False,
1876    }
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):
1879class PreWhere(Expression):
1880    pass
key: ClassVar[str] = 'prewhere'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Where(sqlglot.expressions.core.Expression):
1883class Where(Expression):
1884    pass
key: ClassVar[str] = 'where'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Analyze(sqlglot.expressions.core.Expression):
1887class Analyze(Expression):
1888    arg_types = {
1889        "kind": False,
1890        "this": False,
1891        "options": False,
1892        "mode": False,
1893        "partition": False,
1894        "expression": False,
1895        "properties": False,
1896    }
arg_types = {'kind': False, 'this': 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):
1899class AnalyzeStatistics(Expression):
1900    arg_types = {
1901        "kind": True,
1902        "option": False,
1903        "this": False,
1904        "expressions": False,
1905    }
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):
1908class AnalyzeHistogram(Expression):
1909    arg_types = {
1910        "this": True,
1911        "expressions": True,
1912        "expression": False,
1913        "update_options": False,
1914    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key: ClassVar[str] = 'analyzehistogram'
required_args: 't.ClassVar[set[str]]' = {'expressions', 'this'}
class AnalyzeSample(sqlglot.expressions.core.Expression):
1917class AnalyzeSample(Expression):
1918    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key: ClassVar[str] = 'analyzesample'
required_args: 't.ClassVar[set[str]]' = {'kind', 'sample'}
class AnalyzeListChainedRows(sqlglot.expressions.core.Expression):
1921class AnalyzeListChainedRows(Expression):
1922    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):
1925class AnalyzeDelete(Expression):
1926    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):
1929class AnalyzeWith(Expression):
1930    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):
1933class AnalyzeValidate(Expression):
1934    arg_types = {
1935        "kind": True,
1936        "this": False,
1937        "expression": False,
1938    }
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):
1941class AnalyzeColumns(Expression):
1942    pass
key: ClassVar[str] = 'analyzecolumns'
required_args: 't.ClassVar[set[str]]' = {'this'}
class UsingData(sqlglot.expressions.core.Expression):
1945class UsingData(Expression):
1946    pass
key: ClassVar[str] = 'usingdata'
required_args: 't.ClassVar[set[str]]' = {'this'}
class AddPartition(sqlglot.expressions.core.Expression):
1949class AddPartition(Expression):
1950    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):
1953class AttachOption(Expression):
1954    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):
1957class DropPartition(Expression):
1958    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):
1961class ReplacePartition(Expression):
1962    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key: ClassVar[str] = 'replacepartition'
required_args: 't.ClassVar[set[str]]' = {'expression', 'source'}
class TranslateCharacters(sqlglot.expressions.core.Expression):
1965class TranslateCharacters(Expression):
1966    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):
1969class OverflowTruncateBehavior(Expression):
1970    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):
1973class JSON(Expression):
1974    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):
1977class JSONPath(Expression):
1978    arg_types = {"expressions": True}
1979
1980    @property
1981    def output_name(self) -> str:
1982        last_segment = self.expressions[-1].this
1983        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
1980    @property
1981    def output_name(self) -> str:
1982        last_segment = self.expressions[-1].this
1983        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):
1986class JSONPathPart(Expression):
1987    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'jsonpathpart'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathFilter(JSONPathPart):
1990class JSONPathFilter(JSONPathPart):
1991    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathfilter'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathKey(JSONPathPart):
1994class JSONPathKey(JSONPathPart):
1995    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):
1998class JSONPathRecursive(JSONPathPart):
1999    arg_types = {"this": False}
arg_types = {'this': False}
key: ClassVar[str] = 'jsonpathrecursive'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathRoot(JSONPathPart):
2002class JSONPathRoot(JSONPathPart):
2003    pass
key: ClassVar[str] = 'jsonpathroot'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathScript(JSONPathPart):
2006class JSONPathScript(JSONPathPart):
2007    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathscript'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathSlice(JSONPathPart):
2010class JSONPathSlice(JSONPathPart):
2011    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):
2014class JSONPathSelector(JSONPathPart):
2015    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathselector'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathSubscript(JSONPathPart):
2018class JSONPathSubscript(JSONPathPart):
2019    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathsubscript'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathUnion(JSONPathPart):
2022class JSONPathUnion(JSONPathPart):
2023    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'jsonpathunion'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class JSONPathWildcard(JSONPathPart):
2026class JSONPathWildcard(JSONPathPart):
2027    pass
key: ClassVar[str] = 'jsonpathwildcard'
required_args: 't.ClassVar[set[str]]' = set()
class FormatJson(sqlglot.expressions.core.Expression):
2030class FormatJson(Expression):
2031    pass
key: ClassVar[str] = 'formatjson'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONKeyValue(sqlglot.expressions.core.Expression):
2034class JSONKeyValue(Expression):
2035    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):
2038class JSONColumnDef(Expression):
2039    arg_types = {
2040        "this": False,
2041        "kind": False,
2042        "path": False,
2043        "nested_schema": False,
2044        "ordinality": False,
2045        "format_json": False,
2046    }
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):
2049class JSONSchema(Expression):
2050    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):
2053class JSONValue(Expression):
2054    arg_types = {
2055        "this": True,
2056        "path": True,
2057        "returning": False,
2058        "on_condition": False,
2059    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key: ClassVar[str] = 'jsonvalue'
required_args: 't.ClassVar[set[str]]' = {'path', 'this'}
2062class JSONValueArray(Expression, Func):
2063    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):
2066class OpenJSONColumnDef(Expression):
2067    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]]' = {'kind', 'this'}
class JSONExtractQuote(sqlglot.expressions.core.Expression):
2070class JSONExtractQuote(Expression):
2071    arg_types = {
2072        "option": True,
2073        "scalar": False,
2074    }
arg_types = {'option': True, 'scalar': False}
key: ClassVar[str] = 'jsonextractquote'
required_args: 't.ClassVar[set[str]]' = {'option'}
class ScopeResolution(sqlglot.expressions.core.Expression):
2077class ScopeResolution(Expression):
2078    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):
2081class Stream(Expression):
2082    pass
key: ClassVar[str] = 'stream'
required_args: 't.ClassVar[set[str]]' = {'this'}
class ModelAttribute(sqlglot.expressions.core.Expression):
2085class ModelAttribute(Expression):
2086    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):
2089class XMLNamespace(Expression):
2090    pass
key: ClassVar[str] = 'xmlnamespace'
required_args: 't.ClassVar[set[str]]' = {'this'}
class XMLKeyValueOption(sqlglot.expressions.core.Expression):
2093class XMLKeyValueOption(Expression):
2094    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):
2097class Semicolon(Expression):
2098    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'semicolon'
required_args: 't.ClassVar[set[str]]' = set()
class TableColumn(sqlglot.expressions.core.Expression):
2101class TableColumn(Expression):
2102    @property
2103    def output_name(self) -> str:
2104        return self.name
output_name: str
2102    @property
2103    def output_name(self) -> str:
2104        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):
2107class Variadic(Expression):
2108    pass
key: ClassVar[str] = 'variadic'
required_args: 't.ClassVar[set[str]]' = {'this'}
class StoredProcedure(sqlglot.expressions.core.Expression):
2111class StoredProcedure(Expression):
2112    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):
2115class Block(Expression):
2116    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):
2119class IfBlock(Expression):
2120    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 WhileBlock(sqlglot.expressions.core.Expression):
2123class WhileBlock(Expression):
2124    arg_types = {"this": True, "body": True}
arg_types = {'this': True, 'body': True}
key: ClassVar[str] = 'whileblock'
required_args: 't.ClassVar[set[str]]' = {'body', 'this'}
class EndStatement(sqlglot.expressions.core.Expression):
2127class EndStatement(Expression):
2128    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'endstatement'
required_args: 't.ClassVar[set[str]]' = set()
class FunctionSpecification(sqlglot.expressions.core.Expression):
2132class FunctionSpecification(Expression):
2133    arg_types = {
2134        "this": True,
2135        "characteristics": False,
2136        "properties": False,
2137        "expression": True,
2138    }
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:
2144def union(
2145    *expressions: ExpOrStr,
2146    distinct: bool = True,
2147    dialect: DialectType = None,
2148    copy: bool = True,
2149    **opts: Unpack[ParserNoDialectArgs],
2150) -> Union:
2151    """
2152    Initializes a syntax tree for the `UNION` operation.
2153
2154    Example:
2155        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
2156        'SELECT * FROM foo UNION SELECT * FROM bla'
2157
2158    Args:
2159        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
2160            If `Expr` instances are passed, they will be used as-is.
2161        distinct: set the DISTINCT flag if and only if this is true.
2162        dialect: the dialect used to parse the input expression.
2163        copy: whether to copy the expression.
2164        opts: other options to use to parse the input expressions.
2165
2166    Returns:
2167        The new Union instance.
2168    """
2169    assert len(expressions) >= 2, "At least two expressions are required by `union`."
2170    return _apply_set_operation(
2171        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
2172    )

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:
2175def intersect(
2176    *expressions: ExpOrStr,
2177    distinct: bool = True,
2178    dialect: DialectType = None,
2179    copy: bool = True,
2180    **opts: Unpack[ParserNoDialectArgs],
2181) -> Intersect:
2182    """
2183    Initializes a syntax tree for the `INTERSECT` operation.
2184
2185    Example:
2186        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
2187        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
2188
2189    Args:
2190        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
2191            If `Expr` instances are passed, they will be used as-is.
2192        distinct: set the DISTINCT flag if and only if this is true.
2193        dialect: the dialect used to parse the input expression.
2194        copy: whether to copy the expression.
2195        opts: other options to use to parse the input expressions.
2196
2197    Returns:
2198        The new Intersect instance.
2199    """
2200    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
2201    return _apply_set_operation(
2202        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
2203    )

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:
2206def except_(
2207    *expressions: ExpOrStr,
2208    distinct: bool = True,
2209    dialect: DialectType = None,
2210    copy: bool = True,
2211    **opts: Unpack[ParserNoDialectArgs],
2212) -> Except:
2213    """
2214    Initializes a syntax tree for the `EXCEPT` operation.
2215
2216    Example:
2217        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
2218        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
2219
2220    Args:
2221        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
2222            If `Expr` instances are passed, they will be used as-is.
2223        distinct: set the DISTINCT flag if and only if this is true.
2224        dialect: the dialect used to parse the input expression.
2225        copy: whether to copy the expression.
2226        opts: other options to use to parse the input expressions.
2227
2228    Returns:
2229        The new Except instance.
2230    """
2231    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
2232    return _apply_set_operation(
2233        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
2234    )

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.