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

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

def to_column(self, copy: bool = True) -> sqlglot.expressions.core.Expr:
1000    def to_column(self, copy: bool = True) -> Expr:
1001        parts = self.parts
1002        last_part = parts[-1]
1003
1004        if isinstance(last_part, Identifier):
1005            col: Expr = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
1006        else:
1007            # This branch will be reached if a function or array is wrapped in a `Table`
1008            col = last_part
1009
1010        alias = self.args.get("alias")
1011        if alias:
1012            col = alias_(col, alias.this, copy=copy)
1013
1014        return col
key: ClassVar[str] = 'table'
required_args: 't.ClassVar[set[str]]' = set()
class SetOperation(sqlglot.expressions.core.Expression, Query):
1017class SetOperation(Expression, Query):
1018    arg_types = {
1019        "with_": False,
1020        "this": True,
1021        "expression": True,
1022        "distinct": False,
1023        "by_name": False,
1024        "side": False,
1025        "kind": False,
1026        "on": False,
1027        **QUERY_MODIFIERS,
1028    }
1029
1030    def select(
1031        self: S,
1032        *expressions: ExpOrStr | None,
1033        append: bool = True,
1034        dialect: DialectType = None,
1035        copy: bool = True,
1036        **opts: Unpack[ParserNoDialectArgs],
1037    ) -> S:
1038        this = maybe_copy(self, copy)
1039        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1040        this.expression.unnest().select(
1041            *expressions, append=append, dialect=dialect, copy=False, **opts
1042        )
1043        return this
1044
1045    @property
1046    def named_selects(self) -> list[str]:
1047        expr: Expr = self
1048        while isinstance(expr, SetOperation):
1049            expr = expr.this.unnest()
1050        return _named_selects(expr)
1051
1052    @property
1053    def is_star(self) -> bool:
1054        return self.this.is_star or self.expression.is_star
1055
1056    @property
1057    def selects(self) -> list[Expr]:
1058        expr: Expr = self
1059        while isinstance(expr, SetOperation):
1060            expr = expr.this.unnest()
1061        return getattr(expr, "selects", [])
1062
1063    @property
1064    def left(self) -> Query:
1065        return self.this
1066
1067    @property
1068    def right(self) -> Query:
1069        return self.expression
1070
1071    @property
1072    def kind(self) -> str:
1073        return self.text("kind").upper()
1074
1075    @property
1076    def side(self) -> str:
1077        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}
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:
1030    def select(
1031        self: S,
1032        *expressions: ExpOrStr | None,
1033        append: bool = True,
1034        dialect: DialectType = None,
1035        copy: bool = True,
1036        **opts: Unpack[ParserNoDialectArgs],
1037    ) -> S:
1038        this = maybe_copy(self, copy)
1039        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1040        this.expression.unnest().select(
1041            *expressions, append=append, dialect=dialect, copy=False, **opts
1042        )
1043        return this
named_selects: list[str]
1045    @property
1046    def named_selects(self) -> list[str]:
1047        expr: Expr = self
1048        while isinstance(expr, SetOperation):
1049            expr = expr.this.unnest()
1050        return _named_selects(expr)
is_star: bool
1052    @property
1053    def is_star(self) -> bool:
1054        return self.this.is_star or self.expression.is_star

Checks whether an expression is a star.

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

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

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

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

Set the CLUSTER BY expression.

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

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

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

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

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

Checks whether an expression is a star.

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

Returns the first non subquery.

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

Checks whether an expression is a star.

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

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):
1743class Pivot(Expression):
1744    arg_types = {
1745        "this": False,
1746        "alias": False,
1747        "expressions": False,
1748        "fields": False,
1749        "unpivot": False,
1750        "using": False,
1751        "group": False,
1752        "columns": False,
1753        "include_nulls": False,
1754        "default_on_null": False,
1755        "into": False,
1756        "with_": False,
1757    }
1758
1759    @property
1760    def unpivot(self) -> bool:
1761        return bool(self.args.get("unpivot"))
1762
1763    @property
1764    def fields(self) -> list[Expr]:
1765        return self.args.get("fields", [])
1766
1767    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1768        """
1769        Returns an ordered map of post-rename output column name -> pre-rename
1770        source-side name, in the order the (UN)PIVOT produces them.
1771
1772        For callers that just want the names, iterate the dict (or call .keys()):
1773            >>> from sqlglot import parse_one, exp
1774            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1775            >>> list(piv.output_columns(["a", "b", "c"]))
1776            ['c', 'name', 'val']
1777
1778        AST shape:
1779            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1780                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1781                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1782                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1783
1784            UNPIVOT(val FOR name IN (a, b)):
1785                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1786                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1787                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1788                             are wrapped in PivotAlias(this=Column, alias=Literal).
1789
1790        Args:
1791            pre_pivot_columns: Columns visible to the operator before it runs
1792                (e.g. the source table or subquery's projections).
1793        """
1794        if self.unpivot:
1795            excluded: set[str] = set()
1796            name_columns: list[Identifier] = []
1797            for field in self.fields:
1798                if not isinstance(field, In):
1799                    continue
1800                if isinstance(field.this, Identifier):
1801                    name_columns.append(field.this)
1802                for e in field.expressions:
1803                    excluded.update(c.output_name for c in e.find_all(Column))
1804            value_columns = [
1805                ident
1806                for e in self.expressions
1807                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1808                if isinstance(ident, Identifier)
1809            ]
1810            outputs = [i.name for i in name_columns + value_columns]
1811        else:
1812            excluded = {c.output_name for c in self.find_all(Column)}
1813            outputs = [c.output_name for c in self.args.get("columns") or []]
1814            if not outputs:
1815                outputs = [c.alias_or_name for c in self.expressions]
1816
1817        if not excluded or not outputs:
1818            return {}
1819
1820        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1821
1822        alias = self.args.get("alias")
1823        renames = alias.args.get("columns") if alias else None
1824
1825        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1826        # positionally from the front (DuckDB, Snowflake): the user's names cover
1827        # the leading N output columns, remaining columns keep their auto names.
1828        if renames:
1829            rename_names = [r.name for r in renames]
1830            post_rename = rename_names + pre_rename[len(rename_names) :]
1831        else:
1832            post_rename = pre_rename
1833
1834        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}
unpivot: bool
1759    @property
1760    def unpivot(self) -> bool:
1761        return bool(self.args.get("unpivot"))
fields: list[sqlglot.expressions.core.Expr]
1763    @property
1764    def fields(self) -> list[Expr]:
1765        return self.args.get("fields", [])
def output_columns(self, pre_pivot_columns: Iterable[str]) -> dict[str, str]:
1767    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1768        """
1769        Returns an ordered map of post-rename output column name -> pre-rename
1770        source-side name, in the order the (UN)PIVOT produces them.
1771
1772        For callers that just want the names, iterate the dict (or call .keys()):
1773            >>> from sqlglot import parse_one, exp
1774            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1775            >>> list(piv.output_columns(["a", "b", "c"]))
1776            ['c', 'name', 'val']
1777
1778        AST shape:
1779            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1780                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1781                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1782                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1783
1784            UNPIVOT(val FOR name IN (a, b)):
1785                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1786                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1787                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1788                             are wrapped in PivotAlias(this=Column, alias=Literal).
1789
1790        Args:
1791            pre_pivot_columns: Columns visible to the operator before it runs
1792                (e.g. the source table or subquery's projections).
1793        """
1794        if self.unpivot:
1795            excluded: set[str] = set()
1796            name_columns: list[Identifier] = []
1797            for field in self.fields:
1798                if not isinstance(field, In):
1799                    continue
1800                if isinstance(field.this, Identifier):
1801                    name_columns.append(field.this)
1802                for e in field.expressions:
1803                    excluded.update(c.output_name for c in e.find_all(Column))
1804            value_columns = [
1805                ident
1806                for e in self.expressions
1807                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1808                if isinstance(ident, Identifier)
1809            ]
1810            outputs = [i.name for i in name_columns + value_columns]
1811        else:
1812            excluded = {c.output_name for c in self.find_all(Column)}
1813            outputs = [c.output_name for c in self.args.get("columns") or []]
1814            if not outputs:
1815                outputs = [c.alias_or_name for c in self.expressions]
1816
1817        if not excluded or not outputs:
1818            return {}
1819
1820        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1821
1822        alias = self.args.get("alias")
1823        renames = alias.args.get("columns") if alias else None
1824
1825        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1826        # positionally from the front (DuckDB, Snowflake): the user's names cover
1827        # the leading N output columns, remaining columns keep their auto names.
1828        if renames:
1829            rename_names = [r.name for r in renames]
1830            post_rename = rename_names + pre_rename[len(rename_names) :]
1831        else:
1832            post_rename = pre_rename
1833
1834        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):
1837class UnpivotColumns(Expression):
1838    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key: ClassVar[str] = 'unpivotcolumns'
required_args: 't.ClassVar[set[str]]' = {'this', 'expressions'}
1841class Window(Expression, Condition):
1842    arg_types = {
1843        "this": True,
1844        "partition_by": False,
1845        "order": False,
1846        "spec": False,
1847        "alias": False,
1848        "over": False,
1849        "first": False,
1850    }
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):
1853class WindowSpec(Expression):
1854    arg_types = {
1855        "kind": False,
1856        "start": False,
1857        "start_side": False,
1858        "end": False,
1859        "end_side": False,
1860        "exclude": False,
1861    }
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):
1864class PreWhere(Expression):
1865    pass
key: ClassVar[str] = 'prewhere'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Where(sqlglot.expressions.core.Expression):
1868class Where(Expression):
1869    pass
key: ClassVar[str] = 'where'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Analyze(sqlglot.expressions.core.Expression):
1872class Analyze(Expression):
1873    arg_types = {
1874        "kind": False,
1875        "this": False,
1876        "options": False,
1877        "mode": False,
1878        "partition": False,
1879        "expression": False,
1880        "properties": False,
1881    }
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):
1884class AnalyzeStatistics(Expression):
1885    arg_types = {
1886        "kind": True,
1887        "option": False,
1888        "this": False,
1889        "expressions": False,
1890    }
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):
1893class AnalyzeHistogram(Expression):
1894    arg_types = {
1895        "this": True,
1896        "expressions": True,
1897        "expression": False,
1898        "update_options": False,
1899    }
arg_types = {'this': True, 'expressions': True, 'expression': False, 'update_options': False}
key: ClassVar[str] = 'analyzehistogram'
required_args: 't.ClassVar[set[str]]' = {'this', 'expressions'}
class AnalyzeSample(sqlglot.expressions.core.Expression):
1902class AnalyzeSample(Expression):
1903    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key: ClassVar[str] = 'analyzesample'
required_args: 't.ClassVar[set[str]]' = {'sample', 'kind'}
class AnalyzeListChainedRows(sqlglot.expressions.core.Expression):
1906class AnalyzeListChainedRows(Expression):
1907    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):
1910class AnalyzeDelete(Expression):
1911    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):
1914class AnalyzeWith(Expression):
1915    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):
1918class AnalyzeValidate(Expression):
1919    arg_types = {
1920        "kind": True,
1921        "this": False,
1922        "expression": False,
1923    }
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):
1926class AnalyzeColumns(Expression):
1927    pass
key: ClassVar[str] = 'analyzecolumns'
required_args: 't.ClassVar[set[str]]' = {'this'}
class UsingData(sqlglot.expressions.core.Expression):
1930class UsingData(Expression):
1931    pass
key: ClassVar[str] = 'usingdata'
required_args: 't.ClassVar[set[str]]' = {'this'}
class AddPartition(sqlglot.expressions.core.Expression):
1934class AddPartition(Expression):
1935    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):
1938class AttachOption(Expression):
1939    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):
1942class DropPartition(Expression):
1943    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):
1946class ReplacePartition(Expression):
1947    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):
1950class TranslateCharacters(Expression):
1951    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):
1954class OverflowTruncateBehavior(Expression):
1955    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):
1958class JSON(Expression):
1959    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):
1962class JSONPath(Expression):
1963    arg_types = {"expressions": True, "escape": False}
1964
1965    @property
1966    def output_name(self) -> str:
1967        last_segment = self.expressions[-1].this
1968        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True, 'escape': False}
output_name: str
1965    @property
1966    def output_name(self) -> str:
1967        last_segment = self.expressions[-1].this
1968        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):
1971class JSONPathPart(Expression):
1972    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'jsonpathpart'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathFilter(JSONPathPart):
1975class JSONPathFilter(JSONPathPart):
1976    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathfilter'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathKey(JSONPathPart):
1979class JSONPathKey(JSONPathPart):
1980    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathkey'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathRecursive(JSONPathPart):
1983class JSONPathRecursive(JSONPathPart):
1984    arg_types = {"this": False}
arg_types = {'this': False}
key: ClassVar[str] = 'jsonpathrecursive'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathRoot(JSONPathPart):
1987class JSONPathRoot(JSONPathPart):
1988    pass
key: ClassVar[str] = 'jsonpathroot'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathScript(JSONPathPart):
1991class JSONPathScript(JSONPathPart):
1992    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathscript'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathSlice(JSONPathPart):
1995class JSONPathSlice(JSONPathPart):
1996    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):
1999class JSONPathSelector(JSONPathPart):
2000    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathselector'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathSubscript(JSONPathPart):
2003class JSONPathSubscript(JSONPathPart):
2004    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathsubscript'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathUnion(JSONPathPart):
2007class JSONPathUnion(JSONPathPart):
2008    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'jsonpathunion'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class JSONPathWildcard(JSONPathPart):
2011class JSONPathWildcard(JSONPathPart):
2012    pass
key: ClassVar[str] = 'jsonpathwildcard'
required_args: 't.ClassVar[set[str]]' = set()
class FormatJson(sqlglot.expressions.core.Expression):
2015class FormatJson(Expression):
2016    pass
key: ClassVar[str] = 'formatjson'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONKeyValue(sqlglot.expressions.core.Expression):
2019class JSONKeyValue(Expression):
2020    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):
2023class JSONColumnDef(Expression):
2024    arg_types = {
2025        "this": False,
2026        "kind": False,
2027        "path": False,
2028        "nested_schema": False,
2029        "ordinality": False,
2030        "format_json": False,
2031    }
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):
2034class JSONSchema(Expression):
2035    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):
2038class JSONValue(Expression):
2039    arg_types = {
2040        "this": True,
2041        "path": True,
2042        "returning": False,
2043        "on_condition": False,
2044    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key: ClassVar[str] = 'jsonvalue'
required_args: 't.ClassVar[set[str]]' = {'path', 'this'}
2047class JSONValueArray(Expression, Func):
2048    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):
2051class OpenJSONColumnDef(Expression):
2052    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):
2055class JSONExtractQuote(Expression):
2056    arg_types = {
2057        "option": True,
2058        "scalar": False,
2059    }
arg_types = {'option': True, 'scalar': False}
key: ClassVar[str] = 'jsonextractquote'
required_args: 't.ClassVar[set[str]]' = {'option'}
class ScopeResolution(sqlglot.expressions.core.Expression):
2062class ScopeResolution(Expression):
2063    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):
2066class Stream(Expression):
2067    pass
key: ClassVar[str] = 'stream'
required_args: 't.ClassVar[set[str]]' = {'this'}
class ModelAttribute(sqlglot.expressions.core.Expression):
2070class ModelAttribute(Expression):
2071    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):
2074class XMLNamespace(Expression):
2075    pass
key: ClassVar[str] = 'xmlnamespace'
required_args: 't.ClassVar[set[str]]' = {'this'}
class XMLKeyValueOption(sqlglot.expressions.core.Expression):
2078class XMLKeyValueOption(Expression):
2079    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):
2082class Semicolon(Expression):
2083    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'semicolon'
required_args: 't.ClassVar[set[str]]' = set()
class TableColumn(sqlglot.expressions.core.Expression):
2086class TableColumn(Expression):
2087    @property
2088    def output_name(self) -> str:
2089        return self.name
output_name: str
2087    @property
2088    def output_name(self) -> str:
2089        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):
2092class Variadic(Expression):
2093    pass
key: ClassVar[str] = 'variadic'
required_args: 't.ClassVar[set[str]]' = {'this'}
class StoredProcedure(sqlglot.expressions.core.Expression):
2096class StoredProcedure(Expression):
2097    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):
2100class Block(Expression):
2101    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'block'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class IfBlock(sqlglot.expressions.core.Expression):
2104class IfBlock(Expression):
2105    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):
2108class WhileBlock(Expression):
2109    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):
2112class EndStatement(Expression):
2113    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'endstatement'
required_args: 't.ClassVar[set[str]]' = set()
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:
2119def union(
2120    *expressions: ExpOrStr,
2121    distinct: bool = True,
2122    dialect: DialectType = None,
2123    copy: bool = True,
2124    **opts: Unpack[ParserNoDialectArgs],
2125) -> Union:
2126    """
2127    Initializes a syntax tree for the `UNION` operation.
2128
2129    Example:
2130        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
2131        'SELECT * FROM foo UNION SELECT * FROM bla'
2132
2133    Args:
2134        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
2135            If `Expr` instances are passed, they will be used as-is.
2136        distinct: set the DISTINCT flag if and only if this is true.
2137        dialect: the dialect used to parse the input expression.
2138        copy: whether to copy the expression.
2139        opts: other options to use to parse the input expressions.
2140
2141    Returns:
2142        The new Union instance.
2143    """
2144    assert len(expressions) >= 2, "At least two expressions are required by `union`."
2145    return _apply_set_operation(
2146        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
2147    )

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:
2150def intersect(
2151    *expressions: ExpOrStr,
2152    distinct: bool = True,
2153    dialect: DialectType = None,
2154    copy: bool = True,
2155    **opts: Unpack[ParserNoDialectArgs],
2156) -> Intersect:
2157    """
2158    Initializes a syntax tree for the `INTERSECT` operation.
2159
2160    Example:
2161        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
2162        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
2163
2164    Args:
2165        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
2166            If `Expr` instances are passed, they will be used as-is.
2167        distinct: set the DISTINCT flag if and only if this is true.
2168        dialect: the dialect used to parse the input expression.
2169        copy: whether to copy the expression.
2170        opts: other options to use to parse the input expressions.
2171
2172    Returns:
2173        The new Intersect instance.
2174    """
2175    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
2176    return _apply_set_operation(
2177        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
2178    )

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

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.