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

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

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

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

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

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

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

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:
356    def union(
357        self,
358        *expressions: ExpOrStr,
359        distinct: bool = True,
360        dialect: DialectType = None,
361        copy: bool = True,
362        **opts: Unpack[ParserNoDialectArgs],
363    ) -> Union:
364        """
365        Builds a UNION expression.
366
367        Example:
368            >>> import sqlglot
369            >>> sqlglot.parse_one("SELECT * FROM foo").union("SELECT * FROM bla").sql()
370            'SELECT * FROM foo UNION SELECT * FROM bla'
371
372        Args:
373            expressions: the SQL code strings.
374                If `Expr` instances are passed, they will be used as-is.
375            distinct: set the DISTINCT flag if and only if this is true.
376            dialect: the dialect used to parse the input expression.
377            opts: other options to use to parse the input expressions.
378
379        Returns:
380            The new Union expression.
381        """
382        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:
384    def intersect(
385        self,
386        *expressions: ExpOrStr,
387        distinct: bool = True,
388        dialect: DialectType = None,
389        copy: bool = True,
390        **opts: Unpack[ParserNoDialectArgs],
391    ) -> Intersect:
392        """
393        Builds an INTERSECT expression.
394
395        Example:
396            >>> import sqlglot
397            >>> sqlglot.parse_one("SELECT * FROM foo").intersect("SELECT * FROM bla").sql()
398            'SELECT * FROM foo INTERSECT SELECT * FROM bla'
399
400        Args:
401            expressions: the SQL code strings.
402                If `Expr` instances are passed, they will be used as-is.
403            distinct: set the DISTINCT flag if and only if this is true.
404            dialect: the dialect used to parse the input expression.
405            opts: other options to use to parse the input expressions.
406
407        Returns:
408            The new Intersect expression.
409        """
410        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:
412    def except_(
413        self,
414        *expressions: ExpOrStr,
415        distinct: bool = True,
416        dialect: DialectType = None,
417        copy: bool = True,
418        **opts: Unpack[ParserNoDialectArgs],
419    ) -> Except:
420        """
421        Builds an EXCEPT expression.
422
423        Example:
424            >>> import sqlglot
425            >>> sqlglot.parse_one("SELECT * FROM foo").except_("SELECT * FROM bla").sql()
426            'SELECT * FROM foo EXCEPT SELECT * FROM bla'
427
428        Args:
429            expressions: the SQL code strings.
430                If `Expr` instance are passed, they will be used as-is.
431            distinct: set the DISTINCT flag if and only if this is true.
432            dialect: the dialect used to parse the input expression.
433            opts: other options to use to parse the input expressions.
434
435        Returns:
436            The new Except expression.
437        """
438        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):
441class QueryBand(Expression):
442    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):
445class RecursiveWithSearch(Expression):
446    arg_types = {
447        "kind": True,
448        "this": True,
449        "expression": True,
450        "to": False,
451        "default": False,
452        "using": False,
453    }
arg_types = {'kind': True, 'this': True, 'expression': True, 'to': False, 'default': False, 'using': False}
key: ClassVar[str] = 'recursivewithsearch'
required_args: 't.ClassVar[set[str]]' = {'kind', 'this', 'expression'}
class With(sqlglot.expressions.core.Expression):
456class With(Expression):
457    arg_types = {
458        "expressions": False,
459        "recursive": False,
460        "search": False,
461        "cycle": False,
462        "udfs": False,
463    }
464
465    @property
466    def recursive(self) -> bool:
467        return bool(self.args.get("recursive"))
arg_types = {'expressions': False, 'recursive': False, 'search': False, 'cycle': False, 'udfs': False}
recursive: bool
465    @property
466    def recursive(self) -> bool:
467        return bool(self.args.get("recursive"))
key: ClassVar[str] = 'with'
required_args: 't.ClassVar[set[str]]' = set()
470class CTE(Expression, DerivedTable):
471    arg_types = {
472        "this": True,
473        "alias": True,
474        "scalar": False,
475        "materialized": False,
476        "key_expressions": False,
477    }
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):
480class ProjectionDef(Expression):
481    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):
484class TableAlias(Expression):
485    arg_types = {"this": False, "columns": False}
486
487    @property
488    def columns(self) -> list[t.Any]:
489        return self.args.get("columns") or []
arg_types = {'this': False, 'columns': False}
columns: list[typing.Any]
487    @property
488    def columns(self) -> list[t.Any]:
489        return self.args.get("columns") or []
key: ClassVar[str] = 'tablealias'
required_args: 't.ClassVar[set[str]]' = set()
492class BitString(Expression, Condition):
493    is_primitive = True
is_primitive = True
key: ClassVar[str] = 'bitstring'
required_args: 't.ClassVar[set[str]]' = {'this'}
496class HexString(Expression, Condition):
497    arg_types = {"this": True, "is_integer": False}
498    is_primitive = True
arg_types = {'this': True, 'is_integer': False}
is_primitive = True
key: ClassVar[str] = 'hexstring'
required_args: 't.ClassVar[set[str]]' = {'this'}
501class ByteString(Expression, Condition):
502    arg_types = {"this": True, "is_bytes": False}
503    is_primitive = True
arg_types = {'this': True, 'is_bytes': False}
is_primitive = True
key: ClassVar[str] = 'bytestring'
required_args: 't.ClassVar[set[str]]' = {'this'}
506class RawString(Expression, Condition):
507    is_primitive = True
is_primitive = True
key: ClassVar[str] = 'rawstring'
required_args: 't.ClassVar[set[str]]' = {'this'}
510class UnicodeString(Expression, Condition):
511    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):
514class ColumnPosition(Expression):
515    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):
518class ColumnDef(Expression):
519    arg_types = {
520        "this": True,
521        "kind": False,
522        "constraints": False,
523        "exists": False,
524        "position": False,
525        "default": False,
526        "output": False,
527    }
528
529    @property
530    def constraints(self) -> list[ColumnConstraint]:
531        return self.args.get("constraints") or []
532
533    @property
534    def kind(self) -> DataType | None:
535        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]
529    @property
530    def constraints(self) -> list[ColumnConstraint]:
531        return self.args.get("constraints") or []
kind: sqlglot.expressions.datatypes.DataType | None
533    @property
534    def kind(self) -> DataType | None:
535        return self.args.get("kind")
key: ClassVar[str] = 'columndef'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Changes(sqlglot.expressions.core.Expression):
538class Changes(Expression):
539    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):
542class Connect(Expression):
543    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):
546class Prior(Expression):
547    pass
key: ClassVar[str] = 'prior'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Into(sqlglot.expressions.core.Expression):
550class Into(Expression):
551    arg_types = {
552        "this": False,
553        "temporary": False,
554        "unlogged": False,
555        "bulk_collect": False,
556        "expressions": False,
557    }
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):
560class From(Expression):
561    @property
562    def name(self) -> str:
563        return self.this.name
564
565    @property
566    def alias_or_name(self) -> str:
567        return self.this.alias_or_name
name: str
561    @property
562    def name(self) -> str:
563        return self.this.name
alias_or_name: str
565    @property
566    def alias_or_name(self) -> str:
567        return self.this.alias_or_name
key: ClassVar[str] = 'from'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Having(sqlglot.expressions.core.Expression):
570class Having(Expression):
571    pass
key: ClassVar[str] = 'having'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Index(sqlglot.expressions.core.Expression):
574class Index(Expression):
575    arg_types = {
576        "this": False,
577        "table": False,
578        "unique": False,
579        "primary": False,
580        "amp": False,  # teradata
581        "params": False,
582    }
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):
585class ConditionalInsert(Expression):
586    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):
589class MultitableInserts(Expression):
590    arg_types = {"with_": False, "expressions": True, "kind": False, "source": True}
arg_types = {'with_': False, 'expressions': True, 'kind': False, 'source': True}
key: ClassVar[str] = 'multitableinserts'
required_args: 't.ClassVar[set[str]]' = {'source', 'expressions'}
class OnCondition(sqlglot.expressions.core.Expression):
593class OnCondition(Expression):
594    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):
597class Introducer(Expression):
598    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):
601class National(Expression):
602    is_primitive = True
is_primitive = True
key: ClassVar[str] = 'national'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Partition(sqlglot.expressions.core.Expression):
605class Partition(Expression):
606    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):
609class PartitionRange(Expression):
610    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):
613class PartitionId(Expression):
614    pass
key: ClassVar[str] = 'partitionid'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Fetch(sqlglot.expressions.core.Expression):
617class Fetch(Expression):
618    arg_types = {
619        "direction": False,
620        "count": False,
621        "limit_options": False,
622    }
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):
625class Grant(Expression):
626    arg_types = {
627        "privileges": True,
628        "kind": False,
629        "securable": True,
630        "principals": True,
631        "grant_option": False,
632    }
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False}
key: ClassVar[str] = 'grant'
required_args: 't.ClassVar[set[str]]' = {'securable', 'principals', 'privileges'}
class Revoke(sqlglot.expressions.core.Expression):
635class Revoke(Expression):
636    arg_types = {**Grant.arg_types, "cascade": False}
arg_types = {'privileges': True, 'kind': False, 'securable': True, 'principals': True, 'grant_option': False, 'cascade': False}
key: ClassVar[str] = 'revoke'
required_args: 't.ClassVar[set[str]]' = {'securable', 'principals', 'privileges'}
class Group(sqlglot.expressions.core.Expression):
639class Group(Expression):
640    arg_types = {
641        "expressions": False,
642        "grouping_sets": False,
643        "cube": False,
644        "rollup": False,
645        "totals": False,
646        "all": False,
647    }
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):
650class Cube(Expression):
651    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):
654class Rollup(Expression):
655    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):
658class GroupingSets(Expression):
659    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):
662class Lambda(Expression):
663    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):
666class Limit(Expression):
667    arg_types = {
668        "this": False,
669        "expression": True,
670        "offset": False,
671        "limit_options": False,
672        "expressions": False,
673    }
674
675    @property
676    def is_limit_all(self) -> bool:
677        limit_expression = self.args.get("expression")
678        return isinstance(limit_expression, Var) and limit_expression.name.upper() == "ALL"
arg_types = {'this': False, 'expression': True, 'offset': False, 'limit_options': False, 'expressions': False}
is_limit_all: bool
675    @property
676    def is_limit_all(self) -> bool:
677        limit_expression = self.args.get("expression")
678        return isinstance(limit_expression, Var) and limit_expression.name.upper() == "ALL"
key: ClassVar[str] = 'limit'
required_args: 't.ClassVar[set[str]]' = {'expression'}
class LimitOptions(sqlglot.expressions.core.Expression):
681class LimitOptions(Expression):
682    arg_types = {
683        "percent": False,
684        "rows": False,
685        "with_ties": False,
686    }
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):
689class Join(Expression):
690    arg_types = {
691        "this": True,
692        "on": False,
693        "side": False,
694        "kind": False,
695        "using": False,
696        "method": False,
697        "global_": False,
698        "hint": False,
699        "match_condition": False,  # Snowflake
700        "directed": False,  # Snowflake
701        "expressions": False,
702        "pivots": False,
703    }
704
705    @property
706    def method(self) -> str:
707        return self.text("method").upper()
708
709    @property
710    def kind(self) -> str:
711        return self.text("kind").upper()
712
713    @property
714    def side(self) -> str:
715        return self.text("side").upper()
716
717    @property
718    def hint(self) -> str:
719        return self.text("hint").upper()
720
721    @property
722    def alias_or_name(self) -> str:
723        return self.this.alias_or_name
724
725    @property
726    def is_semi_or_anti_join(self) -> bool:
727        return self.kind in ("SEMI", "ANTI")
728
729    def on(
730        self,
731        *expressions: ExpOrStr | None,
732        append: bool = True,
733        dialect: DialectType = None,
734        copy: bool = True,
735        **opts: Unpack[ParserNoDialectArgs],
736    ) -> Join:
737        """
738        Append to or set the ON expressions.
739
740        Example:
741            >>> import sqlglot
742            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
743            'JOIN x ON y = 1'
744
745        Args:
746            *expressions: the SQL code strings to parse.
747                If an `Expr` instance is passed, it will be used as-is.
748                Multiple expressions are combined with an AND operator.
749            append: if `True`, AND the new expressions to any existing expression.
750                Otherwise, this resets the expression.
751            dialect: the dialect used to parse the input expressions.
752            copy: if `False`, modify this expression instance in-place.
753            opts: other options to use to parse the input expressions.
754
755        Returns:
756            The modified Join expression.
757        """
758        join = _apply_conjunction_builder(
759            *expressions,
760            instance=self,
761            arg="on",
762            append=append,
763            dialect=dialect,
764            copy=copy,
765            **opts,
766        )
767
768        if join.kind == "CROSS":
769            join.set("kind", None)
770
771        return join
772
773    def using(
774        self,
775        *expressions: ExpOrStr | None,
776        append: bool = True,
777        dialect: DialectType = None,
778        copy: bool = True,
779        **opts: Unpack[ParserNoDialectArgs],
780    ) -> Join:
781        """
782        Append to or set the USING expressions.
783
784        Example:
785            >>> import sqlglot
786            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
787            'JOIN x USING (foo, bla)'
788
789        Args:
790            *expressions: the SQL code strings to parse.
791                If an `Expr` instance is passed, it will be used as-is.
792            append: if `True`, concatenate the new expressions to the existing "using" list.
793                Otherwise, this resets the expression.
794            dialect: the dialect used to parse the input expressions.
795            copy: if `False`, modify this expression instance in-place.
796            opts: other options to use to parse the input expressions.
797
798        Returns:
799            The modified Join expression.
800        """
801        join = _apply_list_builder(
802            *expressions,
803            instance=self,
804            arg="using",
805            append=append,
806            dialect=dialect,
807            copy=copy,
808            **opts,
809        )
810
811        if join.kind == "CROSS":
812            join.set("kind", None)
813
814        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
705    @property
706    def method(self) -> str:
707        return self.text("method").upper()
kind: str
709    @property
710    def kind(self) -> str:
711        return self.text("kind").upper()
side: str
713    @property
714    def side(self) -> str:
715        return self.text("side").upper()
hint: str
717    @property
718    def hint(self) -> str:
719        return self.text("hint").upper()
alias_or_name: str
721    @property
722    def alias_or_name(self) -> str:
723        return self.this.alias_or_name
is_semi_or_anti_join: bool
725    @property
726    def is_semi_or_anti_join(self) -> bool:
727        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:
729    def on(
730        self,
731        *expressions: ExpOrStr | None,
732        append: bool = True,
733        dialect: DialectType = None,
734        copy: bool = True,
735        **opts: Unpack[ParserNoDialectArgs],
736    ) -> Join:
737        """
738        Append to or set the ON expressions.
739
740        Example:
741            >>> import sqlglot
742            >>> sqlglot.parse_one("JOIN x", into=Join).on("y = 1").sql()
743            'JOIN x ON y = 1'
744
745        Args:
746            *expressions: the SQL code strings to parse.
747                If an `Expr` instance is passed, it will be used as-is.
748                Multiple expressions are combined with an AND operator.
749            append: if `True`, AND the new expressions to any existing expression.
750                Otherwise, this resets the expression.
751            dialect: the dialect used to parse the input expressions.
752            copy: if `False`, modify this expression instance in-place.
753            opts: other options to use to parse the input expressions.
754
755        Returns:
756            The modified Join expression.
757        """
758        join = _apply_conjunction_builder(
759            *expressions,
760            instance=self,
761            arg="on",
762            append=append,
763            dialect=dialect,
764            copy=copy,
765            **opts,
766        )
767
768        if join.kind == "CROSS":
769            join.set("kind", None)
770
771        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:
773    def using(
774        self,
775        *expressions: ExpOrStr | None,
776        append: bool = True,
777        dialect: DialectType = None,
778        copy: bool = True,
779        **opts: Unpack[ParserNoDialectArgs],
780    ) -> Join:
781        """
782        Append to or set the USING expressions.
783
784        Example:
785            >>> import sqlglot
786            >>> sqlglot.parse_one("JOIN x", into=Join).using("foo", "bla").sql()
787            'JOIN x USING (foo, bla)'
788
789        Args:
790            *expressions: the SQL code strings to parse.
791                If an `Expr` instance is passed, it will be used as-is.
792            append: if `True`, concatenate the new expressions to the existing "using" list.
793                Otherwise, this resets the expression.
794            dialect: the dialect used to parse the input expressions.
795            copy: if `False`, modify this expression instance in-place.
796            opts: other options to use to parse the input expressions.
797
798        Returns:
799            The modified Join expression.
800        """
801        join = _apply_list_builder(
802            *expressions,
803            instance=self,
804            arg="using",
805            append=append,
806            dialect=dialect,
807            copy=copy,
808            **opts,
809        )
810
811        if join.kind == "CROSS":
812            join.set("kind", None)
813
814        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):
817class Lateral(Expression, UDTF):
818    arg_types = {
819        "this": True,
820        "view": False,
821        "outer": False,
822        "alias": False,
823        "cross_apply": False,  # True -> CROSS APPLY, False -> OUTER APPLY
824        "ordinality": False,
825    }
826
827    @property
828    def selects(self) -> list[Expr]:
829        from sqlglot.expressions.array import Unnest
830
831        columns = super().selects
832
833        # UNNEST ... WITH ORDINALITY stores the ordinality column's name in Unnest.offset
834        offset = self.this.args.get("offset") if isinstance(self.this, Unnest) else None
835        if isinstance(offset, Identifier):
836            columns = columns + [offset]
837
838        return columns
arg_types = {'this': True, 'view': False, 'outer': False, 'alias': False, 'cross_apply': False, 'ordinality': False}
selects: list[sqlglot.expressions.core.Expr]
827    @property
828    def selects(self) -> list[Expr]:
829        from sqlglot.expressions.array import Unnest
830
831        columns = super().selects
832
833        # UNNEST ... WITH ORDINALITY stores the ordinality column's name in Unnest.offset
834        offset = self.this.args.get("offset") if isinstance(self.this, Unnest) else None
835        if isinstance(offset, Identifier):
836            columns = columns + [offset]
837
838        return columns
key: ClassVar[str] = 'lateral'
required_args: 't.ClassVar[set[str]]' = {'this'}
class TableFromRows(sqlglot.expressions.core.Expression, UDTF):
841class TableFromRows(Expression, UDTF):
842    arg_types = {
843        "this": True,
844        "alias": False,
845        "joins": False,
846        "pivots": False,
847        "sample": False,
848    }
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):
851class MatchRecognizeMeasure(Expression):
852    arg_types = {
853        "this": True,
854        "window_frame": False,
855    }
arg_types = {'this': True, 'window_frame': False}
key: ClassVar[str] = 'matchrecognizemeasure'
required_args: 't.ClassVar[set[str]]' = {'this'}
class MatchRecognize(sqlglot.expressions.core.Expression):
858class MatchRecognize(Expression):
859    arg_types = {
860        "partition_by": False,
861        "order": False,
862        "measures": False,
863        "rows": False,
864        "after": False,
865        "pattern": False,
866        "define": False,
867        "alias": False,
868    }
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):
871class Final(Expression):
872    pass
key: ClassVar[str] = 'final'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Offset(sqlglot.expressions.core.Expression):
875class Offset(Expression):
876    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):
879class Order(Expression):
880    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):
883class WithFill(Expression):
884    arg_types = {
885        "from_": False,
886        "to": False,
887        "step": False,
888        "interpolate": False,
889    }
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):
892class SkipJSONColumn(Expression):
893    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):
896class Cluster(Expression):
897    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'cluster'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Distribute(Order):
900class Distribute(Order):
901    pass
key: ClassVar[str] = 'distribute'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Sort(Order):
904class Sort(Order):
905    pass
key: ClassVar[str] = 'sort'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class Qualify(sqlglot.expressions.core.Expression):
908class Qualify(Expression):
909    pass
key: ClassVar[str] = 'qualify'
required_args: 't.ClassVar[set[str]]' = {'this'}
class InputOutputFormat(sqlglot.expressions.core.Expression):
912class InputOutputFormat(Expression):
913    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):
916class Return(Expression):
917    pass
key: ClassVar[str] = 'return'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Tuple(sqlglot.expressions.core.Expression):
920class Tuple(Expression):
921    arg_types = {"expressions": False}
922
923    def isin(
924        self,
925        *expressions: t.Any,
926        query: ExpOrStr | None = None,
927        unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None,
928        copy: bool = True,
929        **opts: Unpack[ParserArgs],
930    ) -> In:
931        return In(
932            this=maybe_copy(self, copy),
933            expressions=[convert(e, copy=copy) for e in expressions],
934            query=maybe_parse(query, copy=copy, **opts) if query else None,
935            unnest=(
936                Unnest(
937                    expressions=[
938                        maybe_parse(e, copy=copy, **opts)
939                        for e in t.cast(list[ExpOrStr], ensure_list(unnest))
940                    ]
941                )
942                if unnest
943                else None
944            ),
945        )
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:
923    def isin(
924        self,
925        *expressions: t.Any,
926        query: ExpOrStr | None = None,
927        unnest: ExpOrStr | None | list[ExpOrStr] | tuple[ExpOrStr, ...] = None,
928        copy: bool = True,
929        **opts: Unpack[ParserArgs],
930    ) -> In:
931        return In(
932            this=maybe_copy(self, copy),
933            expressions=[convert(e, copy=copy) for e in expressions],
934            query=maybe_parse(query, copy=copy, **opts) if query else None,
935            unnest=(
936                Unnest(
937                    expressions=[
938                        maybe_parse(e, copy=copy, **opts)
939                        for e in t.cast(list[ExpOrStr], ensure_list(unnest))
940                    ]
941                )
942                if unnest
943                else None
944            ),
945        )
key: ClassVar[str] = 'tuple'
required_args: 't.ClassVar[set[str]]' = set()
class QueryOption(sqlglot.expressions.core.Expression):
948class QueryOption(Expression):
949    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):
953class ForClause(Expression):
954    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):
957class WithTableHint(Expression):
958    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):
961class IndexTableHint(Expression):
962    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):
965class HistoricalData(Expression):
966    arg_types = {"this": True, "kind": True, "expression": True}
arg_types = {'this': True, 'kind': True, 'expression': True}
key: ClassVar[str] = 'historicaldata'
required_args: 't.ClassVar[set[str]]' = {'kind', 'this', 'expression'}
class Put(sqlglot.expressions.core.Expression):
969class Put(Expression):
970    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key: ClassVar[str] = 'put'
required_args: 't.ClassVar[set[str]]' = {'target', 'this'}
class Get(sqlglot.expressions.core.Expression):
973class Get(Expression):
974    arg_types = {"this": True, "target": True, "properties": False}
arg_types = {'this': True, 'target': True, 'properties': False}
key: ClassVar[str] = 'get'
required_args: 't.ClassVar[set[str]]' = {'target', 'this'}
class ListStage(sqlglot.expressions.core.Expression):
977class ListStage(Expression):
978    """Lists files in a Snowflake stage or Git repository clone."""
979
980    arg_types = {"this": True, "pattern": False}

Lists files in a Snowflake stage or Git repository clone.

arg_types = {'this': True, 'pattern': False}
key: ClassVar[str] = 'liststage'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Table(sqlglot.expressions.core.Expression, Selectable):
 983class Table(Expression, Selectable):
 984    arg_types = {
 985        "this": False,
 986        "alias": False,
 987        "db": False,
 988        "catalog": False,
 989        "laterals": False,
 990        "joins": False,
 991        "pivots": False,
 992        "hints": False,
 993        "system_time": False,
 994        "version": False,
 995        "format": False,
 996        "pattern": False,
 997        "ordinality": False,
 998        "when": False,
 999        "only": False,
1000        "partition": False,
1001        "changes": False,
1002        "rows_from": False,
1003        "sample": False,
1004        "indexed": False,
1005    }
1006
1007    @property
1008    def name(self) -> str:
1009        this = self.this
1010        if not this or (isinstance(this, Func) and not isinstance(this, DynamicIdentifier)):
1011            return ""
1012        return this.name
1013
1014    @property
1015    def db(self) -> str:
1016        return self.text("db")
1017
1018    @property
1019    def catalog(self) -> str:
1020        return self.text("catalog")
1021
1022    @property
1023    def selects(self) -> list[Expr]:
1024        return []
1025
1026    @property
1027    def named_selects(self) -> list[str]:
1028        return []
1029
1030    @property
1031    def parts(self) -> list[Expr]:
1032        """Return the parts of a table in order catalog, db, table."""
1033        parts: list[Expr] = []
1034
1035        for arg in ("catalog", "db", "this"):
1036            part = self.args.get(arg)
1037
1038            if isinstance(part, Dot):
1039                parts.extend(part.flatten())
1040            elif isinstance(part, Expr):
1041                parts.append(part)
1042
1043        return parts
1044
1045    def to_column(self, copy: bool = True) -> Expr:
1046        parts = self.parts
1047        last_part = parts[-1]
1048
1049        if isinstance(last_part, Identifier):
1050            col: Expr = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
1051        else:
1052            # This branch will be reached if a function or array is wrapped in a `Table`
1053            col = last_part
1054
1055        alias = self.args.get("alias")
1056        if alias:
1057            col = alias_(col, alias.this, copy=copy)
1058
1059        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
1007    @property
1008    def name(self) -> str:
1009        this = self.this
1010        if not this or (isinstance(this, Func) and not isinstance(this, DynamicIdentifier)):
1011            return ""
1012        return this.name
db: str
1014    @property
1015    def db(self) -> str:
1016        return self.text("db")
catalog: str
1018    @property
1019    def catalog(self) -> str:
1020        return self.text("catalog")
selects: list[sqlglot.expressions.core.Expr]
1022    @property
1023    def selects(self) -> list[Expr]:
1024        return []
named_selects: list[str]
1026    @property
1027    def named_selects(self) -> list[str]:
1028        return []
parts: list[sqlglot.expressions.core.Expr]
1030    @property
1031    def parts(self) -> list[Expr]:
1032        """Return the parts of a table in order catalog, db, table."""
1033        parts: list[Expr] = []
1034
1035        for arg in ("catalog", "db", "this"):
1036            part = self.args.get(arg)
1037
1038            if isinstance(part, Dot):
1039                parts.extend(part.flatten())
1040            elif isinstance(part, Expr):
1041                parts.append(part)
1042
1043        return parts

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

def to_column(self, copy: bool = True) -> sqlglot.expressions.core.Expr:
1045    def to_column(self, copy: bool = True) -> Expr:
1046        parts = self.parts
1047        last_part = parts[-1]
1048
1049        if isinstance(last_part, Identifier):
1050            col: Expr = column(*reversed(parts[0:4]), fields=parts[4:], copy=copy)  # type: ignore
1051        else:
1052            # This branch will be reached if a function or array is wrapped in a `Table`
1053            col = last_part
1054
1055        alias = self.args.get("alias")
1056        if alias:
1057            col = alias_(col, alias.this, copy=copy)
1058
1059        return col
key: ClassVar[str] = 'table'
required_args: 't.ClassVar[set[str]]' = set()
class SetOperation(sqlglot.expressions.core.Expression, Query):
1076class SetOperation(Expression, Query):
1077    arg_types = {
1078        "with_": False,
1079        "this": True,
1080        "expression": True,
1081        "distinct": False,
1082        "by_name": False,
1083        "side": False,
1084        "kind": False,
1085        "on": False,
1086        **QUERY_MODIFIERS,
1087    }
1088
1089    def select(
1090        self: S,
1091        *expressions: ExpOrStr | None,
1092        append: bool = True,
1093        dialect: DialectType = None,
1094        copy: bool = True,
1095        **opts: Unpack[ParserNoDialectArgs],
1096    ) -> S:
1097        this = maybe_copy(self, copy)
1098        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1099        this.expression.unnest().select(
1100            *expressions, append=append, dialect=dialect, copy=False, **opts
1101        )
1102        return this
1103
1104    @property
1105    def named_selects(self) -> list[str]:
1106        expr: Expr = self
1107        while isinstance(expr, SetOperation):
1108            if expr.args.get("by_name"):
1109                left = t.cast(Selectable, expr.this.unnest()).named_selects
1110                right = t.cast(Selectable, expr.expression.unnest()).named_selects
1111                return list(dict.fromkeys(left + right))
1112
1113            expr = expr.this.unnest()
1114        return _named_selects(expr)
1115
1116    @property
1117    def is_star(self) -> bool:
1118        return _is_star(self)
1119
1120    @property
1121    def selects(self) -> list[Expr]:
1122        expr: Expr = self
1123        while isinstance(expr, SetOperation):
1124            expr = expr.this.unnest()
1125        return getattr(expr, "selects", [])
1126
1127    @property
1128    def left(self) -> Query:
1129        return self.this
1130
1131    @property
1132    def right(self) -> Query:
1133        return self.expression
1134
1135    @property
1136    def kind(self) -> str:
1137        return self.text("kind").upper()
1138
1139    @property
1140    def side(self) -> str:
1141        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:
1089    def select(
1090        self: S,
1091        *expressions: ExpOrStr | None,
1092        append: bool = True,
1093        dialect: DialectType = None,
1094        copy: bool = True,
1095        **opts: Unpack[ParserNoDialectArgs],
1096    ) -> S:
1097        this = maybe_copy(self, copy)
1098        this.this.unnest().select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1099        this.expression.unnest().select(
1100            *expressions, append=append, dialect=dialect, copy=False, **opts
1101        )
1102        return this
named_selects: list[str]
1104    @property
1105    def named_selects(self) -> list[str]:
1106        expr: Expr = self
1107        while isinstance(expr, SetOperation):
1108            if expr.args.get("by_name"):
1109                left = t.cast(Selectable, expr.this.unnest()).named_selects
1110                right = t.cast(Selectable, expr.expression.unnest()).named_selects
1111                return list(dict.fromkeys(left + right))
1112
1113            expr = expr.this.unnest()
1114        return _named_selects(expr)
is_star: bool
1116    @property
1117    def is_star(self) -> bool:
1118        return _is_star(self)

Checks whether an expression is a star.

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

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:
1238    def group_by(
1239        self,
1240        *expressions: ExpOrStr | None,
1241        append: bool = True,
1242        dialect: DialectType = None,
1243        copy: bool = True,
1244        **opts: Unpack[ParserNoDialectArgs],
1245    ) -> Select:
1246        """
1247        Set the GROUP BY expression.
1248
1249        Example:
1250            >>> Select().from_("tbl").select("x", "COUNT(1)").group_by("x").sql()
1251            'SELECT x, COUNT(1) FROM tbl GROUP BY x'
1252
1253        Args:
1254            *expressions: the SQL code strings to parse.
1255                If a `Group` instance is passed, this is used as-is.
1256                If another `Expr` instance is passed, it will be wrapped in a `Group`.
1257                If nothing is passed in then a group by is not applied to the expression
1258            append: if `True`, add to any existing expressions.
1259                Otherwise, this flattens all the `Group` expression into a single expression.
1260            dialect: the dialect used to parse the input expression.
1261            copy: if `False`, modify this expression instance in-place.
1262            opts: other options to use to parse the input expressions.
1263
1264        Returns:
1265            The modified Select expression.
1266        """
1267        if not expressions:
1268            return self if not copy else self.copy()
1269
1270        return _apply_child_list_builder(
1271            *expressions,
1272            instance=self,
1273            arg="group",
1274            append=append,
1275            copy=copy,
1276            prefix="GROUP BY",
1277            into=Group,
1278            dialect=dialect,
1279            **opts,
1280        )

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:
1282    def sort_by(
1283        self,
1284        *expressions: ExpOrStr | None,
1285        append: bool = True,
1286        dialect: DialectType = None,
1287        copy: bool = True,
1288        **opts: Unpack[ParserNoDialectArgs],
1289    ) -> Select:
1290        """
1291        Set the SORT BY expression.
1292
1293        Example:
1294            >>> Select().from_("tbl").select("x").sort_by("x DESC").sql(dialect="hive")
1295            'SELECT x FROM tbl SORT BY x DESC'
1296
1297        Args:
1298            *expressions: the SQL code strings to parse.
1299                If a `Group` instance is passed, this is used as-is.
1300                If another `Expr` instance is passed, it will be wrapped in a `SORT`.
1301            append: if `True`, add to any existing expressions.
1302                Otherwise, this flattens all the `Order` expression into a single expression.
1303            dialect: the dialect used to parse the input expression.
1304            copy: if `False`, modify this expression instance in-place.
1305            opts: other options to use to parse the input expressions.
1306
1307        Returns:
1308            The modified Select expression.
1309        """
1310        return _apply_child_list_builder(
1311            *expressions,
1312            instance=self,
1313            arg="sort",
1314            append=append,
1315            copy=copy,
1316            prefix="SORT BY",
1317            into=Sort,
1318            dialect=dialect,
1319            **opts,
1320        )

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:
1322    def cluster_by(
1323        self,
1324        *expressions: ExpOrStr | None,
1325        append: bool = True,
1326        dialect: DialectType = None,
1327        copy: bool = True,
1328        **opts: Unpack[ParserNoDialectArgs],
1329    ) -> Select:
1330        """
1331        Set the CLUSTER BY expression.
1332
1333        Example:
1334            >>> Select().from_("tbl").select("x").cluster_by("x").sql(dialect="hive")
1335            'SELECT x FROM tbl CLUSTER BY x'
1336
1337        Args:
1338            *expressions: the SQL code strings to parse.
1339                If a `Group` instance is passed, this is used as-is.
1340                If another `Expr` instance is passed, it will be wrapped in a `Cluster`.
1341            append: if `True`, add to any existing expressions.
1342                Otherwise, this flattens all the `Order` expression into a single expression.
1343            dialect: the dialect used to parse the input expression.
1344            copy: if `False`, modify this expression instance in-place.
1345            opts: other options to use to parse the input expressions.
1346
1347        Returns:
1348            The modified Select expression.
1349        """
1350        return _apply_child_list_builder(
1351            *expressions,
1352            instance=self,
1353            arg="cluster",
1354            append=append,
1355            copy=copy,
1356            prefix="CLUSTER BY",
1357            into=Cluster,
1358            dialect=dialect,
1359            **opts,
1360        )

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:
1362    def select(
1363        self,
1364        *expressions: ExpOrStr | None,
1365        append: bool = True,
1366        dialect: DialectType = None,
1367        copy: bool = True,
1368        **opts: Unpack[ParserNoDialectArgs],
1369    ) -> Select:
1370        return _apply_list_builder(
1371            *expressions,
1372            instance=self,
1373            arg="expressions",
1374            append=append,
1375            dialect=dialect,
1376            into=Expr,
1377            copy=copy,
1378            **opts,
1379        )
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:
1381    def lateral(
1382        self,
1383        *expressions: ExpOrStr | None,
1384        append: bool = True,
1385        dialect: DialectType = None,
1386        copy: bool = True,
1387        **opts: Unpack[ParserNoDialectArgs],
1388    ) -> Select:
1389        """
1390        Append to or set the LATERAL expressions.
1391
1392        Example:
1393            >>> Select().select("x").lateral("OUTER explode(y) tbl2 AS z").from_("tbl").sql()
1394            'SELECT x FROM tbl LATERAL VIEW OUTER EXPLODE(y) tbl2 AS z'
1395
1396        Args:
1397            *expressions: the SQL code strings to parse.
1398                If an `Expr` instance is passed, it will be used as-is.
1399            append: if `True`, add to any existing expressions.
1400                Otherwise, this resets the expressions.
1401            dialect: the dialect used to parse the input expressions.
1402            copy: if `False`, modify this expression instance in-place.
1403            opts: other options to use to parse the input expressions.
1404
1405        Returns:
1406            The modified Select expression.
1407        """
1408        return _apply_list_builder(
1409            *expressions,
1410            instance=self,
1411            arg="laterals",
1412            append=append,
1413            into=Lateral,
1414            prefix="LATERAL VIEW",
1415            dialect=dialect,
1416            copy=copy,
1417            **opts,
1418        )

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

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:
1518    def having(
1519        self,
1520        *expressions: ExpOrStr | None,
1521        append: bool = True,
1522        dialect: DialectType = None,
1523        copy: bool = True,
1524        **opts: Unpack[ParserNoDialectArgs],
1525    ) -> Select:
1526        """
1527        Append to or set the HAVING expressions.
1528
1529        Example:
1530            >>> Select().select("x", "COUNT(y)").from_("tbl").group_by("x").having("COUNT(y) > 3").sql()
1531            'SELECT x, COUNT(y) FROM tbl GROUP BY x HAVING COUNT(y) > 3'
1532
1533        Args:
1534            *expressions: the SQL code strings to parse.
1535                If an `Expr` instance is passed, it will be used as-is.
1536                Multiple expressions are combined with an AND operator.
1537            append: if `True`, AND the new expressions to any existing expression.
1538                Otherwise, this resets the expression.
1539            dialect: the dialect used to parse the input expressions.
1540            copy: if `False`, modify this expression instance in-place.
1541            opts: other options to use to parse the input expressions.
1542
1543        Returns:
1544            The modified Select expression.
1545        """
1546        return _apply_conjunction_builder(
1547            *expressions,
1548            instance=self,
1549            arg="having",
1550            append=append,
1551            into=Having,
1552            dialect=dialect,
1553            copy=copy,
1554            **opts,
1555        )

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:
1557    def window(
1558        self,
1559        *expressions: ExpOrStr | None,
1560        append: bool = True,
1561        dialect: DialectType = None,
1562        copy: bool = True,
1563        **opts: Unpack[ParserNoDialectArgs],
1564    ) -> Select:
1565        return _apply_list_builder(
1566            *expressions,
1567            instance=self,
1568            arg="windows",
1569            append=append,
1570            into=Window,
1571            dialect=dialect,
1572            copy=copy,
1573            **opts,
1574        )
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:
1576    def qualify(
1577        self,
1578        *expressions: ExpOrStr | None,
1579        append: bool = True,
1580        dialect: DialectType = None,
1581        copy: bool = True,
1582        **opts: Unpack[ParserNoDialectArgs],
1583    ) -> Select:
1584        return _apply_conjunction_builder(
1585            *expressions,
1586            instance=self,
1587            arg="qualify",
1588            append=append,
1589            into=Qualify,
1590            dialect=dialect,
1591            copy=copy,
1592            **opts,
1593        )
def distinct( self, *ons: Union[int, str, sqlglot.expressions.core.Expr, NoneType], distinct: bool = True, copy: bool = True) -> Select:
1595    def distinct(self, *ons: ExpOrStr | None, distinct: bool = True, copy: bool = True) -> Select:
1596        """
1597        Set the OFFSET expression.
1598
1599        Example:
1600            >>> Select().from_("tbl").select("x").distinct().sql()
1601            'SELECT DISTINCT x FROM tbl'
1602
1603        Args:
1604            ons: the expressions to distinct on
1605            distinct: whether the Select should be distinct
1606            copy: if `False`, modify this expression instance in-place.
1607
1608        Returns:
1609            Select: the modified expression.
1610        """
1611        instance = maybe_copy(self, copy)
1612        on = Tuple(expressions=[maybe_parse(on, copy=copy) for on in ons if on]) if ons else None
1613        instance.set("distinct", Distinct(on=on) if distinct else None)
1614        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:
1616    def ctas(
1617        self,
1618        table: ExpOrStr,
1619        properties: dict | None = None,
1620        dialect: DialectType = None,
1621        copy: bool = True,
1622        **opts: Unpack[ParserNoDialectArgs],
1623    ) -> Create:
1624        """
1625        Convert this expression to a CREATE TABLE AS statement.
1626
1627        Example:
1628            >>> Select().select("*").from_("tbl").ctas("x").sql()
1629            'CREATE TABLE x AS SELECT * FROM tbl'
1630
1631        Args:
1632            table: the SQL code string to parse as the table name.
1633                If another `Expr` instance is passed, it will be used as-is.
1634            properties: an optional mapping of table properties
1635            dialect: the dialect used to parse the input table.
1636            copy: if `False`, modify this expression instance in-place.
1637            opts: other options to use to parse the input table.
1638
1639        Returns:
1640            The new Create expression.
1641        """
1642        instance = maybe_copy(self, copy)
1643        table_expression = maybe_parse(table, into=Table, dialect=dialect, **opts)
1644
1645        properties_expression = None
1646        if properties:
1647            from sqlglot.expressions.properties import Properties as _Properties
1648
1649            properties_expression = _Properties.from_dict(properties)
1650
1651        from sqlglot.expressions.ddl import Create as _Create
1652
1653        return _Create(
1654            this=table_expression,
1655            kind="TABLE",
1656            expression=instance,
1657            properties=properties_expression,
1658        )

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:
1660    def lock(self, update: bool = True, copy: bool = True) -> Select:
1661        """
1662        Set the locking read mode for this expression.
1663
1664        Examples:
1665            >>> Select().select("x").from_("tbl").where("x = 'a'").lock().sql("mysql")
1666            "SELECT x FROM tbl WHERE x = 'a' FOR UPDATE"
1667
1668            >>> Select().select("x").from_("tbl").where("x = 'a'").lock(update=False).sql("mysql")
1669            "SELECT x FROM tbl WHERE x = 'a' FOR SHARE"
1670
1671        Args:
1672            update: if `True`, the locking type will be `FOR UPDATE`, else it will be `FOR SHARE`.
1673            copy: if `False`, modify this expression instance in-place.
1674
1675        Returns:
1676            The modified expression.
1677        """
1678        inst = maybe_copy(self, copy)
1679        inst.set("locks", [Lock(update=update)])
1680
1681        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:
1683    def hint(self, *hints: ExpOrStr, dialect: DialectType = None, copy: bool = True) -> Select:
1684        """
1685        Set hints for this expression.
1686
1687        Examples:
1688            >>> Select().select("x").from_("tbl").hint("BROADCAST(y)").sql(dialect="spark")
1689            'SELECT /*+ BROADCAST(y) */ x FROM tbl'
1690
1691        Args:
1692            hints: The SQL code strings to parse as the hints.
1693                If an `Expr` instance is passed, it will be used as-is.
1694            dialect: The dialect used to parse the hints.
1695            copy: If `False`, modify this expression instance in-place.
1696
1697        Returns:
1698            The modified expression.
1699        """
1700        inst = maybe_copy(self, copy)
1701        inst.set(
1702            "hint", Hint(expressions=[maybe_parse(h, copy=copy, dialect=dialect) for h in hints])
1703        )
1704
1705        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]
1707    @property
1708    def named_selects(self) -> list[str]:
1709        selects = []
1710
1711        for e in self.expressions:
1712            if e.alias_or_name:
1713                selects.append(e.output_name)
1714            elif isinstance(e, Aliases):
1715                selects.extend([a.name for a in e.aliases])
1716        return selects
is_star: bool
1718    @property
1719    def is_star(self) -> bool:
1720        return any(expression.is_star for expression in self.expressions)

Checks whether an expression is a star.

selects: list[sqlglot.expressions.core.Expr]
1722    @property
1723    def selects(self) -> list[Expr]:
1724        return self.expressions
key: ClassVar[str] = 'select'
required_args: 't.ClassVar[set[str]]' = set()
class Subquery(sqlglot.expressions.core.Expression, DerivedTable, Query):
1727class Subquery(Expression, DerivedTable, Query):
1728    is_subquery: t.ClassVar[bool] = True
1729    arg_types = {
1730        "this": True,
1731        "alias": False,
1732        "with_": False,
1733        **QUERY_MODIFIERS,
1734    }
1735
1736    def unnest(self) -> Expr:
1737        """Returns the first non subquery."""
1738        expression: Expr = self
1739        while isinstance(expression, Subquery):
1740            expression = expression.this
1741        return expression
1742
1743    def unwrap(self) -> Subquery:
1744        expression = self
1745        while expression.same_parent and expression.is_wrapper:
1746            expression = t.cast(Subquery, expression.parent)
1747        return expression
1748
1749    def select(
1750        self,
1751        *expressions: ExpOrStr | None,
1752        append: bool = True,
1753        dialect: DialectType = None,
1754        copy: bool = True,
1755        **opts: Unpack[ParserNoDialectArgs],
1756    ) -> Subquery:
1757        this = maybe_copy(self, copy)
1758        inner = this.unnest()
1759        if hasattr(inner, "select"):
1760            inner.select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1761        return this
1762
1763    @property
1764    def is_wrapper(self) -> bool:
1765        """
1766        Whether this Subquery acts as a simple wrapper around another expression.
1767
1768        SELECT * FROM (((SELECT * FROM t)))
1769                      ^
1770                      This corresponds to a "wrapper" Subquery node
1771        """
1772        return all(v is None for k, v in self.args.items() if k != "this")
1773
1774    @property
1775    def is_star(self) -> bool:
1776        return _is_star(self)
1777
1778    @property
1779    def output_name(self) -> str:
1780        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:
1736    def unnest(self) -> Expr:
1737        """Returns the first non subquery."""
1738        expression: Expr = self
1739        while isinstance(expression, Subquery):
1740            expression = expression.this
1741        return expression

Returns the first non subquery.

def unwrap(self) -> Subquery:
1743    def unwrap(self) -> Subquery:
1744        expression = self
1745        while expression.same_parent and expression.is_wrapper:
1746            expression = t.cast(Subquery, expression.parent)
1747        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:
1749    def select(
1750        self,
1751        *expressions: ExpOrStr | None,
1752        append: bool = True,
1753        dialect: DialectType = None,
1754        copy: bool = True,
1755        **opts: Unpack[ParserNoDialectArgs],
1756    ) -> Subquery:
1757        this = maybe_copy(self, copy)
1758        inner = this.unnest()
1759        if hasattr(inner, "select"):
1760            inner.select(*expressions, append=append, dialect=dialect, copy=False, **opts)
1761        return this
is_wrapper: bool
1763    @property
1764    def is_wrapper(self) -> bool:
1765        """
1766        Whether this Subquery acts as a simple wrapper around another expression.
1767
1768        SELECT * FROM (((SELECT * FROM t)))
1769                      ^
1770                      This corresponds to a "wrapper" Subquery node
1771        """
1772        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
1774    @property
1775    def is_star(self) -> bool:
1776        return _is_star(self)

Checks whether an expression is a star.

output_name: str
1778    @property
1779    def output_name(self) -> str:
1780        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):
1783class TableSample(Expression):
1784    arg_types = {
1785        "expressions": False,
1786        "method": False,
1787        "bucket_numerator": False,
1788        "bucket_denominator": False,
1789        "bucket_field": False,
1790        "percent": False,
1791        "rows": False,
1792        "size": False,
1793        "seed": False,
1794    }
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):
1797class Tag(Expression):
1798    """Tags are used for generating arbitrary sql like SELECT <span>x</span>."""
1799
1800    arg_types = {
1801        "this": False,
1802        "prefix": False,
1803        "postfix": False,
1804    }

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):
1807class Pivot(Expression):
1808    arg_types = {
1809        "this": False,
1810        "alias": False,
1811        "expressions": False,
1812        "fields": False,
1813        "unpivot": False,
1814        "using": False,
1815        "group": False,
1816        "columns": False,
1817        "include_nulls": False,
1818        "default_on_null": False,
1819        "into": False,
1820        "with_": False,
1821        "identify_pivot_strings": False,
1822        "prefixed_pivot_columns": False,
1823        "pivot_column_naming": False,
1824        "value_columns_first": False,
1825    }
1826
1827    @property
1828    def unpivot(self) -> bool:
1829        return bool(self.args.get("unpivot"))
1830
1831    @property
1832    def fields(self) -> list[Expr]:
1833        return self.args.get("fields", [])
1834
1835    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1836        """
1837        Returns an ordered map of post-rename output column name -> pre-rename
1838        source-side name, in the order the (UN)PIVOT produces them.
1839
1840        For callers that just want the names, iterate the dict (or call .keys()):
1841            >>> from sqlglot import parse_one, exp
1842            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1843            >>> list(piv.output_columns(["a", "b", "c"]))
1844            ['c', 'name', 'val']
1845
1846        AST shape:
1847            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1848                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1849                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1850                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1851
1852            UNPIVOT(val FOR name IN (a, b)):
1853                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1854                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1855                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1856                             are wrapped in PivotAlias(this=Column, alias=Literal).
1857
1858        Args:
1859            pre_pivot_columns: Columns visible to the operator before it runs
1860                (e.g. the source table or subquery's projections).
1861        """
1862        if self.unpivot:
1863            excluded: set[str] = set()
1864            name_columns: list[Identifier] = []
1865            for field in self.fields:
1866                if not isinstance(field, In):
1867                    continue
1868                if isinstance(field.this, Identifier):
1869                    name_columns.append(field.this)
1870                for e in field.expressions:
1871                    excluded.update(c.output_name for c in e.find_all(Column))
1872            value_columns = [
1873                ident
1874                for e in self.expressions
1875                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1876                if isinstance(ident, Identifier)
1877            ]
1878            # T-SQL emits the value column(s) ahead of the name column, everyone else emits them after it
1879            ordered = (
1880                value_columns + name_columns
1881                if self.args.get("value_columns_first")
1882                else name_columns + value_columns
1883            )
1884            outputs = [i.name for i in ordered]
1885        else:
1886            excluded = {c.output_name for c in self.find_all(Column)}
1887            outputs = [c.output_name for c in self.args.get("columns") or []]
1888            if not outputs:
1889                outputs = [c.alias_or_name for c in self.expressions]
1890
1891        if not excluded or not outputs:
1892            return {}
1893
1894        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1895
1896        alias = self.args.get("alias")
1897        renames = alias.args.get("columns") if alias else None
1898
1899        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1900        # positionally from the front (DuckDB, Snowflake): the user's names cover
1901        # the leading N output columns, remaining columns keep their auto names.
1902        if renames:
1903            rename_names = [r.name for r in renames]
1904            post_rename = rename_names + pre_rename[len(rename_names) :]
1905        else:
1906            post_rename = pre_rename
1907
1908        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
1827    @property
1828    def unpivot(self) -> bool:
1829        return bool(self.args.get("unpivot"))
fields: list[sqlglot.expressions.core.Expr]
1831    @property
1832    def fields(self) -> list[Expr]:
1833        return self.args.get("fields", [])
def output_columns(self, pre_pivot_columns: Iterable[str]) -> dict[str, str]:
1835    def output_columns(self, pre_pivot_columns: t.Iterable[str]) -> dict[str, str]:
1836        """
1837        Returns an ordered map of post-rename output column name -> pre-rename
1838        source-side name, in the order the (UN)PIVOT produces them.
1839
1840        For callers that just want the names, iterate the dict (or call .keys()):
1841            >>> from sqlglot import parse_one, exp
1842            >>> piv = parse_one("SELECT * FROM t UNPIVOT(val FOR name IN (a, b))").find(exp.Pivot)
1843            >>> list(piv.output_columns(["a", "b", "c"]))
1844            ['c', 'name', 'val']
1845
1846        AST shape:
1847            PIVOT(SUM(val) FOR name IN ('a', 'b')):
1848                expressions: aggregate(s), e.g. [Sum(this=Column(val))]
1849                fields:      [In(this=Column(name), expressions=[Literal('a'), Literal('b')])]
1850                columns:     optional explicit output identifiers (e.g. set by Snowflake)
1851
1852            UNPIVOT(val FOR name IN (a, b)):
1853                expressions: value Identifier(s), or Tuple(Identifiers) for multi-value
1854                fields:      [In(this=Identifier(name), expressions=[Column(a), Column(b)])]
1855                             For literal-aliased entries (`a AS 'x'`) the IN expressions
1856                             are wrapped in PivotAlias(this=Column, alias=Literal).
1857
1858        Args:
1859            pre_pivot_columns: Columns visible to the operator before it runs
1860                (e.g. the source table or subquery's projections).
1861        """
1862        if self.unpivot:
1863            excluded: set[str] = set()
1864            name_columns: list[Identifier] = []
1865            for field in self.fields:
1866                if not isinstance(field, In):
1867                    continue
1868                if isinstance(field.this, Identifier):
1869                    name_columns.append(field.this)
1870                for e in field.expressions:
1871                    excluded.update(c.output_name for c in e.find_all(Column))
1872            value_columns = [
1873                ident
1874                for e in self.expressions
1875                for ident in (e.expressions if isinstance(e, Tuple) else [e])
1876                if isinstance(ident, Identifier)
1877            ]
1878            # T-SQL emits the value column(s) ahead of the name column, everyone else emits them after it
1879            ordered = (
1880                value_columns + name_columns
1881                if self.args.get("value_columns_first")
1882                else name_columns + value_columns
1883            )
1884            outputs = [i.name for i in ordered]
1885        else:
1886            excluded = {c.output_name for c in self.find_all(Column)}
1887            outputs = [c.output_name for c in self.args.get("columns") or []]
1888            if not outputs:
1889                outputs = [c.alias_or_name for c in self.expressions]
1890
1891        if not excluded or not outputs:
1892            return {}
1893
1894        pre_rename = [c for c in pre_pivot_columns if c not in excluded] + outputs
1895
1896        alias = self.args.get("alias")
1897        renames = alias.args.get("columns") if alias else None
1898
1899        # `PIVOT(...) AS alias(c1, c2, ...)` renames the operator's output columns
1900        # positionally from the front (DuckDB, Snowflake): the user's names cover
1901        # the leading N output columns, remaining columns keep their auto names.
1902        if renames:
1903            rename_names = [r.name for r in renames]
1904            post_rename = rename_names + pre_rename[len(rename_names) :]
1905        else:
1906            post_rename = pre_rename
1907
1908        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):
1911class UnpivotColumns(Expression):
1912    arg_types = {"this": True, "expressions": True}
arg_types = {'this': True, 'expressions': True}
key: ClassVar[str] = 'unpivotcolumns'
required_args: 't.ClassVar[set[str]]' = {'this', 'expressions'}
1915class Window(Expression, Condition):
1916    arg_types = {
1917        "this": True,
1918        "partition_by": False,
1919        "order": False,
1920        "spec": False,
1921        "alias": False,
1922        "over": False,
1923        "first": False,
1924    }
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):
1927class WindowSpec(Expression):
1928    arg_types = {
1929        "kind": False,
1930        "start": False,
1931        "start_side": False,
1932        "end": False,
1933        "end_side": False,
1934        "exclude": False,
1935    }
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):
1938class PreWhere(Expression):
1939    pass
key: ClassVar[str] = 'prewhere'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Where(sqlglot.expressions.core.Expression):
1942class Where(Expression):
1943    pass
key: ClassVar[str] = 'where'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Analyze(sqlglot.expressions.core.Expression):
1946class Analyze(Expression):
1947    arg_types = {
1948        "kind": False,
1949        "tables": False,
1950        "options": False,
1951        "mode": False,
1952        "partition": False,
1953        "expression": False,
1954        "properties": False,
1955    }
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):
1958class AnalyzeStatistics(Expression):
1959    arg_types = {
1960        "kind": True,
1961        "option": False,
1962        "this": False,
1963        "expressions": False,
1964    }
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):
1967class AnalyzeHistogram(Expression):
1968    arg_types = {
1969        "this": True,
1970        "expressions": True,
1971        "expression": False,
1972        "update_options": False,
1973    }
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):
1976class AnalyzeSample(Expression):
1977    arg_types = {"kind": True, "sample": True}
arg_types = {'kind': True, 'sample': True}
key: ClassVar[str] = 'analyzesample'
required_args: 't.ClassVar[set[str]]' = {'kind', 'sample'}
class AnalyzeListChainedRows(sqlglot.expressions.core.Expression):
1980class AnalyzeListChainedRows(Expression):
1981    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):
1984class AnalyzeDelete(Expression):
1985    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):
1988class AnalyzeWith(Expression):
1989    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):
1992class AnalyzeValidate(Expression):
1993    arg_types = {
1994        "kind": True,
1995        "this": False,
1996        "expression": False,
1997    }
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):
2000class AnalyzeColumns(Expression):
2001    pass
key: ClassVar[str] = 'analyzecolumns'
required_args: 't.ClassVar[set[str]]' = {'this'}
class UsingData(sqlglot.expressions.core.Expression):
2004class UsingData(Expression):
2005    pass
key: ClassVar[str] = 'usingdata'
required_args: 't.ClassVar[set[str]]' = {'this'}
class AddPartition(sqlglot.expressions.core.Expression):
2008class AddPartition(Expression):
2009    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):
2012class AttachOption(Expression):
2013    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):
2016class DropPartition(Expression):
2017    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):
2020class ReplacePartition(Expression):
2021    arg_types = {"expression": True, "source": True}
arg_types = {'expression': True, 'source': True}
key: ClassVar[str] = 'replacepartition'
required_args: 't.ClassVar[set[str]]' = {'expression', 'source'}
class TranslateCharacters(sqlglot.expressions.core.Expression):
2024class TranslateCharacters(Expression):
2025    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):
2028class OverflowTruncateBehavior(Expression):
2029    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):
2032class JSON(Expression):
2033    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):
2036class JSONPath(Expression):
2037    arg_types = {"expressions": True}
2038
2039    @property
2040    def output_name(self) -> str:
2041        last_segment = self.expressions[-1].this
2042        return last_segment if isinstance(last_segment, str) else ""
arg_types = {'expressions': True}
output_name: str
2039    @property
2040    def output_name(self) -> str:
2041        last_segment = self.expressions[-1].this
2042        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):
2045class JSONPathPart(Expression):
2046    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'jsonpathpart'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathFilter(JSONPathPart):
2049class JSONPathFilter(JSONPathPart):
2050    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathfilter'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathKey(JSONPathPart):
2053class JSONPathKey(JSONPathPart):
2054    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):
2057class JSONPathRecursive(JSONPathPart):
2058    arg_types = {"this": False}
arg_types = {'this': False}
key: ClassVar[str] = 'jsonpathrecursive'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathRoot(JSONPathPart):
2061class JSONPathRoot(JSONPathPart):
2062    pass
key: ClassVar[str] = 'jsonpathroot'
required_args: 't.ClassVar[set[str]]' = set()
class JSONPathScript(JSONPathPart):
2065class JSONPathScript(JSONPathPart):
2066    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathscript'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathSlice(JSONPathPart):
2069class JSONPathSlice(JSONPathPart):
2070    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):
2073class JSONPathSelector(JSONPathPart):
2074    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathselector'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathSubscript(JSONPathPart):
2077class JSONPathSubscript(JSONPathPart):
2078    arg_types = {"this": True}
arg_types = {'this': True}
key: ClassVar[str] = 'jsonpathsubscript'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONPathUnion(JSONPathPart):
2081class JSONPathUnion(JSONPathPart):
2082    arg_types = {"expressions": True}
arg_types = {'expressions': True}
key: ClassVar[str] = 'jsonpathunion'
required_args: 't.ClassVar[set[str]]' = {'expressions'}
class JSONPathWildcard(JSONPathPart):
2085class JSONPathWildcard(JSONPathPart):
2086    pass
key: ClassVar[str] = 'jsonpathwildcard'
required_args: 't.ClassVar[set[str]]' = set()
class FormatJson(sqlglot.expressions.core.Expression):
2089class FormatJson(Expression):
2090    pass
key: ClassVar[str] = 'formatjson'
required_args: 't.ClassVar[set[str]]' = {'this'}
class JSONKeyValue(sqlglot.expressions.core.Expression):
2093class JSONKeyValue(Expression):
2094    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):
2097class JSONColumnDef(Expression):
2098    arg_types = {
2099        "this": False,
2100        "kind": False,
2101        "path": False,
2102        "nested_schema": False,
2103        "ordinality": False,
2104        "format_json": False,
2105    }
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):
2108class JSONSchema(Expression):
2109    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):
2112class JSONValue(Expression):
2113    arg_types = {
2114        "this": True,
2115        "path": True,
2116        "returning": False,
2117        "on_condition": False,
2118    }
arg_types = {'this': True, 'path': True, 'returning': False, 'on_condition': False}
key: ClassVar[str] = 'jsonvalue'
required_args: 't.ClassVar[set[str]]' = {'path', 'this'}
2121class JSONValueArray(Expression, Func):
2122    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):
2125class OpenJSONColumnDef(Expression):
2126    arg_types = {"this": True, "kind": True, "path": False, "as_json": False}
arg_types = {'this': True, 'kind': True, 'path': False, 'as_json': False}
key: ClassVar[str] = 'openjsoncolumndef'
required_args: 't.ClassVar[set[str]]' = {'kind', 'this'}
class JSONExtractQuote(sqlglot.expressions.core.Expression):
2129class JSONExtractQuote(Expression):
2130    arg_types = {
2131        "option": True,
2132        "scalar": False,
2133    }
arg_types = {'option': True, 'scalar': False}
key: ClassVar[str] = 'jsonextractquote'
required_args: 't.ClassVar[set[str]]' = {'option'}
class ScopeResolution(sqlglot.expressions.core.Expression):
2136class ScopeResolution(Expression):
2137    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):
2140class Stream(Expression):
2141    pass
key: ClassVar[str] = 'stream'
required_args: 't.ClassVar[set[str]]' = {'this'}
class ModelAttribute(sqlglot.expressions.core.Expression):
2144class ModelAttribute(Expression):
2145    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):
2148class XMLNamespace(Expression):
2149    pass
key: ClassVar[str] = 'xmlnamespace'
required_args: 't.ClassVar[set[str]]' = {'this'}
class XMLKeyValueOption(sqlglot.expressions.core.Expression):
2152class XMLKeyValueOption(Expression):
2153    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):
2156class Semicolon(Expression):
2157    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'semicolon'
required_args: 't.ClassVar[set[str]]' = set()
class TableColumn(sqlglot.expressions.core.Expression):
2160class TableColumn(Expression):
2161    @property
2162    def output_name(self) -> str:
2163        return self.name
output_name: str
2161    @property
2162    def output_name(self) -> str:
2163        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):
2166class Variadic(Expression):
2167    pass
key: ClassVar[str] = 'variadic'
required_args: 't.ClassVar[set[str]]' = {'this'}
class StoredProcedure(sqlglot.expressions.core.Expression):
2170class StoredProcedure(Expression):
2171    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):
2174class Block(Expression):
2175    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):
2178class IfBlock(Expression):
2179    arg_types = {"this": True, "true": True, "false": False}
arg_types = {'this': True, 'true': True, 'false': False}
key: ClassVar[str] = 'ifblock'
required_args: 't.ClassVar[set[str]]' = {'true', 'this'}
class CaseStatement(sqlglot.expressions.core.Expression):
2182class CaseStatement(Expression):
2183    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):
2186class WhileBlock(Expression):
2187    arg_types = {"this": True, "body": True, "label": False}
arg_types = {'this': True, 'body': True, 'label': False}
key: ClassVar[str] = 'whileblock'
required_args: 't.ClassVar[set[str]]' = {'body', 'this'}
class LoopBlock(sqlglot.expressions.core.Expression):
2190class LoopBlock(Expression):
2191    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):
2194class RepeatBlock(Expression):
2195    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):
2198class Leave(Expression):
2199    pass
key: ClassVar[str] = 'leave'
required_args: 't.ClassVar[set[str]]' = {'this'}
class Iterate(sqlglot.expressions.core.Expression):
2202class Iterate(Expression):
2203    pass
key: ClassVar[str] = 'iterate'
required_args: 't.ClassVar[set[str]]' = {'this'}
class EndStatement(sqlglot.expressions.core.Expression):
2206class EndStatement(Expression):
2207    arg_types = {}
arg_types = {}
key: ClassVar[str] = 'endstatement'
required_args: 't.ClassVar[set[str]]' = set()
class FunctionSpecification(sqlglot.expressions.core.Expression):
2211class FunctionSpecification(Expression):
2212    arg_types = {
2213        "this": True,
2214        "characteristics": False,
2215        "properties": False,
2216        "expression": True,
2217    }
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:
2223def union(
2224    *expressions: ExpOrStr,
2225    distinct: bool = True,
2226    dialect: DialectType = None,
2227    copy: bool = True,
2228    **opts: Unpack[ParserNoDialectArgs],
2229) -> Union:
2230    """
2231    Initializes a syntax tree for the `UNION` operation.
2232
2233    Example:
2234        >>> union("SELECT * FROM foo", "SELECT * FROM bla").sql()
2235        'SELECT * FROM foo UNION SELECT * FROM bla'
2236
2237    Args:
2238        expressions: the SQL code strings, corresponding to the `UNION`'s operands.
2239            If `Expr` instances are passed, they will be used as-is.
2240        distinct: set the DISTINCT flag if and only if this is true.
2241        dialect: the dialect used to parse the input expression.
2242        copy: whether to copy the expression.
2243        opts: other options to use to parse the input expressions.
2244
2245    Returns:
2246        The new Union instance.
2247    """
2248    assert len(expressions) >= 2, "At least two expressions are required by `union`."
2249    return _apply_set_operation(
2250        *expressions, set_operation=Union, distinct=distinct, dialect=dialect, copy=copy, **opts
2251    )

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

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:
2285def except_(
2286    *expressions: ExpOrStr,
2287    distinct: bool = True,
2288    dialect: DialectType = None,
2289    copy: bool = True,
2290    **opts: Unpack[ParserNoDialectArgs],
2291) -> Except:
2292    """
2293    Initializes a syntax tree for the `EXCEPT` operation.
2294
2295    Example:
2296        >>> except_("SELECT * FROM foo", "SELECT * FROM bla").sql()
2297        'SELECT * FROM foo EXCEPT SELECT * FROM bla'
2298
2299    Args:
2300        expressions: the SQL code strings, corresponding to the `EXCEPT`'s operands.
2301            If `Expr` instances are passed, they will be used as-is.
2302        distinct: set the DISTINCT flag if and only if this is true.
2303        dialect: the dialect used to parse the input expression.
2304        copy: whether to copy the expression.
2305        opts: other options to use to parse the input expressions.
2306
2307    Returns:
2308        The new Except instance.
2309    """
2310    assert len(expressions) >= 2, "At least two expressions are required by `except_`."
2311    return _apply_set_operation(
2312        *expressions, set_operation=Except, distinct=distinct, dialect=dialect, copy=copy, **opts
2313    )

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.