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

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

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

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

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

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

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

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:
355    def union(
356        self,
357        *expressions: ExpOrStr,
358        distinct: bool = True,
359        dialect: DialectType = None,
360        copy: bool = True,
361        **opts: Unpack[ParserNoDialectArgs],
362    ) -> Union:
363        """
364        Builds a UNION expression.
365
366        Example:
367            >>> import sqlglot
368            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
369            'SELECT * FROM foo UNION SELECT * FROM bla'
370
371        Args:
372            expressions: the SQL code strings.
373                If `Expr` instances are passed, they will be used as-is.
374            distinct: set the DISTINCT flag if and only if this is true.
375            dialect: the dialect used to parse the input expression.
376            opts: other options to use to parse the input expressions.
377
378        Returns:
379            The new Union expression.
380        """
381        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:
383    def intersect(
384        self,
385        *expressions: ExpOrStr,
386        distinct: bool = True,
387        dialect: DialectType = None,
388        copy: bool = True,
389        **opts: Unpack[ParserNoDialectArgs],
390    ) -> Intersect:
391        """
392        Builds an INTERSECT expression.
393
394        Example:
395            >>> import sqlglot
396            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
397            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
398
399        Args:
400            expressions: the SQL code strings.
401                If `Expr` instances are passed, they will be used as-is.
402            distinct: set the DISTINCT flag if and only if this is true.
403            dialect: the dialect used to parse the input expression.
404            opts: other options to use to parse the input expressions.
405
406        Returns:
407            The new Intersect expression.
408        """
409        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:
411    def except_(
412        self,
413        *expressions: ExpOrStr,
414        distinct: bool = True,
415        dialect: DialectType = None,
416        copy: bool = True,
417        **opts: Unpack[ParserNoDialectArgs],
418    ) -> Except:
419        """
420        Builds an EXCEPT expression.
421
422        Example:
423            >>> import sqlglot
424            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
425            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
426
427        Args:
428            expressions: the SQL code strings.
429                If `Expr` instance are passed, they will be used as-is.
430            distinct: set the DISTINCT flag if and only if this is true.
431            dialect: the dialect used to parse the input expression.
432            opts: other options to use to parse the input expressions.
433
434        Returns:
435            The new Except expression.
436        """
437        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):
440class QueryBand(Expression):
441    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):
444class RecursiveWithSearch(Expression):
445    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]]' = {'this', 'expression', 'kind'}
class With(sqlglot.expressions.core.Expression):
448class With(Expression):
449    arg_types = {"expressions": False, "recursive": False, "search": False, "udfs": False}
450
451    @property
452    def recursive(self) -> bool:
453        return bool(self.args.get("recursive"))
arg_types = {'expressions': False, 'recursive': False, 'search': False, 'udfs': False}
recursive: bool
451    @property
452    def recursive(self) -> bool:
453        return bool(self.args.get("recursive"))
key: ClassVar[str] = 'with'
required_args: 't.ClassVar[set[str]]' = set()
456class CTE(Expression, DerivedTable):
457    arg_types = {
458        "this": True,
459        "alias": True,
460        "scalar": False,
461        "materialized": False,
462        "key_expressions": False,
463    }
arg_types = {'this': True, 'alias': True, 'scalar': False, 'materialized': False, 'key_expressions': False}
key: ClassVar[str] = 'cte'
required_args: 't.ClassVar[set[str]]' = {'this', 'alias'}
class ProjectionDef(sqlglot.expressions.core.Expression):
466class ProjectionDef(Expression):
467    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key: ClassVar[str] = 'projectiondef'
required_args: 't.ClassVar[set[str]]' = {'this', 'expression'}
class TableAlias(sqlglot.expressions.core.Expression):
470class TableAlias(Expression):
471    arg_types = {"this": False, "columns": False}
472
473    @property
474    def columns(self) -> list[t.Any]:
475        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns: list[typing.Any]
473    @property
474    def columns(self) -> list[t.Any]:
475        return self.args.get("columns") or []
key: ClassVar[str] = 'tablealias'
required_args: 't.ClassVar[set[str]]' = set()
478class BitString(Expression, Condition):
479    is_primitive = True
is_primitive = True
key: ClassVar[str] = 'bitstring'
required_args: 't.ClassVar[set[str]]' = {'this'}
482class HexString(Expression, Condition):
483    arg_types = {"this": True, "is_integer": False}
484    is_primitive = True
arg_types = {'this': True, 'is_integer': False}
is_primitive = True
key: ClassVar[str] = 'hexstring'
required_args: 't.ClassVar[set[str]]' = {'this'}
487class ByteString(Expression, Condition):
488    arg_types = {"this": True, "is_bytes": False}
489    is_primitive = True
arg_types = {'this': True, 'is_bytes': False}
is_primitive = True
key: ClassVar[str] = 'bytestring'
required_args: 't.ClassVar[set[str]]' = {'this'}
492class RawString(Expression, Condition):
493    is_primitive = True
is_primitive = True
key: ClassVar[str] = 'rawstring'
required_args: 't.ClassVar[set[str]]' = {'this'}
496class UnicodeString(Expression, Condition):
497    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):
500class ColumnPosition(Expression):
501    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):
504class ColumnDef(Expression):
505    arg_types = {
506        "this": True,
507        "kind": False,
508        "constraints": False,
509        "exists": False,
510        "position": False,
511        "default": False,
512        "output": False,
513    }
514
515    @property
516    def constraints(self) -> list[ColumnConstraint]:
517        return self.args.get("constraints") or []
518
519    @property
520    def kind(self) -> DataType | None:
521        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]
515    @property
516    def constraints(self) -> list[ColumnConstraint]:
517        return self.args.get("constraints") or []
kind: sqlglot.expressions.datatypes.DataType | None
519    @property
520    def kind(self) -> DataType | None:
521        return self.args.get("kind")
key: ClassVar[str] = 'columndef'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Changes(sqlglot.expressions.core.Expression):
524class Changes(Expression):
525    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):
528class Connect(Expression):
529    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):
532class Prior(Expression):
533    pass
key: ClassVar[str] = 'prior'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Into(sqlglot.expressions.core.Expression):
536class Into(Expression):
537    arg_types = {
538        "this": False,
539        "temporary": False,
540        "unlogged": False,
541        "bulk_collect": False,
542        "expressions": False,
543    }
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):
546class From(Expression):
547    @property
548    def name(self) -> str:
549        return self.this.name
550
551    @property
552    def alias_or_name(self) -> str:
553        return self.this.alias_or_name
name: str
547    @property
548    def name(self) -> str:
549        return self.this.name
alias_or_name: str
551    @property
552    def alias_or_name(self) -> str:
553        return self.this.alias_or_name
key: ClassVar[str] = 'from'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Having(sqlglot.expressions.core.Expression):
556class Having(Expression):
557    pass
key: ClassVar[str] = 'having'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Index(sqlglot.expressions.core.Expression):
560class Index(Expression):
561    arg_types = {
562        "this": False,
563        "table": False,
564        "unique": False,
565        "primary": False,
566        "amp": False,  # teradata
567        "params": False,
568    }
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):
571class ConditionalInsert(Expression):
572    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):
575class MultitableInserts(Expression):
576    arg_types = {"expressions": True, "kind": True, "source": True}
arg_types = {'expressions': True, 'kind': True, 'source': True}
key: ClassVar[str] = 'multitableinserts'
required_args: 't.ClassVar[set[str]]' = {'source', 'kind', 'expressions'}
class OnCondition(sqlglot.expressions.core.Expression):
579class OnCondition(Expression):
580    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):
583class Introducer(Expression):
584    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key: ClassVar[str] = 'introducer'
required_args: 't.ClassVar[set[str]]' = {'this', 'expression'}
class National(sqlglot.expressions.core.Expression):
587class National(Expression):
588    is_primitive = True
is_primitive = True
key: ClassVar[str] = 'national'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Partition(sqlglot.expressions.core.Expression):
591class Partition(Expression):
592    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):
595class PartitionRange(Expression):
596    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):
599class PartitionId(Expression):
600    pass
key: ClassVar[str] = 'partitionid'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Fetch(sqlglot.expressions.core.Expression):
603class Fetch(Expression):
604    arg_types = {
605        "direction": False,
606        "count": False,
607        "limit_options": False,
608    }
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):
611class Grant(Expression):
612    arg_types = {
613        "privileges": True,
614        "kind": False,
615        "securable": True,
616        "principals": True,
617        "grant_option": False,
618    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key: ClassVar[str] = 'grant'
required_args: 't.ClassVar[set[str]]' = {'principals', 'securable', 'privileges'}
class Revoke(sqlglot.expressions.core.Expression):
621class Revoke(Expression):
622    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]]' = {'principals', 'securable', 'privileges'}
class Group(sqlglot.expressions.core.Expression):
625class Group(Expression):
626    arg_types = {
627        "expressions": False,
628        "grouping_sets": False,
629        "cube": False,
630        "rollup": False,
631        "totals": False,
632        "all": False,
633    }
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):
636class Cube(Expression):
637    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key: ClassVar[str] = 'cube'
required_args: 't.ClassVar[set[str]]' = set()
class Rollup(sqlglot.expressions.core.Expression):
640class Rollup(Expression):
641    arg_types = {"expressions": False}
arg_types = {'expressions': False}
key: ClassVar[str] = 'rollup'
required_args: 't.ClassVar[set[str]]' = set()
class GroupingSets(sqlglot.expressions.core.Expression):
644class GroupingSets(Expression):
645    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'groupingsets'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Lambda(sqlglot.expressions.core.Expression):
648class Lambda(Expression):
649    arg_types = {"this": True, "expressions": True, "colon": False}
arg_types = {'this': True, 'expressions': True, 'colon': False}
key: ClassVar[str] = 'lambda'
required_args: 't.ClassVar[set[str]]' = {'this', 'expressions'}
class Limit(sqlglot.expressions.core.Expression):
652class Limit(Expression):
653    arg_types = {
654        "this": False,
655        "expression": True,
656        "offset": False,
657        "limit_options": False,
658        "expressions": False,
659    }
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
key: ClassVar[str] = 'limit'
required_args: 't.ClassVar[set[str]]' = {'expression'}
class LimitOptions(sqlglot.expressions.core.Expression):
662class LimitOptions(Expression):
663    arg_types = {
664        "percent": False,
665        "rows": False,
666        "with_ties": False,
667    }
arg_types = {'percent': False, 'rows': False, 'with_ties': False}
key: ClassVar[str] = 'limitoptions'
required_args: 't.ClassVar[set[str]]' = set()
class Join(sqlglot.expressions.core.Expression):
670class Join(Expression):
671    arg_types = {
672        "this": True,
673        "on": False,
674        "side": False,
675        "kind": False,
676        "using": False,
677        "method": False,
678        "global_": False,
679        "hint": False,
680        "match_condition": False,  # Snowflake
681        "directed": False,  # Snowflake
682        "expressions": False,
683        "pivots": False,
684    }
685
686    @property
687    def method(self) -> str:
688        return self.text("method").upper()
689
690    @property
691    def kind(self) -> str:
692        return self.text("kind").upper()
693
694    @property
695    def side(self) -> str:
696        return self.text("side").upper()
697
698    @property
699    def hint(self) -> str:
700        return self.text("hint").upper()
701
702    @property
703    def alias_or_name(self) -> str:
704        return self.this.alias_or_name
705
706    @property
707    def is_semi_or_anti_join(self) -> bool:
708        return self.kind in ("SEMI", "ANTI")
709
710    def on(
711        self,
712        *expressions: ExpOrStr | None,
713        append: bool = True,
714        dialect: DialectType = None,
715        copy: bool = True,
716        **opts: Unpack[ParserNoDialectArgs],
717    ) -> Join:
718        """
719        Append to or set the ON expressions.
720
721        Example:
722            >>> import sqlglot
723            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
724            'JOIN x ON y = 1'
725
726        Args:
727            *expressions: the SQL code strings to parse.
728                If an `Expr` instance is passed, it will be used as-is.
729                Multiple expressions are combined with an AND operator.
730            append: if `True`, AND the new expressions to any existing expression.
731                Otherwise, this resets the expression.
732            dialect: the dialect used to parse the input expressions.
733            copy: if `False`, modify this expression instance in-place.
734            opts: other options to use to parse the input expressions.
735
736        Returns:
737            The modified Join expression.
738        """
739        join = _apply_conjunction_builder(
740            *expressions,
741            instance=self,
742            arg="on",
743            append=append,
744            dialect=dialect,
745            copy=copy,
746            **opts,
747        )
748
749        if join.kind == "CROSS":
750            join.set("kind", None)
751
752        return join
753
754    def using(
755        self,
756        *expressions: ExpOrStr | None,
757        append: bool = True,
758        dialect: DialectType = None,
759        copy: bool = True,
760        **opts: Unpack[ParserNoDialectArgs],
761    ) -> Join:
762        """
763        Append to or set the USING expressions.
764
765        Example:
766            >>> import sqlglot
767            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
768            'JOIN x USING (foo, bla)'
769
770        Args:
771            *expressions: the SQL code strings to parse.
772                If an `Expr` instance is passed, it will be used as-is.
773            append: if `True`, concatenate the new expressions to the existing "using" list.
774                Otherwise, this resets the expression.
775            dialect: the dialect used to parse the input expressions.
776            copy: if `False`, modify this expression instance in-place.
777            opts: other options to use to parse the input expressions.
778
779        Returns:
780            The modified Join expression.
781        """
782        join = _apply_list_builder(
783            *expressions,
784            instance=self,
785            arg="using",
786            append=append,
787            dialect=dialect,
788            copy=copy,
789            **opts,
790        )
791
792        if join.kind == "CROSS":
793            join.set("kind", None)
794
795        return join
arg_types = {'this': True, 'on': False, 'side': False, 'kind': False, 'using': False, 'method': False, 'global_': False, 'hint': False, 'match_condition': False, 'directed': False, 'expressions': False, 'pivots': False}
method: str
686    @property
687    def method(self) -> str:
688        return self.text("method").upper()
kind: str
690    @property
691    def kind(self) -> str:
692        return self.text("kind").upper()
side: str
694    @property
695    def side(self) -> str:
696        return self.text("side").upper()
hint: str
698    @property
699    def hint(self) -> str:
700        return self.text("hint").upper()
alias_or_name: str
702    @property
703    def alias_or_name(self) -> str:
704        return self.this.alias_or_name
is_semi_or_anti_join: bool
706    @property
707    def is_semi_or_anti_join(self) -> bool:
708        return self.kind in ("SEMI", "ANTI")
def on( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Join:
710    def on(
711        self,
712        *expressions: ExpOrStr | None,
713        append: bool = True,
714        dialect: DialectType = None,
715        copy: bool = True,
716        **opts: Unpack[ParserNoDialectArgs],
717    ) -> Join:
718        """
719        Append to or set the ON expressions.
720
721        Example:
722            >>> import sqlglot
723            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
724            'JOIN x ON y = 1'
725
726        Args:
727            *expressions: the SQL code strings to parse.
728                If an `Expr` instance is passed, it will be used as-is.
729                Multiple expressions are combined with an AND operator.
730            append: if `True`, AND the new expressions to any existing expression.
731                Otherwise, this resets the expression.
732            dialect: the dialect used to parse the input expressions.
733            copy: if `False`, modify this expression instance in-place.
734            opts: other options to use to parse the input expressions.
735
736        Returns:
737            The modified Join expression.
738        """
739        join = _apply_conjunction_builder(
740            *expressions,
741            instance=self,
742            arg="on",
743            append=append,
744            dialect=dialect,
745            copy=copy,
746            **opts,
747        )
748
749        if join.kind == "CROSS":
750            join.set("kind", None)
751
752        return join

Append to or set the ON expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
'JOIN x ON y = 1'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expr instance is passed, it will be used as-is. Multiple expressions are combined with an AND operator.
  • append: if True, AND the new expressions to any existing expression. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

def using( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Join:
754    def using(
755        self,
756        *expressions: ExpOrStr | None,
757        append: bool = True,
758        dialect: DialectType = None,
759        copy: bool = True,
760        **opts: Unpack[ParserNoDialectArgs],
761    ) -> Join:
762        """
763        Append to or set the USING expressions.
764
765        Example:
766            >>> import sqlglot
767            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
768            'JOIN x USING (foo, bla)'
769
770        Args:
771            *expressions: the SQL code strings to parse.
772                If an `Expr` instance is passed, it will be used as-is.
773            append: if `True`, concatenate the new expressions to the existing "using" list.
774                Otherwise, this resets the expression.
775            dialect: the dialect used to parse the input expressions.
776            copy: if `False`, modify this expression instance in-place.
777            opts: other options to use to parse the input expressions.
778
779        Returns:
780            The modified Join expression.
781        """
782        join = _apply_list_builder(
783            *expressions,
784            instance=self,
785            arg="using",
786            append=append,
787            dialect=dialect,
788            copy=copy,
789            **opts,
790        )
791
792        if join.kind == "CROSS":
793            join.set("kind", None)
794
795        return join

Append to or set the USING expressions.

Example:
>>> import sqlglot
>>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
'JOIN x USING (foo, bla)'
Arguments:
  • *expressions: the SQL code strings to parse. If an Expr instance is passed, it will be used as-is.
  • append: if True, concatenate the new expressions to the existing "using" list. Otherwise, this resets the expression.
  • dialect: the dialect used to parse the input expressions.
  • copy: if False, modify this expression instance in-place.
  • opts: other options to use to parse the input expressions.
Returns:

The modified Join expression.

key: ClassVar[str] = 'join'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Lateral(sqlglot.expressions.core.Expression, UDTF):
798class Lateral(Expression, UDTF):
799    arg_types = {
800        "this": True,
801        "view": False,
802        "outer": False,
803        "alias": False,
804        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
805        "ordinality": False,
806    }
807
808    @property
809    def selects(self) -> list[Expr]:
810        from sqlglot.expressions.array import Unnest
811
812        columns = super().selects
813
814        # UNNEST ... WITH ORDINALITY stores the ordinality column's name in Unnest.offset
815        offset = self.this.args.get("offset") if isinstance(self.this, Unnest) else None
816        if isinstance(offset, Identifier):
817            columns = columns + [offset]
818
819        return columns
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
selects: list[sqlglot.expressions.core.Expr]
808    @property
809    def selects(self) -> list[Expr]:
810        from sqlglot.expressions.array import Unnest
811
812        columns = super().selects
813
814        # UNNEST ... WITH ORDINALITY stores the ordinality column's name in Unnest.offset
815        offset = self.this.args.get("offset") if isinstance(self.this, Unnest) else None
816        if isinstance(offset, Identifier):
817            columns = columns + [offset]
818
819        return columns
key: ClassVar[str] = 'lateral'
required_args: 't.ClassVar[set[str]]' = {'this'}
class TableFromRows(sqlglot.expressions.core.Expression, UDTF):
822class TableFromRows(Expression, UDTF):
823    arg_types = {
824        "this": True,
825        "alias": False,
826        "joins": False,
827        "pivots": False,
828        "sample": False,
829    }
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):
832class MatchRecognizeMeasure(Expression):
833    arg_types = {
834        "this": True,
835        "window_frame": False,
836    }
arg_types = {'this': True, 'window_frame': False}
key: ClassVar[str] = 'matchrecognizemeasure'
required_args: 't.ClassVar[set[str]]' = {'this'}
class MatchRecognize(sqlglot.expressions.core.Expression):
839class MatchRecognize(Expression):
840    arg_types = {
841        "partition_by": False,
842        "order": False,
843        "measures": False,
844        "rows": False,
845        "after": False,
846        "pattern": False,
847        "define": False,
848        "alias": False,
849    }
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):
852class Final(Expression):
853    pass
key: ClassVar[str] = 'final'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Offset(sqlglot.expressions.core.Expression):
856class Offset(Expression):
857    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):
860class Order(Expression):
861    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):
864class WithFill(Expression):
865    arg_types = {
866        "from_": False,
867        "to": False,
868        "step": False,
869        "interpolate": False,
870    }
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):
873class SkipJSONColumn(Expression):
874    arg_types = {"regexp": False, "expression": True}
arg_types = {'regexp': False, 'expression': True}
key: ClassVar[str] = 'skipjsoncolumn'
required_args: 't.ClassVar[set[str]]' = {'expression'}
class Cluster(sqlglot.expressions.core.Expression):
877class Cluster(Expression):
878    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'cluster'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Distribute(Order):
881class Distribute(Order):
882    pass
key: ClassVar[str] = 'distribute'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Sort(Order):
885class Sort(Order):
886    pass
key: ClassVar[str] = 'sort'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Qualify(sqlglot.expressions.core.Expression):
889class Qualify(Expression):
890    pass
key: ClassVar[str] = 'qualify'
required_args: 't.ClassVar[set[str]]' = {'this'}
class InputOutputFormat(sqlglot.expressions.core.Expression):
893class InputOutputFormat(Expression):
894    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):
897class Return(Expression):
898    pass
key: ClassVar[str] = 'return'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Tuple(sqlglot.expressions.core.Expression):
901class Tuple(Expression):
902    arg_types = {"expressions": False}
903
904    def isin(
905        self,
906        *expressions: t.Any,
907        query: ExpOrStr | None = None,
908        unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None,
909        copy: bool = True,
910        **opts: Unpack[ParserArgs],
911    ) -> In:
912        return In(
913            this=maybe_copy(self, copy),
914            expressions=[convert(e, copy=copy) for e in expressions],
915            query=maybe_parse(query, copy=copy, **opts) if query else None,
916            unnest=(
917                Unnest(
918                    expressions=[
919                        maybe_parse(e, copy=copy, **opts)
920                        for e in t.cast(list[ExpOrStr], ensure_list(unnest))
921                    ]
922                )
923                if unnest
924                else None
925            ),
926        )
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:
904    def isin(
905        self,
906        *expressions: t.Any,
907        query: ExpOrStr | None = None,
908        unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None,
909        copy: bool = True,
910        **opts: Unpack[ParserArgs],
911    ) -> In:
912        return In(
913            this=maybe_copy(self, copy),
914            expressions=[convert(e, copy=copy) for e in expressions],
915            query=maybe_parse(query, copy=copy, **opts) if query else None,
916            unnest=(
917                Unnest(
918                    expressions=[
919                        maybe_parse(e, copy=copy, **opts)
920                        for e in t.cast(list[ExpOrStr], ensure_list(unnest))
921                    ]
922                )
923                if unnest
924                else None
925            ),
926        )
key: ClassVar[str] = 'tuple'
required_args: 't.ClassVar[set[str]]' = set()
class QueryOption(sqlglot.expressions.core.Expression):
929class QueryOption(Expression):
930    arg_types = {"this": True, "expression": False}
arg_types = {'this': True, 'expression': False}
key: ClassVar[str] = 'queryoption'
required_args: 't.ClassVar[set[str]]' = {'this'}
class ForClause(sqlglot.expressions.core.Expression):
934class ForClause(Expression):
935    arg_types = {"kind": True, "expressions": False}
arg_types = {'kind': True, 'expressions': False}
key: ClassVar[str] = 'forclause'
required_args: 't.ClassVar[set[str]]' = {'kind'}
class WithTableHint(sqlglot.expressions.core.Expression):
938class WithTableHint(Expression):
939    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):
942class IndexTableHint(Expression):
943    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):
946class HistoricalData(Expression):
947    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]]' = {'this', 'expression', 'kind'}
class Put(sqlglot.expressions.core.Expression):
950class Put(Expression):
951    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]]' = {'this', 'target'}
class Get(sqlglot.expressions.core.Expression):
954class Get(Expression):
955    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]]' = {'this', 'target'}
class Table(sqlglot.expressions.core.Expression, Selectable):
 958class Table(Expression, Selectable):
 959    arg_types = {
 960        "this": False,
 961        "alias": False,
 962        "db": False,
 963        "catalog": False,
 964        "laterals": False,
 965        "joins": False,
 966        "pivots": False,
 967        "hints": False,
 968        "system_time": False,
 969        "version": False,
 970        "format": False,
 971        "pattern": False,
 972        "ordinality": False,
 973        "when": False,
 974        "only": False,
 975        "partition": False,
 976        "changes": False,
 977        "rows_from": False,
 978        "sample": False,
 979        "indexed": False,
 980    }
 981
 982    @property
 983    def name(self) -> str:
 984        this = self.this
 985        if not this or (isinstance(this, Func) and not isinstance(this, DynamicIdentifier)):
 986            return ""
 987        return this.name
 988
 989    @property
 990    def db(self) -> str:
 991        return self.text("db")
 992
 993    @property
 994    def catalog(self) -> str:
 995        return self.text("catalog")
 996
 997    @property
 998    def selects(self) -> list[Expr]:
 999        return []
1000
1001    @property
1002    def named_selects(self) -> list[str]:
1003        return []
1004
1005    @property
1006    def parts(self) -> list[Expr]:
1007        """Return the parts of a table in order catalog, db, table."""
1008        parts: list[Expr] = []
1009
1010        for arg in ("catalog", "db", "this"):
1011            part = self.args.get(arg)
1012
1013            if isinstance(part, Dot):
1014                parts.extend(part.flatten())
1015            elif isinstance(part, Expr):
1016                parts.append(part)
1017
1018        return parts
1019
1020    def to_column(self, copy: bool = True) -> Expr:
1021        parts = self.parts
1022        last_part = parts[-1]
1023
1024        if isinstance(last_part, Identifier):
1025            col: Expr = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
1026        else:
1027            # This branch will be reached if a function or array is wrapped in a `Table`
1028            col = last_part
1029
1030        alias = self.args.get("alias")
1031        if alias:
1032            col = alias_(col, alias.this, copy=copy)
1033
1034        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
982    @property
983    def name(self) -> str:
984        this = self.this
985        if not this or (isinstance(this, Func) and not isinstance(this, DynamicIdentifier)):
986            return ""
987        return this.name
db: str
989    @property
990    def db(self) -> str:
991        return self.text("db")
catalog: str
993    @property
994    def catalog(self) -> str:
995        return self.text("catalog")
selects: list[sqlglot.expressions.core.Expr]
997    @property
998    def selects(self) -> list[Expr]:
999        return []
named_selects: list[str]
1001    @property
1002    def named_selects(self) -> list[str]:
1003        return []
parts: list[sqlglot.expressions.core.Expr]
1005    @property
1006    def parts(self) -> list[Expr]:
1007        """Return the parts of a table in order catalog, db, table."""
1008        parts: list[Expr] = []
1009
1010        for arg in ("catalog", "db", "this"):
1011            part = self.args.get(arg)
1012
1013            if isinstance(part, Dot):
1014                parts.extend(part.flatten())
1015            elif isinstance(part, Expr):
1016                parts.append(part)
1017
1018        return parts

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

def to_column(self, copy: bool = True) -> sqlglot.expressions.core.Expr:
1020    def to_column(self, copy: bool = True) -> Expr:
1021        parts = self.parts
1022        last_part = parts[-1]
1023
1024        if isinstance(last_part, Identifier):
1025            col: Expr = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
1026        else:
1027            # This branch will be reached if a function or array is wrapped in a `Table`
1028            col = last_part
1029
1030        alias = self.args.get("alias")
1031        if alias:
1032            col = alias_(col, alias.this, copy=copy)
1033
1034        return col
key: ClassVar[str] = 'table'
required_args: 't.ClassVar[set[str]]' = set()
class SetOperation(sqlglot.expressions.core.Expression, Query):
1051class SetOperation(Expression, Query):
1052    arg_types = {
1053        "with_": False,
1054        "this": True,
1055        "expression": True,
1056        "distinct": False,
1057        "by_name": False,
1058        "side": False,
1059        "kind": False,
1060        "on": False,
1061        **QUERY_MODIFIERS,
1062    }
1063
1064    def select(
1065        self: S,
1066        *expressions: ExpOrStr | None,
1067        append: bool = True,
1068        dialect: DialectType = None,
1069        copy: bool = True,
1070        **opts: Unpack[ParserNoDialectArgs],
1071    ) -> S:
1072        this = maybe_copy(self, copy)
1073        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1074        this.expression.unnest().select(
1075            *expressions, append=append, dialect=dialect, copy=False, **opts
1076        )
1077        return this
1078
1079    @property
1080    def named_selects(self) -> list[str]:
1081        expr: Expr = self
1082        while isinstance(expr, SetOperation):
1083            if expr.args.get("by_name"):
1084                left = t.cast(Selectable, expr.this.unnest()).named_selects
1085                right = t.cast(Selectable, expr.expression.unnest()).named_selects
1086                return list(dict.fromkeys(left + right))
1087
1088            expr = expr.this.unnest()
1089        return _named_selects(expr)
1090
1091    @property
1092    def is_star(self) -> bool:
1093        return _is_star(self)
1094
1095    @property
1096    def selects(self) -> list[Expr]:
1097        expr: Expr = self
1098        while isinstance(expr, SetOperation):
1099            expr = expr.this.unnest()
1100        return getattr(expr, "selects", [])
1101
1102    @property
1103    def left(self) -> Query:
1104        return self.this
1105
1106    @property
1107    def right(self) -> Query:
1108        return self.expression
1109
1110    @property
1111    def kind(self) -> str:
1112        return self.text("kind").upper()
1113
1114    @property
1115    def side(self) -> str:
1116        return self.text("side").upper()
arg_types = {'with_': False, 'this': True, 'expression': True, 'distinct': False, 'by_name': False, 'side': False, 'kind': False, 'on': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False, 'for_': False}
def select( self: ~S, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> ~S:
1064    def select(
1065        self: S,
1066        *expressions: ExpOrStr | None,
1067        append: bool = True,
1068        dialect: DialectType = None,
1069        copy: bool = True,
1070        **opts: Unpack[ParserNoDialectArgs],
1071    ) -> S:
1072        this = maybe_copy(self, copy)
1073        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1074        this.expression.unnest().select(
1075            *expressions, append=append, dialect=dialect, copy=False, **opts
1076        )
1077        return this
named_selects: list[str]
1079    @property
1080    def named_selects(self) -> list[str]:
1081        expr: Expr = self
1082        while isinstance(expr, SetOperation):
1083            if expr.args.get("by_name"):
1084                left = t.cast(Selectable, expr.this.unnest()).named_selects
1085                right = t.cast(Selectable, expr.expression.unnest()).named_selects
1086                return list(dict.fromkeys(left + right))
1087
1088            expr = expr.this.unnest()
1089        return _named_selects(expr)
is_star: bool
1091    @property
1092    def is_star(self) -> bool:
1093        return _is_star(self)

Checks whether an expression is a star.

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

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

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:
1257    def sort_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 SORT BY expression.
1267
1268        Example:
1269            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
1270            'SELECT x FROM tbl SORT 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 `SORT`.
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="sort",
1289            append=append,
1290            copy=copy,
1291            prefix="SORT BY",
1292            into=Sort,
1293            dialect=dialect,
1294            **opts,
1295        )

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:
1297    def cluster_by(
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        """
1306        Set the CLUSTER BY expression.
1307
1308        Example:
1309            >>> Select().from_("tbl").select("x").cluster_by("x").sql(dialect="hive")
1310            'SELECT x FROM tbl CLUSTER BY x'
1311
1312        Args:
1313            *expressions: the SQL code strings to parse.
1314                If a `Group` instance is passed, this is used as-is.
1315                If another `Expr` instance is passed, it will be wrapped in a `Cluster`.
1316            append: if `True`, add to any existing expressions.
1317                Otherwise, this flattens all the `Order` expression into a single expression.
1318            dialect: the dialect used to parse the input expression.
1319            copy: if `False`, modify this expression instance in-place.
1320            opts: other options to use to parse the input expressions.
1321
1322        Returns:
1323            The modified Select expression.
1324        """
1325        return _apply_child_list_builder(
1326            *expressions,
1327            instance=self,
1328            arg="cluster",
1329            append=append,
1330            copy=copy,
1331            prefix="CLUSTER BY",
1332            into=Cluster,
1333            dialect=dialect,
1334            **opts,
1335        )

Set the CLUSTER BY expression.

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

The modified Select expression.

def select( self, *expressions: Union[int, str, sqlglot.expressions.core.Expr, NoneType], append: bool = True, dialect: Union[str, sqlglot.dialects.Dialect, type[sqlglot.dialects.Dialect], NoneType] = None, copy: bool = True, **opts: typing_extensions.Unpack[sqlglot._typing.ParserNoDialectArgs]) -> Select:
1337    def select(
1338        self,
1339        *expressions: ExpOrStr | None,
1340        append: bool = True,
1341        dialect: DialectType = None,
1342        copy: bool = True,
1343        **opts: Unpack[ParserNoDialectArgs],
1344    ) -> Select:
1345        return _apply_list_builder(
1346            *expressions,
1347            instance=self,
1348            arg="expressions",
1349            append=append,
1350            dialect=dialect,
1351            into=Expr,
1352            copy=copy,
1353            **opts,
1354        )
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:
1356    def lateral(
1357        self,
1358        *expressions: ExpOrStr | None,
1359        append: bool = True,
1360        dialect: DialectType = None,
1361        copy: bool = True,
1362        **opts: Unpack[ParserNoDialectArgs],
1363    ) -> Select:
1364        """
1365        Append to or set the LATERAL expressions.
1366
1367        Example:
1368            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
1369            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
1370
1371        Args:
1372            *expressions: the SQL code strings to parse.
1373                If an `Expr` instance is passed, it will be used as-is.
1374            append: if `True`, add to any existing expressions.
1375                Otherwise, this resets the expressions.
1376            dialect: the dialect used to parse the input expressions.
1377            copy: if `False`, modify this expression instance in-place.
1378            opts: other options to use to parse the input expressions.
1379
1380        Returns:
1381            The modified Select expression.
1382        """
1383        return _apply_list_builder(
1384            *expressions,
1385            instance=self,
1386            arg="laterals",
1387            append=append,
1388            into=Lateral,
1389            prefix="LATERAL VIEW",
1390            dialect=dialect,
1391            copy=copy,
1392            **opts,
1393        )

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:
1395    def join(
1396        self,
1397        expression: ExpOrStr,
1398        on: ExpOrStr | list[ExpOrStr] | tuple[ExpOrStr, ...] | None = None,
1399        using: ExpOrStr | list[ExpOrStr] | tuple[ExpOrStr, ...] | None = None,
1400        append: bool = True,
1401        join_type: str | None = None,
1402        join_alias: Identifier | str | None = None,
1403        dialect: DialectType = None,
1404        copy: bool = True,
1405        **opts: Unpack[ParserNoDialectArgs],
1406    ) -> Select:
1407        """
1408        Append to or set the JOIN expressions.
1409
1410        Example:
1411            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y").sql()
1412            'SELECT * FROM tbl JOIN tbl2 ON tbl1.y = tbl2.y'
1413
1414            >>> Select().select("1").from_("a").join("b", using=["x", "y", "z"]).sql()
1415            'SELECT 1 FROM a JOIN b USING (x, y, z)'
1416
1417            Use `join_type` to change the type of join:
1418
1419            >>> Select().select("*").from_("tbl").join("tbl2", on="tbl1.y = tbl2.y", join_type="left outer").sql()
1420            'SELECT * FROM tbl LEFT OUTER JOIN tbl2 ON tbl1.y = tbl2.y'
1421
1422        Args:
1423            expression: the SQL code string to parse.
1424                If an `Expr` instance is passed, it will be used as-is.
1425            on: optionally specify the join "on" criteria as a SQL string.
1426                If an `Expr` instance is passed, it will be used as-is.
1427            using: optionally specify the join "using" criteria as a SQL string.
1428                If an `Expr` instance is passed, it will be used as-is.
1429            append: if `True`, add to any existing expressions.
1430                Otherwise, this resets the expressions.
1431            join_type: if set, alter the parsed join type.
1432            join_alias: an optional alias for the joined source.
1433            dialect: the dialect used to parse the input expressions.
1434            copy: if `False`, modify this expression instance in-place.
1435            opts: other options to use to parse the input expressions.
1436
1437        Returns:
1438            Select: the modified expression.
1439        """
1440        parse_args: ParserArgs = {"dialect": dialect, **opts}
1441        try:
1442            expression = maybe_parse(expression, into=Join, prefix="JOIN", **parse_args)
1443        except ParseError:
1444            expression = maybe_parse(expression, into=(Join, Expr), **parse_args)
1445
1446        join = expression if isinstance(expression, Join) else Join(this=expression)
1447
1448        if isinstance(join.this, Select):
1449            join.this.replace(join.this.subquery())
1450
1451        if join_type:
1452            new_join: Join = maybe_parse(f"FROM _ {join_type} JOIN _", **parse_args).find(Join)
1453            method = new_join.method
1454            side = new_join.side
1455            kind = new_join.kind
1456
1457            if method:
1458                join.set("method", method)
1459            if side:
1460                join.set("side", side)
1461            if kind:
1462                join.set("kind", kind)
1463
1464        if on:
1465            on_exprs: list[ExpOrStr] = ensure_list(on)
1466            on = and_(*on_exprs, dialect=dialect, copy=copy, **opts)
1467            join.set("on", on)
1468
1469        if using:
1470            using_exprs: list[ExpOrStr] = ensure_list(using)
1471            join = _apply_list_builder(
1472                *using_exprs,
1473                instance=join,
1474                arg="using",
1475                append=append,
1476                copy=copy,
1477                into=Identifier,
1478                **opts,
1479            )
1480
1481        if join_alias:
1482            join.set("this", alias_(join.this, join_alias, table=True))
1483
1484        return _apply_list_builder(
1485            join,
1486            instance=self,
1487            arg="joins",
1488            append=append,
1489            copy=copy,
1490            **opts,
1491        )

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:
1493    def having(
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        """
1502        Append to or set the HAVING expressions.
1503
1504        Example:
1505            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
1506            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
1507
1508        Args:
1509            *expressions: the SQL code strings to parse.
1510                If an `Expr` instance is passed, it will be used as-is.
1511                Multiple expressions are combined with an AND operator.
1512            append: if `True`, AND the new expressions to any existing expression.
1513                Otherwise, this resets the expression.
1514            dialect: the dialect used to parse the input expressions.
1515            copy: if `False`, modify this expression instance in-place.
1516            opts: other options to use to parse the input expressions.
1517
1518        Returns:
1519            The modified Select expression.
1520        """
1521        return _apply_conjunction_builder(
1522            *expressions,
1523            instance=self,
1524            arg="having",
1525            append=append,
1526            into=Having,
1527            dialect=dialect,
1528            copy=copy,
1529            **opts,
1530        )

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:
1532    def window(
1533        self,
1534        *expressions: ExpOrStr | None,
1535        append: bool = True,
1536        dialect: DialectType = None,
1537        copy: bool = True,
1538        **opts: Unpack[ParserNoDialectArgs],
1539    ) -> Select:
1540        return _apply_list_builder(
1541            *expressions,
1542            instance=self,
1543            arg="windows",
1544            append=append,
1545            into=Window,
1546            dialect=dialect,
1547            copy=copy,
1548            **opts,
1549        )
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:
1551    def qualify(
1552        self,
1553        *expressions: ExpOrStr | None,
1554        append: bool = True,
1555        dialect: DialectType = None,
1556        copy: bool = True,
1557        **opts: Unpack[ParserNoDialectArgs],
1558    ) -> Select:
1559        return _apply_conjunction_builder(
1560            *expressions,
1561            instance=self,
1562            arg="qualify",
1563            append=append,
1564            into=Qualify,
1565            dialect=dialect,
1566            copy=copy,
1567            **opts,
1568        )
def distinct( self, *ons: Union[int, str, sqlglot.expressions.core.Expr, NoneType], distinct: bool = True, copy: bool = True) -> Select:
1570    def distinct(self, *ons: ExpOrStr | None, distinct: bool = True, copy: bool = True) -> Select:
1571        """
1572        Set the OFFSET expression.
1573
1574        Example:
1575            >>> Select().from_("tbl").select("x").distinct().sql()
1576            'SELECT DISTINCT x FROM tbl'
1577
1578        Args:
1579            ons: the expressions to distinct on
1580            distinct: whether the Select should be distinct
1581            copy: if `False`, modify this expression instance in-place.
1582
1583        Returns:
1584            Select: the modified expression.
1585        """
1586        instance = maybe_copy(self, copy)
1587        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
1588        instance.set("distinct", Distinct(on=on) if distinct else None)
1589        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:
1591    def ctas(
1592        self,
1593        table: ExpOrStr,
1594        properties: dict | None = None,
1595        dialect: DialectType = None,
1596        copy: bool = True,
1597        **opts: Unpack[ParserNoDialectArgs],
1598    ) -> Create:
1599        """
1600        Convert this expression to a CREATE TABLE AS statement.
1601
1602        Example:
1603            >>> Select().select("*").from_("tbl").ctas("x").sql()
1604            'CREATE TABLE x AS SELECT * FROM tbl'
1605
1606        Args:
1607            table: the SQL code string to parse as the table name.
1608                If another `Expr` instance is passed, it will be used as-is.
1609            properties: an optional mapping of table properties
1610            dialect: the dialect used to parse the input table.
1611            copy: if `False`, modify this expression instance in-place.
1612            opts: other options to use to parse the input table.
1613
1614        Returns:
1615            The new Create expression.
1616        """
1617        instance = maybe_copy(self, copy)
1618        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
1619
1620        properties_expression = None
1621        if properties:
1622            from sqlglot.expressions.properties import Properties as _Properties
1623
1624            properties_expression = _Properties.from_dict(properties)
1625
1626        from sqlglot.expressions.ddl import Create as _Create
1627
1628        return _Create(
1629            this=table_expression,
1630            kind="TABLE",
1631            expression=instance,
1632            properties=properties_expression,
1633        )

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:
1635    def lock(self, update: bool = True, copy: bool = True) -> Select:
1636        """
1637        Set the locking read mode for this expression.
1638
1639        Examples:
1640            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
1641            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
1642
1643            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
1644            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
1645
1646        Args:
1647            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
1648            copy: if `False`, modify this expression instance in-place.
1649
1650        Returns:
1651            The modified expression.
1652        """
1653        inst = maybe_copy(self, copy)
1654        inst.set("locks", [Lock(update=update)])
1655
1656        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:
1658    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
1659        """
1660        Set hints for this expression.
1661
1662        Examples:
1663            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
1664            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
1665
1666        Args:
1667            hints: The SQL code strings to parse as the hints.
1668                If an `Expr` instance is passed, it will be used as-is.
1669            dialect: The dialect used to parse the hints.
1670            copy: If `False`, modify this expression instance in-place.
1671
1672        Returns:
1673            The modified expression.
1674        """
1675        inst = maybe_copy(self, copy)
1676        inst.set(
1677            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
1678        )
1679
1680        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]
1682    @property
1683    def named_selects(self) -> list[str]:
1684        selects = []
1685
1686        for e in self.expressions:
1687            if e.alias_or_name:
1688                selects.append(e.output_name)
1689            elif isinstance(e, Aliases):
1690                selects.extend([a.name for a in e.aliases])
1691        return selects
is_star: bool
1693    @property
1694    def is_star(self) -> bool:
1695        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: list[sqlglot.expressions.core.Expr]
1697    @property
1698    def selects(self) -> list[Expr]:
1699        return self.expressions
key: ClassVar[str] = 'select'
required_args: 't.ClassVar[set[str]]' = set()
class Subquery(sqlglot.expressions.core.Expression, DerivedTable, Query):
1702class Subquery(Expression, DerivedTable, Query):
1703    is_subquery: t.ClassVar[bool] = True
1704    arg_types = {
1705        "this": True,
1706        "alias": False,
1707        "with_": False,
1708        **QUERY_MODIFIERS,
1709    }
1710
1711    def unnest(self) -> Expr:
1712        """Returns the first non subquery."""
1713        expression: Expr = self
1714        while isinstance(expression, Subquery):
1715            expression = expression.this
1716        return expression
1717
1718    def unwrap(self) -> Subquery:
1719        expression = self
1720        while expression.same_parent and expression.is_wrapper:
1721            expression = t.cast(Subquery, expression.parent)
1722        return expression
1723
1724    def select(
1725        self,
1726        *expressions: ExpOrStr | None,
1727        append: bool = True,
1728        dialect: DialectType = None,
1729        copy: bool = True,
1730        **opts: Unpack[ParserNoDialectArgs],
1731    ) -> Subquery:
1732        this = maybe_copy(self, copy)
1733        inner = this.unnest()
1734        if hasattr(inner, "select"):
1735            inner.select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1736        return this
1737
1738    @property
1739    def is_wrapper(self) -> bool:
1740        """
1741        Whether this Subquery acts as a simple wrapper around another expression.
1742
1743        SELECT * FROM (((SELECT * FROM t)))
1744                      ^
1745                      This corresponds to a "wrapper" Subquery node
1746        """
1747        return all(v is None for k, v in self.args.items() if k != "this")
1748
1749    @property
1750    def is_star(self) -> bool:
1751        return _is_star(self)
1752
1753    @property
1754    def output_name(self) -> str:
1755        return self.alias
is_subquery: ClassVar[bool] = True
arg_types = {'this': True, 'alias': False, 'with_': False, 'match': False, 'laterals': False, 'joins': False, 'connect': False, 'pivots': False, 'prewhere': False, 'where': False, 'group': False, 'having': False, 'qualify': False, 'windows': False, 'distribute': False, 'sort': False, 'cluster': False, 'order': False, 'limit': False, 'offset': False, 'locks': False, 'sample': False, 'settings': False, 'format': False, 'options': False, 'for_': False}
def unnest(self) -> sqlglot.expressions.core.Expr:
1711    def unnest(self) -> Expr:
1712        """Returns the first non subquery."""
1713        expression: Expr = self
1714        while isinstance(expression, Subquery):
1715            expression = expression.this
1716        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
1718    def unwrap(self) -> Subquery:
1719        expression = self
1720        while expression.same_parent and expression.is_wrapper:
1721            expression = t.cast(Subquery, expression.parent)
1722        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:
1724    def select(
1725        self,
1726        *expressions: ExpOrStr | None,
1727        append: bool = True,
1728        dialect: DialectType = None,
1729        copy: bool = True,
1730        **opts: Unpack[ParserNoDialectArgs],
1731    ) -> Subquery:
1732        this = maybe_copy(self, copy)
1733        inner = this.unnest()
1734        if hasattr(inner, "select"):
1735            inner.select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1736        return this
is_wrapper: bool
1738    @property
1739    def is_wrapper(self) -> bool:
1740        """
1741        Whether this Subquery acts as a simple wrapper around another expression.
1742
1743        SELECT * FROM (((SELECT * FROM t)))
1744                      ^
1745                      This corresponds to a "wrapper" Subquery node
1746        """
1747        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
1749    @property
1750    def is_star(self) -> bool:
1751        return _is_star(self)

Checks whether an expression is a star.

output_name: str
1753    @property
1754    def output_name(self) -> str:
1755        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):
1758class TableSample(Expression):
1759    arg_types = {
1760        "expressions": False,
1761        "method": False,
1762        "bucket_numerator": False,
1763        "bucket_denominator": False,
1764        "bucket_field": False,
1765        "percent": False,
1766        "rows": False,
1767        "size": False,
1768        "seed": False,
1769    }
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):
1772class Tag(Expression):
1773    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
1774
1775    arg_types = {
1776        "this": False,
1777        "prefix": False,
1778        "postfix": False,
1779    }

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):
1782class Pivot(Expression):
1783    arg_types = {
1784        "this": False,
1785        "alias": False,
1786        "expressions": False,
1787        "fields": False,
1788        "unpivot": False,
1789        "using": False,
1790        "group": False,
1791        "columns": False,
1792        "include_nulls": False,
1793        "default_on_null": False,
1794        "into": False,
1795        "with_": False,
1796        "identify_pivot_strings": False,
1797        "prefixed_pivot_columns": False,
1798        "pivot_column_naming": False,
1799        "value_columns_first": False,
1800    }
1801
1802    @property
1803    def unpivot(self) -> bool:
1804        return bool(self.args.get("unpivot"))
1805
1806    @property
1807    def fields(self) -> list[Expr]:
1808        return self.args.get("fields", [])
1809
1810    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1811        """
1812        Returns an ordered map of post-rename output column name -> pre-rename
1813        source-side name, in the order the (UN)PIVOT produces them.
1814
1815        For callers that just want the names, iterate the dict (or call .keys()):
1816            >>> from sqlglot import parse_one, exp
1817            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1818            >>> list(piv.output_columns(["a", "b", "c"]))
1819            ['c', 'name', 'val']
1820
1821        AST shape:
1822            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1823                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1824                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1825                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1826
1827            UNPIVOT(val FOR name IN (a, b)):
1828                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1829                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1830                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1831                             are wrapped in PivotAlias(this=Column, alias=Literal).
1832
1833        Args:
1834            pre_pivot_columns: Columns visible to the operator before it runs
1835                (e.g. the source table or subquery's projections).
1836        """
1837        if self.unpivot:
1838            excluded: set[str] = set()
1839            name_columns: list[Identifier] = []
1840            for field in self.fields:
1841                if not isinstance(field, In):
1842                    continue
1843                if isinstance(field.this, Identifier):
1844                    name_columns.append(field.this)
1845                for e in field.expressions:
1846                    excluded.update(c.output_name for c in e.find_all(Column))
1847            value_columns = [
1848                ident
1849                for e in self.expressions
1850                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1851                if isinstance(ident, Identifier)
1852            ]
1853            # T-SQL emits the value column(s) ahead of the name column, everyone else emits them after it
1854            ordered = (
1855                value_columns + name_columns
1856                if self.args.get("value_columns_first")
1857                else name_columns + value_columns
1858            )
1859            outputs = [i.name for i in ordered]
1860        else:
1861            excluded = {c.output_name for c in self.find_all(Column)}
1862            outputs = [c.output_name for c in self.args.get("columns") or []]
1863            if not outputs:
1864                outputs = [c.alias_or_name for c in self.expressions]
1865
1866        if not excluded or not outputs:
1867            return {}
1868
1869        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1870
1871        alias = self.args.get("alias")
1872        renames = alias.args.get("columns") if alias else None
1873
1874        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1875        # positionally from the front (DuckDB, Snowflake): the user's names cover
1876        # the leading N output columns, remaining columns keep their auto names.
1877        if renames:
1878            rename_names = [r.name for r in renames]
1879            post_rename = rename_names + pre_rename[len(rename_names) :]
1880        else:
1881            post_rename = pre_rename
1882
1883        return dict(zip(post_rename, pre_rename))
arg_types = {'this': False, 'alias': False, 'expressions': False, 'fields': False, 'unpivot': False, 'using': False, 'group': False, 'columns': False, 'include_nulls': False, 'default_on_null': False, 'into': False, 'with_': False, 'identify_pivot_strings': False, 'prefixed_pivot_columns': False, 'pivot_column_naming': False, 'value_columns_first': False}
unpivot: bool
1802    @property
1803    def unpivot(self) -> bool:
1804        return bool(self.args.get("unpivot"))
fields: list[sqlglot.expressions.core.Expr]
1806    @property
1807    def fields(self) -> list[Expr]:
1808        return self.args.get("fields", [])
def output_columns(self, pre_pivot_columns: Iterable[str]) -> dict[str, str]:
1810    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1811        """
1812        Returns an ordered map of post-rename output column name -> pre-rename
1813        source-side name, in the order the (UN)PIVOT produces them.
1814
1815        For callers that just want the names, iterate the dict (or call .keys()):
1816            >>> from sqlglot import parse_one, exp
1817            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1818            >>> list(piv.output_columns(["a", "b", "c"]))
1819            ['c', 'name', 'val']
1820
1821        AST shape:
1822            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1823                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1824                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1825                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1826
1827            UNPIVOT(val FOR name IN (a, b)):
1828                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1829                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1830                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1831                             are wrapped in PivotAlias(this=Column, alias=Literal).
1832
1833        Args:
1834            pre_pivot_columns: Columns visible to the operator before it runs
1835                (e.g. the source table or subquery's projections).
1836        """
1837        if self.unpivot:
1838            excluded: set[str] = set()
1839            name_columns: list[Identifier] = []
1840            for field in self.fields:
1841                if not isinstance(field, In):
1842                    continue
1843                if isinstance(field.this, Identifier):
1844                    name_columns.append(field.this)
1845                for e in field.expressions:
1846                    excluded.update(c.output_name for c in e.find_all(Column))
1847            value_columns = [
1848                ident
1849                for e in self.expressions
1850                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1851                if isinstance(ident, Identifier)
1852            ]
1853            # T-SQL emits the value column(s) ahead of the name column, everyone else emits them after it
1854            ordered = (
1855                value_columns + name_columns
1856                if self.args.get("value_columns_first")
1857                else name_columns + value_columns
1858            )
1859            outputs = [i.name for i in ordered]
1860        else:
1861            excluded = {c.output_name for c in self.find_all(Column)}
1862            outputs = [c.output_name for c in self.args.get("columns") or []]
1863            if not outputs:
1864                outputs = [c.alias_or_name for c in self.expressions]
1865
1866        if not excluded or not outputs:
1867            return {}
1868
1869        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1870
1871        alias = self.args.get("alias")
1872        renames = alias.args.get("columns") if alias else None
1873
1874        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1875        # positionally from the front (DuckDB, Snowflake): the user's names cover
1876        # the leading N output columns, remaining columns keep their auto names.
1877        if renames:
1878            rename_names = [r.name for r in renames]
1879            post_rename = rename_names + pre_rename[len(rename_names) :]
1880        else:
1881            post_rename = pre_rename
1882
1883        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):
1886class UnpivotColumns(Expression):
1887    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key: ClassVar[str] = 'unpivotcolumns'
required_args: 't.ClassVar[set[str]]' = {'this', 'expressions'}
1890class Window(Expression, Condition):
1891    arg_types = {
1892        "this": True,
1893        "partition_by": False,
1894        "order": False,
1895        "spec": False,
1896        "alias": False,
1897        "over": False,
1898        "first": False,
1899    }
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):
1902class WindowSpec(Expression):
1903    arg_types = {
1904        "kind": False,
1905        "start": False,
1906        "start_side": False,
1907        "end": False,
1908        "end_side": False,
1909        "exclude": False,
1910    }
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):
1913class PreWhere(Expression):
1914    pass
key: ClassVar[str] = 'prewhere'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Where(sqlglot.expressions.core.Expression):
1917class Where(Expression):
1918    pass
key: ClassVar[str] = 'where'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Analyze(sqlglot.expressions.core.Expression):
1921class Analyze(Expression):
1922    arg_types = {
1923        "kind": False,
1924        "tables": False,
1925        "options": False,
1926        "mode": False,
1927        "partition": False,
1928        "expression": False,
1929        "properties": False,
1930    }
arg_types = {'kind': False, 'tables': False, 'options': False, 'mode': False, 'partition': False, 'expression': False, 'properties': False}
key: ClassVar[str] = 'analyze'
required_args: 't.ClassVar[set[str]]' = set()
class AnalyzeStatistics(sqlglot.expressions.core.Expression):
1933class AnalyzeStatistics(Expression):
1934    arg_types = {
1935        "kind": True,
1936        "option": False,
1937        "this": False,
1938        "expressions": False,
1939    }
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):
1942class AnalyzeHistogram(Expression):
1943    arg_types = {
1944        "this": True,
1945        "expressions": True,
1946        "expression": False,
1947        "update_options": False,
1948    }
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):
1951class AnalyzeSample(Expression):
1952    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):
1955class AnalyzeListChainedRows(Expression):
1956    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):
1959class AnalyzeDelete(Expression):
1960    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):
1963class AnalyzeWith(Expression):
1964    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):
1967class AnalyzeValidate(Expression):
1968    arg_types = {
1969        "kind": True,
1970        "this": False,
1971        "expression": False,
1972    }
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):
1975class AnalyzeColumns(Expression):
1976    pass
key: ClassVar[str] = 'analyzecolumns'
required_args: 't.ClassVar[set[str]]' = {'this'}
class UsingData(sqlglot.expressions.core.Expression):
1979class UsingData(Expression):
1980    pass
key: ClassVar[str] = 'usingdata'
required_args: 't.ClassVar[set[str]]' = {'this'}
class AddPartition(sqlglot.expressions.core.Expression):
1983class AddPartition(Expression):
1984    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):
1987class AttachOption(Expression):
1988    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):
1991class DropPartition(Expression):
1992    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):
1995class ReplacePartition(Expression):
1996    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key: ClassVar[str] = 'replacepartition'
required_args: 't.ClassVar[set[str]]' = {'source', 'expression'}
class TranslateCharacters(sqlglot.expressions.core.Expression):
1999class TranslateCharacters(Expression):
2000    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]]' = {'this', 'expression'}
class OverflowTruncateBehavior(sqlglot.expressions.core.Expression):
2003class OverflowTruncateBehavior(Expression):
2004    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):
2007class JSON(Expression):
2008    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):
2011class JSONPath(Expression):
2012    arg_types = {"expressions": True}
2013
2014    @property
2015    def output_name(self) -> str:
2016        last_segment = self.expressions[-1].this
2017        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
2014    @property
2015    def output_name(self) -> str:
2016        last_segment = self.expressions[-1].this
2017        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):
2020class JSONPathPart(Expression):
2021    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'jsonpathpart'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathFilter(JSONPathPart):
2024class JSONPathFilter(JSONPathPart):
2025    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathfilter'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathKey(JSONPathPart):
2028class JSONPathKey(JSONPathPart):
2029    arg_types = {"this": True, "quoted": False}
arg_types = {'this': True, 'quoted': False}
key: ClassVar[str] = 'jsonpathkey'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathRecursive(JSONPathPart):
2032class JSONPathRecursive(JSONPathPart):
2033    arg_types = {"this": False}
arg_types = {'this': False}
key: ClassVar[str] = 'jsonpathrecursive'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathRoot(JSONPathPart):
2036class JSONPathRoot(JSONPathPart):
2037    pass
key: ClassVar[str] = 'jsonpathroot'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathScript(JSONPathPart):
2040class JSONPathScript(JSONPathPart):
2041    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathscript'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathSlice(JSONPathPart):
2044class JSONPathSlice(JSONPathPart):
2045    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):
2048class JSONPathSelector(JSONPathPart):
2049    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathselector'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathSubscript(JSONPathPart):
2052class JSONPathSubscript(JSONPathPart):
2053    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathsubscript'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathUnion(JSONPathPart):
2056class JSONPathUnion(JSONPathPart):
2057    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'jsonpathunion'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class JSONPathWildcard(JSONPathPart):
2060class JSONPathWildcard(JSONPathPart):
2061    pass
key: ClassVar[str] = 'jsonpathwildcard'
required_args: 't.ClassVar[set[str]]' = set()
class FormatJson(sqlglot.expressions.core.Expression):
2064class FormatJson(Expression):
2065    pass
key: ClassVar[str] = 'formatjson'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONKeyValue(sqlglot.expressions.core.Expression):
2068class JSONKeyValue(Expression):
2069    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key: ClassVar[str] = 'jsonkeyvalue'
required_args: 't.ClassVar[set[str]]' = {'this', 'expression'}
class JSONColumnDef(sqlglot.expressions.core.Expression):
2072class JSONColumnDef(Expression):
2073    arg_types = {
2074        "this": False,
2075        "kind": False,
2076        "path": False,
2077        "nested_schema": False,
2078        "ordinality": False,
2079        "format_json": False,
2080    }
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):
2083class JSONSchema(Expression):
2084    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):
2087class JSONValue(Expression):
2088    arg_types = {
2089        "this": True,
2090        "path": True,
2091        "returning": False,
2092        "on_condition": False,
2093    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key: ClassVar[str] = 'jsonvalue'
required_args: 't.ClassVar[set[str]]' = {'this', 'path'}
2096class JSONValueArray(Expression, Func):
2097    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):
2100class OpenJSONColumnDef(Expression):
2101    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
arg_types = {'this': True, 'kind': True, 'path': False, 'as_json': False}
key: ClassVar[str] = 'openjsoncolumndef'
required_args: 't.ClassVar[set[str]]' = {'this', 'kind'}
class JSONExtractQuote(sqlglot.expressions.core.Expression):
2104class JSONExtractQuote(Expression):
2105    arg_types = {
2106        "option": True,
2107        "scalar": False,
2108    }
arg_types = {'option': True, 'scalar': False}
key: ClassVar[str] = 'jsonextractquote'
required_args: 't.ClassVar[set[str]]' = {'option'}
class ScopeResolution(sqlglot.expressions.core.Expression):
2111class ScopeResolution(Expression):
2112    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):
2115class Stream(Expression):
2116    pass
key: ClassVar[str] = 'stream'
required_args: 't.ClassVar[set[str]]' = {'this'}
class ModelAttribute(sqlglot.expressions.core.Expression):
2119class ModelAttribute(Expression):
2120    arg_types = {"this": True, "expression": True}
arg_types = {'this': True, 'expression': True}
key: ClassVar[str] = 'modelattribute'
required_args: 't.ClassVar[set[str]]' = {'this', 'expression'}
class XMLNamespace(sqlglot.expressions.core.Expression):
2123class XMLNamespace(Expression):
2124    pass
key: ClassVar[str] = 'xmlnamespace'
required_args: 't.ClassVar[set[str]]' = {'this'}
class XMLKeyValueOption(sqlglot.expressions.core.Expression):
2127class XMLKeyValueOption(Expression):
2128    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):
2131class Semicolon(Expression):
2132    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'semicolon'
required_args: 't.ClassVar[set[str]]' = set()
class TableColumn(sqlglot.expressions.core.Expression):
2135class TableColumn(Expression):
2136    @property
2137    def output_name(self) -> str:
2138        return self.name
output_name: str
2136    @property
2137    def output_name(self) -> str:
2138        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):
2141class Variadic(Expression):
2142    pass
key: ClassVar[str] = 'variadic'
required_args: 't.ClassVar[set[str]]' = {'this'}
class StoredProcedure(sqlglot.expressions.core.Expression):
2145class StoredProcedure(Expression):
2146    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):
2149class Block(Expression):
2150    arg_types = {"expressions": True, "begin": False}
arg_types = {'expressions': True, 'begin': False}
key: ClassVar[str] = 'block'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class IfBlock(sqlglot.expressions.core.Expression):
2153class IfBlock(Expression):
2154    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]]' = {'this', 'true'}
class CaseStatement(sqlglot.expressions.core.Expression):
2157class CaseStatement(Expression):
2158    arg_types = {"this": False, "ifs": True, "default": False}
arg_types = {'this': False, 'ifs': True, 'default': False}
key: ClassVar[str] = 'casestatement'
required_args: 't.ClassVar[set[str]]' = {'ifs'}
class WhileBlock(sqlglot.expressions.core.Expression):
2161class WhileBlock(Expression):
2162    arg_types = {"this": True, "body": True, "label": False}
arg_types = {'this': True, 'body': True, 'label': False}
key: ClassVar[str] = 'whileblock'
required_args: 't.ClassVar[set[str]]' = {'this', 'body'}
class LoopBlock(sqlglot.expressions.core.Expression):
2165class LoopBlock(Expression):
2166    arg_types = {"body": True, "label": False}
arg_types = {'body': True, 'label': False}
key: ClassVar[str] = 'loopblock'
required_args: 't.ClassVar[set[str]]' = {'body'}
class RepeatBlock(sqlglot.expressions.core.Expression):
2169class RepeatBlock(Expression):
2170    arg_types = {"body": True, "until": True, "label": False}
arg_types = {'body': True, 'until': True, 'label': False}
key: ClassVar[str] = 'repeatblock'
required_args: 't.ClassVar[set[str]]' = {'body', 'until'}
class Leave(sqlglot.expressions.core.Expression):
2173class Leave(Expression):
2174    pass
key: ClassVar[str] = 'leave'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Iterate(sqlglot.expressions.core.Expression):
2177class Iterate(Expression):
2178    pass
key: ClassVar[str] = 'iterate'
required_args: 't.ClassVar[set[str]]' = {'this'}
class EndStatement(sqlglot.expressions.core.Expression):
2181class EndStatement(Expression):
2182    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'endstatement'
required_args: 't.ClassVar[set[str]]' = set()
class FunctionSpecification(sqlglot.expressions.core.Expression):
2186class FunctionSpecification(Expression):
2187    arg_types = {
2188        "this": True,
2189        "characteristics": False,
2190        "properties": False,
2191        "expression": True,
2192    }
arg_types = {'this': True, 'characteristics': False, 'properties': False, 'expression': True}
key: ClassVar[str] = 'functionspecification'
required_args: 't.ClassVar[set[str]]' = {'this', 'expression'}
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:
2198def union(
2199    *expressions: ExpOrStr,
2200    distinct: bool = True,
2201    dialect: DialectType = None,
2202    copy: bool = True,
2203    **opts: Unpack[ParserNoDialectArgs],
2204) -> Union:
2205    """
2206    Initializes a syntax tree for the `UNION` operation.
2207
2208    Example:
2209        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
2210        'SELECT * FROM foo UNION SELECT * FROM bla'
2211
2212    Args:
2213        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
2214            If `Expr` instances are passed, they will be used as-is.
2215        distinct: set the DISTINCT flag if and only if this is true.
2216        dialect: the dialect used to parse the input expression.
2217        copy: whether to copy the expression.
2218        opts: other options to use to parse the input expressions.
2219
2220    Returns:
2221        The new Union instance.
2222    """
2223    assert len(expressions) >= 2, "At least two expressions are required by `union`."
2224    return _apply_set_operation(
2225        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
2226    )

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:
2229def intersect(
2230    *expressions: ExpOrStr,
2231    distinct: bool = True,
2232    dialect: DialectType = None,
2233    copy: bool = True,
2234    **opts: Unpack[ParserNoDialectArgs],
2235) -> Intersect:
2236    """
2237    Initializes a syntax tree for the `INTERSECT` operation.
2238
2239    Example:
2240        >>> intersect("SELECT * FROM foo", "SELECT * FROM bla").sql()
2241        'SELECT * FROM foo INTERSECT SELECT * FROM bla'
2242
2243    Args:
2244        expressions: the SQL code strings, corresponding to the `INTERSECT`'s operands.
2245            If `Expr` instances are passed, they will be used as-is.
2246        distinct: set the DISTINCT flag if and only if this is true.
2247        dialect: the dialect used to parse the input expression.
2248        copy: whether to copy the expression.
2249        opts: other options to use to parse the input expressions.
2250
2251    Returns:
2252        The new Intersect instance.
2253    """
2254    assert len(expressions) >= 2, "At least two expressions are required by `intersect`."
2255    return _apply_set_operation(
2256        *expressions, set_operation=Intersect, distinct=distinct, dialect=dialect, copy=copy, **opts
2257    )

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:
2260def except_(
2261    *expressions: ExpOrStr,
2262    distinct: bool = True,
2263    dialect: DialectType = None,
2264    copy: bool = True,
2265    **opts: Unpack[ParserNoDialectArgs],
2266) -> Except:
2267    """
2268    Initializes a syntax tree for the `EXCEPT` operation.
2269
2270    Example:
2271        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
2272        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
2273
2274    Args:
2275        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
2276            If `Expr` instances are passed, they will be used as-is.
2277        distinct: set the DISTINCT flag if and only if this is true.
2278        dialect: the dialect used to parse the input expression.
2279        copy: whether to copy the expression.
2280        opts: other options to use to parse the input expressions.
2281
2282    Returns:
2283        The new Except instance.
2284    """
2285    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
2286    return _apply_set_operation(
2287        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
2288    )

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.